kopia lustrzana https://github.com/onthegomap/planetiler
make min pixel size/tolerance configurable
rodzic
c4ffc10b72
commit
b2a6d5910e
|
@ -63,11 +63,15 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
|
|||
private double defaultBufferPixels = 4;
|
||||
private ZoomFunction<Number> bufferPixelOverrides;
|
||||
private double defaultMinPixelSize = 1;
|
||||
private double minPixelSizeAtMaxZoom = 256d / 4096;
|
||||
private ZoomFunction<Number> minPixelSize = null;
|
||||
private ZoomFunction<Number> labelGridPixelSize = null;
|
||||
private ZoomFunction<Number> labelGridLimit = null;
|
||||
private boolean attrsChangeByZoom = false;
|
||||
private CacheByZoom<Map<String, Object>> attrCache = null;
|
||||
private double defaultPixelTolerance = 0.1d;
|
||||
private double pixelToleranceAtMaxZoom = 256d / 4096;
|
||||
private ZoomFunction<Double> pixelTolerance = null;
|
||||
|
||||
private Feature(String layer, Geometry geom, boolean area) {
|
||||
this.layer = layer;
|
||||
|
@ -130,7 +134,8 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
|
|||
}
|
||||
|
||||
public double getMinPixelSize(int zoom) {
|
||||
return ZoomFunction.applyAsDoubleOrElse(minPixelSize, zoom, defaultMinPixelSize);
|
||||
return zoom == 14 ? minPixelSizeAtMaxZoom
|
||||
: ZoomFunction.applyAsDoubleOrElse(minPixelSize, zoom, defaultMinPixelSize);
|
||||
}
|
||||
|
||||
public Feature setMinPixelSize(double minPixelSize) {
|
||||
|
@ -143,6 +148,41 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Feature setMinPixelSizeAtMaxZoom(double minPixelSize) {
|
||||
this.minPixelSizeAtMaxZoom = minPixelSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Feature setMinPixelSizeAtAllZooms(int minPixelSize) {
|
||||
return setMinPixelSizeAtMaxZoom(minPixelSize)
|
||||
.setMinPixelSize(minPixelSize);
|
||||
}
|
||||
|
||||
|
||||
public Feature setPixelTolerance(double tolerance) {
|
||||
this.defaultPixelTolerance = tolerance;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Feature setPixelToleranceAtMaxZoom(double tolerance) {
|
||||
this.pixelToleranceAtMaxZoom = tolerance;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Feature setPixelToleranceAtAllZooms(double tolerance) {
|
||||
return setPixelToleranceAtMaxZoom(tolerance).setPixelTolerance(tolerance);
|
||||
}
|
||||
|
||||
public Feature setPixelToleranceBelowZoom(int zoom, double tolerance) {
|
||||
this.pixelTolerance = ZoomFunction.maxZoom(zoom, tolerance);
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getPixelTolerance(int zoom) {
|
||||
return zoom == 14 ? pixelToleranceAtMaxZoom
|
||||
: ZoomFunction.applyAsDoubleOrElse(pixelTolerance, zoom, defaultPixelTolerance);
|
||||
}
|
||||
|
||||
public double getLabelGridPixelSizeAtZoom(int zoom) {
|
||||
return ZoomFunction.applyAsDoubleOrElse(labelGridPixelSize, zoom, DEFAULT_LABEL_GRID_SIZE);
|
||||
}
|
||||
|
|
|
@ -7,11 +7,9 @@ import com.onthegomap.flatmap.VectorTileEncoder;
|
|||
import com.onthegomap.flatmap.geo.GeoUtils;
|
||||
import com.onthegomap.flatmap.geo.GeometryException;
|
||||
import com.onthegomap.flatmap.geo.TileCoord;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Consumer;
|
||||
import org.locationtech.jts.geom.Coordinate;
|
||||
|
@ -84,7 +82,6 @@ public class FeatureRenderer {
|
|||
long id = idGen.incrementAndGet();
|
||||
boolean hasLabelGrid = feature.hasLabelGrid();
|
||||
for (int zoom = feature.getMaxZoom(); zoom >= feature.getMinZoom(); zoom--) {
|
||||
Map<TileCoord, Set<Coordinate>> sliced = new HashMap<>();
|
||||
Map<String, Object> attrs = feature.getAttrsAtZoom(zoom);
|
||||
double buffer = feature.getBufferPixelsAtZoom(zoom) / 256;
|
||||
int tilesAtZoom = 1 << zoom;
|
||||
|
@ -138,18 +135,12 @@ public class FeatureRenderer {
|
|||
|
||||
private void addLinearFeature(FeatureCollector.Feature feature, Geometry input) {
|
||||
long id = idGen.incrementAndGet();
|
||||
// TODO move to feature?
|
||||
double minSizeAtMaxZoom = 1d / 4096;
|
||||
double normalTolerance = 0.1 / 256;
|
||||
double toleranceAtMaxZoom = 1d / 4096;
|
||||
|
||||
boolean area = input instanceof Polygonal;
|
||||
double worldLength = (area || input.getNumGeometries() > 1) ? 0 : input.getLength();
|
||||
for (int z = feature.getMaxZoom(); z >= feature.getMinZoom(); z--) {
|
||||
boolean isMaxZoom = feature.getMaxZoom() == 14;
|
||||
double scale = 1 << z;
|
||||
double tolerance = isMaxZoom ? toleranceAtMaxZoom : normalTolerance;
|
||||
double minSize = isMaxZoom ? minSizeAtMaxZoom : (feature.getMinPixelSize(z) / 256);
|
||||
double tolerance = feature.getPixelTolerance(z) / 256d;
|
||||
double minSize = feature.getMinPixelSize(z) / 256d;
|
||||
if (area) {
|
||||
minSize *= minSize;
|
||||
} else if (worldLength > 0 && worldLength * scale < minSize) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import static com.onthegomap.flatmap.TestUtils.assertSubmap;
|
|||
import static com.onthegomap.flatmap.TestUtils.newLineString;
|
||||
import static com.onthegomap.flatmap.TestUtils.newPoint;
|
||||
import static com.onthegomap.flatmap.TestUtils.newPolygon;
|
||||
import static com.onthegomap.flatmap.TestUtils.rectangle;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import com.onthegomap.flatmap.read.ReaderFeature;
|
||||
|
@ -103,7 +104,7 @@ public class FeatureCollectorTest {
|
|||
.setAttr("attr1", 2)
|
||||
.setMinPixelSize(1)
|
||||
.setMinPixelSizeBelowZoom(12, 10);
|
||||
assertFeatures(14, List.of(
|
||||
assertFeatures(13, List.of(
|
||||
Map.of(
|
||||
"_layer", "layername",
|
||||
"_minzoom", 12,
|
||||
|
@ -134,7 +135,7 @@ public class FeatureCollectorTest {
|
|||
.inheritFromSource("key")
|
||||
.setMinPixelSize(1)
|
||||
.setMinPixelSizeBelowZoom(12, 10);
|
||||
assertFeatures(14, List.of(
|
||||
assertFeatures(13, List.of(
|
||||
Map.of(
|
||||
"_layer", "layername",
|
||||
"_minzoom", 12,
|
||||
|
@ -152,5 +153,99 @@ public class FeatureCollectorTest {
|
|||
), collector);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMinSizeAtMaxZoomDefaultsToTileResolution() {
|
||||
var collector = factory.get(new ReaderFeature(rectangle(10, 20), Map.of()));
|
||||
var poly = collector.polygon("layername")
|
||||
.setMinPixelSize(1)
|
||||
.setMinPixelSizeBelowZoom(12, 10);
|
||||
assertEquals(10, poly.getMinPixelSize(12));
|
||||
assertEquals(1, poly.getMinPixelSize(13));
|
||||
assertEquals(256d / 4096, poly.getMinPixelSize(14));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetMinSizeAtMaxZoom() {
|
||||
var collector = factory.get(new ReaderFeature(rectangle(10, 20), Map.of()));
|
||||
var poly = collector.polygon("layername")
|
||||
.setMinPixelSize(1)
|
||||
.setMinPixelSizeAtMaxZoom(0.5)
|
||||
.setMinPixelSizeBelowZoom(12, 10);
|
||||
assertEquals(10, poly.getMinPixelSize(12));
|
||||
assertEquals(1, poly.getMinPixelSize(13));
|
||||
assertEquals(0.5, poly.getMinPixelSize(14));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetMinSizeAtAllZooms() {
|
||||
var collector = factory.get(new ReaderFeature(rectangle(10, 20), Map.of()));
|
||||
var poly = collector.polygon("layername")
|
||||
.setMinPixelSizeAtAllZooms(2)
|
||||
.setMinPixelSizeBelowZoom(12, 10);
|
||||
assertEquals(10, poly.getMinPixelSize(12));
|
||||
assertEquals(2, poly.getMinPixelSize(13));
|
||||
assertEquals(2, poly.getMinPixelSize(14));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultMinPixelSize() {
|
||||
var collector = factory.get(new ReaderFeature(rectangle(10, 20), Map.of()));
|
||||
var poly = collector.polygon("layername");
|
||||
assertEquals(1, poly.getMinPixelSize(12));
|
||||
assertEquals(1, poly.getMinPixelSize(13));
|
||||
assertEquals(256d / 4096, poly.getMinPixelSize(14));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToleranceDefault() {
|
||||
var collector = factory.get(new ReaderFeature(rectangle(10, 20), Map.of()));
|
||||
var poly = collector.polygon("layername");
|
||||
assertEquals(0.1, poly.getPixelTolerance(12));
|
||||
assertEquals(0.1, poly.getPixelTolerance(13));
|
||||
assertEquals(256d / 4096, poly.getPixelTolerance(14));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetTolerance() {
|
||||
var collector = factory.get(new ReaderFeature(rectangle(10, 20), Map.of()));
|
||||
var poly = collector.polygon("layername")
|
||||
.setPixelTolerance(1);
|
||||
assertEquals(1d, poly.getPixelTolerance(12));
|
||||
assertEquals(1d, poly.getPixelTolerance(13));
|
||||
assertEquals(256d / 4096, poly.getPixelTolerance(14));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetToleranceAtAllZooms() {
|
||||
var collector = factory.get(new ReaderFeature(rectangle(10, 20), Map.of()));
|
||||
var poly = collector.polygon("layername")
|
||||
.setPixelToleranceAtAllZooms(1);
|
||||
assertEquals(1d, poly.getPixelTolerance(12));
|
||||
assertEquals(1d, poly.getPixelTolerance(13));
|
||||
assertEquals(1d, poly.getPixelTolerance(14));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetMaxZoom() {
|
||||
var collector = factory.get(new ReaderFeature(rectangle(10, 20), Map.of()));
|
||||
var poly = collector.polygon("layername")
|
||||
.setPixelToleranceAtMaxZoom(2);
|
||||
assertEquals(0.1d, poly.getPixelTolerance(12));
|
||||
assertEquals(0.1d, poly.getPixelTolerance(13));
|
||||
assertEquals(2d, poly.getPixelTolerance(14));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetAllZoomMethods() {
|
||||
var collector = factory.get(new ReaderFeature(rectangle(10, 20), Map.of()));
|
||||
var poly = collector.polygon("layername")
|
||||
.setPixelTolerance(1)
|
||||
.setPixelToleranceAtMaxZoom(2)
|
||||
.setPixelToleranceBelowZoom(12, 3);
|
||||
assertEquals(3d, poly.getPixelTolerance(12));
|
||||
assertEquals(1d, poly.getPixelTolerance(13));
|
||||
assertEquals(2d, poly.getPixelTolerance(14));
|
||||
}
|
||||
|
||||
// TODO test shape coercion
|
||||
}
|
||||
|
|
|
@ -433,6 +433,29 @@ public class FeatureRendererTest {
|
|||
), renderGeometry(feature));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDuplicatePointsRemovedAfterRounding() {
|
||||
var eps = Z14_WIDTH / 4096;
|
||||
var pixel = Z14_WIDTH / 256;
|
||||
var feature = lineFeature(newLineString(
|
||||
0.5 + pixel * 10, 0.5 + pixel * 10,
|
||||
0.5 + pixel * 20, 0.5 + pixel * 10,
|
||||
0.5 + pixel * 20, 0.5 + pixel * 10 + eps / 3
|
||||
))
|
||||
.setMinPixelSize(1)
|
||||
.setZoomRange(14, 14)
|
||||
.setBufferPixels(0)
|
||||
.setPixelToleranceAtAllZooms(0);
|
||||
assertExactSameFeatures(Map.of(
|
||||
TileCoord.ofXYZ(Z14_TILES / 2, Z14_TILES / 2, 14), List.of(
|
||||
newLineString(
|
||||
10, 10,
|
||||
20, 10
|
||||
)
|
||||
)
|
||||
), renderGeometry(feature));
|
||||
}
|
||||
|
||||
/*
|
||||
* POLYGON TESTS
|
||||
*/
|
||||
|
|
Ładowanie…
Reference in New Issue