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 2017-2019 Gustl22
* Copyright 2018-2019 devemux86
* Copyright 2019 marq24
*
* 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 PointF labelPosition;
public PointF centroidPosition, labelPosition;
/**
* layer of the element (0-10) overrides the theme drawing order.
@@ -57,6 +58,7 @@ public class MapElement extends GeometryBuffer {
public MapElement(MapElement element) {
super(element);
this.tags.set(element.tags.asArray());
this.centroidPosition = element.centroidPosition;
this.labelPosition = element.labelPosition;
this.setLayer(element.layer);
}
@@ -101,6 +103,10 @@ public class MapElement extends GeometryBuffer {
|| "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) {
labelPosition = new PointF(x, y);
}
@@ -122,6 +128,10 @@ public class MapElement extends GeometryBuffer {
@Override
public MapElement scale(float scaleX, float scaleY) {
super.scale(scaleX, scaleY);
if (centroidPosition != null) {
centroidPosition.x *= scaleX;
centroidPosition.y *= scaleY;
}
if (labelPosition != null) {
labelPosition.x *= scaleX;
labelPosition.y *= scaleY;
@@ -132,6 +142,10 @@ public class MapElement extends GeometryBuffer {
@Override
public MapElement translate(float dx, float dy) {
super.translate(dx, dy);
if (centroidPosition != null) {
centroidPosition.x += dx;
centroidPosition.y += dy;
}
if (labelPosition != null) {
labelPosition.x += dx;
labelPosition.y += dy;

View File

@@ -2,6 +2,7 @@
* Copyright 2013 Hannes Janetzek
* Copyright 2016-2018 devemux86
* Copyright 2016 Andrey Novikov
* Copyright 2019 marq24
*
* 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.geom.PolyLabel;
import static org.oscim.core.GeometryBuffer.GeometryType.LINE;
import static org.oscim.core.GeometryBuffer.GeometryType.POINT;
import static org.oscim.core.GeometryBuffer.GeometryType.POLY;
import static org.oscim.core.GeometryBuffer.GeometryType.*;
import static org.oscim.layers.tile.vector.labeling.LabelLayer.LABEL_DATA;
public class LabelTileLoaderHook implements TileLoaderThemeHook {
@@ -135,6 +134,8 @@ public class LabelTileLoaderHook implements TileLoaderThemeHook {
}
} else if (element.type == POLY) {
PointF centroid = element.labelPosition;
if (centroid == null)
centroid = element.centroidPosition;
if (!Parameters.POLY_SYMBOL) {
if (centroid == null)
return false;

View File

@@ -6,6 +6,7 @@
* Copyright 2016 Andrey Novikov
* Copyright 2017-2018 Gustl22
* Copyright 2018 Bezzu
* Copyright 2019 marq24
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
*
@@ -968,6 +969,26 @@ public class MapDatabase implements ITileDataSource {
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.
// But clip everything if buildings are displayed.
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.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;
/**
* Calculation of centroids for all polygons.
* (may affect performance)
*/
public static boolean POLY_CENTROID = false;
/**
* Optimal placement of labels or symbols on polygons.
*/