Create centroids based on non clipped ways (#734)

- introduced a new member to the MapElement to store the pre-calculated centroid of the way (none clipped)
- auto create element.centroidPosition based on all (none clipped) points of a osm-way
- skipping rendering of centered symbols, if OFF screen
- introduced Parameter to enable/disable the feature
This commit is contained in:
marq24
2019-07-30 20:07:45 +02:00
committed by Emux
parent 653c6489b9
commit 55d8797f37
4 changed files with 50 additions and 4 deletions

View File

@@ -3,6 +3,7 @@
* Copyright 2016 Andrey Novikov * Copyright 2016 Andrey Novikov
* Copyright 2017-2019 Gustl22 * Copyright 2017-2019 Gustl22
* Copyright 2018-2019 devemux86 * Copyright 2018-2019 devemux86
* Copyright 2019 marq24
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
* *
@@ -30,7 +31,7 @@ import org.oscim.theme.IRenderTheme;
*/ */
public class MapElement extends GeometryBuffer { public class MapElement extends GeometryBuffer {
public PointF labelPosition; public PointF centroidPosition, labelPosition;
/** /**
* layer of the element (0-10) overrides the theme drawing order. * layer of the element (0-10) overrides the theme drawing order.
@@ -57,6 +58,7 @@ public class MapElement extends GeometryBuffer {
public MapElement(MapElement element) { public MapElement(MapElement element) {
super(element); super(element);
this.tags.set(element.tags.asArray()); this.tags.set(element.tags.asArray());
this.centroidPosition = element.centroidPosition;
this.labelPosition = element.labelPosition; this.labelPosition = element.labelPosition;
this.setLayer(element.layer); this.setLayer(element.layer);
} }
@@ -101,6 +103,10 @@ public class MapElement extends GeometryBuffer {
|| "building:part".equals(tags.getValue("layer")); // OpenMapTiles || "building:part".equals(tags.getValue("layer")); // OpenMapTiles
} }
public void setCentroidPosition(float x, float y) {
centroidPosition = new PointF(x, y);
}
public void setLabelPosition(float x, float y) { public void setLabelPosition(float x, float y) {
labelPosition = new PointF(x, y); labelPosition = new PointF(x, y);
} }
@@ -122,6 +128,10 @@ public class MapElement extends GeometryBuffer {
@Override @Override
public MapElement scale(float scaleX, float scaleY) { public MapElement scale(float scaleX, float scaleY) {
super.scale(scaleX, scaleY); super.scale(scaleX, scaleY);
if (centroidPosition != null) {
centroidPosition.x *= scaleX;
centroidPosition.y *= scaleY;
}
if (labelPosition != null) { if (labelPosition != null) {
labelPosition.x *= scaleX; labelPosition.x *= scaleX;
labelPosition.y *= scaleY; labelPosition.y *= scaleY;
@@ -132,6 +142,10 @@ public class MapElement extends GeometryBuffer {
@Override @Override
public MapElement translate(float dx, float dy) { public MapElement translate(float dx, float dy) {
super.translate(dx, dy); super.translate(dx, dy);
if (centroidPosition != null) {
centroidPosition.x += dx;
centroidPosition.y += dy;
}
if (labelPosition != null) { if (labelPosition != null) {
labelPosition.x += dx; labelPosition.x += dx;
labelPosition.y += dy; labelPosition.y += dy;

View File

@@ -2,6 +2,7 @@
* Copyright 2013 Hannes Janetzek * Copyright 2013 Hannes Janetzek
* Copyright 2016-2018 devemux86 * Copyright 2016-2018 devemux86
* Copyright 2016 Andrey Novikov * Copyright 2016 Andrey Novikov
* Copyright 2019 marq24
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
* *
@@ -32,9 +33,7 @@ import org.oscim.theme.styles.TextStyle;
import org.oscim.utils.Parameters; import org.oscim.utils.Parameters;
import org.oscim.utils.geom.PolyLabel; import org.oscim.utils.geom.PolyLabel;
import static org.oscim.core.GeometryBuffer.GeometryType.LINE; import static org.oscim.core.GeometryBuffer.GeometryType.*;
import static org.oscim.core.GeometryBuffer.GeometryType.POINT;
import static org.oscim.core.GeometryBuffer.GeometryType.POLY;
import static org.oscim.layers.tile.vector.labeling.LabelLayer.LABEL_DATA; import static org.oscim.layers.tile.vector.labeling.LabelLayer.LABEL_DATA;
public class LabelTileLoaderHook implements TileLoaderThemeHook { public class LabelTileLoaderHook implements TileLoaderThemeHook {
@@ -135,6 +134,8 @@ public class LabelTileLoaderHook implements TileLoaderThemeHook {
} }
} else if (element.type == POLY) { } else if (element.type == POLY) {
PointF centroid = element.labelPosition; PointF centroid = element.labelPosition;
if (centroid == null)
centroid = element.centroidPosition;
if (!Parameters.POLY_SYMBOL) { if (!Parameters.POLY_SYMBOL) {
if (centroid == null) if (centroid == null)
return false; return false;

View File

@@ -6,6 +6,7 @@
* Copyright 2016 Andrey Novikov * Copyright 2016 Andrey Novikov
* Copyright 2017-2018 Gustl22 * Copyright 2017-2018 Gustl22
* Copyright 2018 Bezzu * Copyright 2018 Bezzu
* Copyright 2019 marq24
* *
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org). * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
* *
@@ -968,6 +969,26 @@ public class MapDatabase implements ITileDataSource {
mTileProjection.project(e); mTileProjection.project(e);
// When a way will be rendered then typically a label / symbol will be applied
// by the render theme. If the way does not come with a defined labelPosition
// we should calculate a position, that is based on all points of the given way.
// This "auto" position calculation is also done in the LabelTileLoaderHook class
// but then the points of the way have been already reduced cause of the clipping
// that is happening. So the suggestion here is to calculate the centroid of the way
// and use that as centroidPosition of the element.
if (Parameters.POLY_CENTROID && e.labelPosition == null) {
float x = 0;
float y = 0;
int n = e.index[0];
for (int i = 0; i < n; ) {
x += e.points[i++];
y += e.points[i++];
}
x /= (n / 2);
y /= (n / 2);
e.setCentroidPosition(x, y);
}
// Avoid clipping for buildings, which slows rendering. // Avoid clipping for buildings, which slows rendering.
// But clip everything if buildings are displayed. // But clip everything if buildings are displayed.
if (!e.tags.containsKey(Tag.KEY_BUILDING) if (!e.tags.containsKey(Tag.KEY_BUILDING)
@@ -1277,6 +1298,10 @@ public class MapDatabase implements ITileDataSource {
e.labelPosition.x = projectLon(e.labelPosition.x); e.labelPosition.x = projectLon(e.labelPosition.x);
e.labelPosition.y = projectLat(e.labelPosition.y); e.labelPosition.y = projectLat(e.labelPosition.y);
} }
if (e.centroidPosition != null) {
e.centroidPosition.x = projectLon(e.centroidPosition.x);
e.centroidPosition.y = projectLat(e.centroidPosition.y);
}
} }
} }
} }

View File

@@ -41,6 +41,12 @@ public final class Parameters {
*/ */
public static int MAXIMUM_BUFFER_SIZE = 8000000; public static int MAXIMUM_BUFFER_SIZE = 8000000;
/**
* Calculation of centroids for all polygons.
* (may affect performance)
*/
public static boolean POLY_CENTROID = false;
/** /**
* Optimal placement of labels or symbols on polygons. * Optimal placement of labels or symbols on polygons.
*/ */