-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pre-collide places layer point features and reduce density / overlaps #300
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,13 +36,15 @@ static int getSortKey(double minZoom, int kindRank, int populationRank, long pop | |
// (nvkelso 20230803) floats with significant single decimal precision | ||
// but results in "Too many possible values" | ||
// Order ASCENDING (smaller manually curated Natural Earth min_zoom win over larger values, across kinds) | ||
.orderByInt((int) minZoom, 0, 15) | ||
// minZoom is a float with 1 significant digit for manually curated places | ||
.orderByInt((int) (minZoom * 10), 0, 150) | ||
// Order ASCENDING (smaller values win, countries then locality then neighbourhood, breaks ties for same minZoom) | ||
.thenByInt(kindRank, 0, 6) | ||
.thenByInt(kindRank, 0, 12) | ||
// Order DESCENDING (larger values win, San Francisco rank 11 wins over Oakland rank 10) | ||
.thenByInt(populationRank, 15, 0) | ||
// Disabled to allow population log to have larger range | ||
//.thenByInt(populationRank, 15, 0) | ||
// Order DESCENDING (larger values win, Millbrea 40k wins over San Bruno 20k, both rank 7) | ||
.thenByLog(population, 1000000000, 1, 100) | ||
.thenByLog(population, 40000000, 1, 100) | ||
// Order ASCENDING (shorter strings are better than longer strings for map display and adds predictability) | ||
.thenByInt(name == null ? 0 : name.length(), 0, 31) | ||
.get(); | ||
|
@@ -55,15 +57,30 @@ static int getSortKey(double minZoom, int kindRank, int populationRank, long pop | |
|
||
private static final ZoomFunction<Number> LOCALITY_GRID_SIZE_ZOOM_FUNCTION = | ||
ZoomFunction.fromMaxZoomThresholds(Map.of( | ||
6, 32, | ||
7, 64 | ||
3, 24, | ||
4, 24, | ||
5, 24, | ||
7, 24, | ||
8, 32, | ||
9, 32, | ||
10, 32, | ||
11, 24, | ||
14, 24, | ||
15, 16 | ||
), 0); | ||
|
||
private static final ZoomFunction<Number> LOCALITY_GRID_LIMIT_ZOOM_FUNCTION = | ||
ZoomFunction.fromMaxZoomThresholds(Map.of( | ||
6, 8, | ||
7, 6, | ||
9, 4 | ||
3, 1, | ||
4, 1, | ||
5, 1, | ||
6, 1, | ||
8, 1, | ||
9, 1, | ||
10, 1, | ||
11, 1, | ||
14, 2, | ||
15, 3 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could argue the zoom 15 step could be a larger int, or not limited at all |
||
), 0); | ||
|
||
public void processOsm(SourceFeature sf, FeatureCollector features) { | ||
|
@@ -148,7 +165,7 @@ public void processOsm(SourceFeature sf, FeatureCollector features) { | |
// This minZoom can be changed to smaller value in the NE data join step below | ||
minZoom = 11.0f; | ||
maxZoom = 15.0f; | ||
kindRank = 3; | ||
kindRank = 4; | ||
if (population == 0) { | ||
minZoom = 12.0f; | ||
population = 1000; | ||
|
@@ -159,7 +176,7 @@ public void processOsm(SourceFeature sf, FeatureCollector features) { | |
// This minZoom can be changed to smaller value in the NE data join step below | ||
minZoom = 11.0f; | ||
maxZoom = 15.0f; | ||
kindRank = 3; | ||
kindRank = 5; | ||
if (population == 0) { | ||
minZoom = 12.0f; | ||
population = 200; | ||
|
@@ -170,7 +187,7 @@ public void processOsm(SourceFeature sf, FeatureCollector features) { | |
// This minZoom can be changed to smaller value in the NE data join step below | ||
minZoom = 13.0f; | ||
maxZoom = 15.0f; | ||
kindRank = 3; | ||
kindRank = 6; | ||
if (population == 0) { | ||
minZoom = 14.0f; | ||
population = 100; | ||
|
@@ -181,7 +198,7 @@ public void processOsm(SourceFeature sf, FeatureCollector features) { | |
// This minZoom can be changed to smaller value in the NE data join step below | ||
minZoom = 13.0f; | ||
maxZoom = 15.0f; | ||
kindRank = 3; | ||
kindRank = 7; | ||
if (population == 0) { | ||
minZoom = 14.0f; | ||
population = 50; | ||
|
@@ -193,7 +210,7 @@ public void processOsm(SourceFeature sf, FeatureCollector features) { | |
// This minZoom can be changed to smaller value in the NE data join step below | ||
minZoom = 13.0f; | ||
maxZoom = 15.0f; | ||
kindRank = 3; | ||
kindRank = 8; | ||
if (population == 0) { | ||
minZoom = 14.0f; | ||
population = 1000; | ||
|
@@ -204,19 +221,19 @@ public void processOsm(SourceFeature sf, FeatureCollector features) { | |
kind = "neighbourhood"; | ||
minZoom = 11.0f; | ||
maxZoom = 15.0f; | ||
kindRank = 4; | ||
kindRank = 9; | ||
break; | ||
case "quarter": | ||
kind = "macrohood"; | ||
minZoom = 10.0f; | ||
maxZoom = 15.0f; | ||
kindRank = 5; | ||
kindRank = 10; | ||
break; | ||
case "neighbourhood": | ||
kind = "neighbourhood"; | ||
minZoom = 12.0f; | ||
maxZoom = 15.0f; | ||
kindRank = 6; | ||
kindRank = 11; | ||
break; | ||
} | ||
|
||
|
@@ -287,12 +304,14 @@ public void processOsm(SourceFeature sf, FeatureCollector features) { | |
//feat.setSortKey(minZoom * 1000 + 400 - populationRank * 200 + placeNumber.incrementAndGet()); | ||
feat.setSortKey(getSortKey(minZoom, kindRank, populationRank, population, sf.getString("name"))); | ||
|
||
// This is only necessary when prepping for raster renderers | ||
feat.setBufferPixels(16); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If Protomaps is only targeting vector renderers than this could be set to 0 to reduce file size There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we still want a buffer for drawing townspots correctly very close to tile edges? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If 256 isn't evenly dvisible by your label grid size then you need a bit extra in order for label grid squares to be aware of points in the square from neighboring tiles otherwise the density might get off a bit around tile boundaries. Looks like 24 is the only problematic one. I think a buffer of 16 should be the minimum that works with label grid of 24. If you want to go smaller you could either switch label grid to a power of 2 or use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the min buffer pixel limit should be |
||
|
||
// We set the sort keys so the label grid can be sorted predictably (bonus: tile features also sorted) | ||
// NOTE: The buffer needs to be consistent with the innteral grid pixel sizes | ||
//feat.setPointLabelGridSizeAndLimit(13, 64, 4); // each cell in the 4x4 grid can have 4 items | ||
feat.setPointLabelGridPixelSize(LOCALITY_GRID_SIZE_ZOOM_FUNCTION) | ||
.setPointLabelGridLimit(LOCALITY_GRID_LIMIT_ZOOM_FUNCTION) | ||
.setBufferPixels(64); | ||
.setPointLabelGridLimit(LOCALITY_GRID_LIMIT_ZOOM_FUNCTION); | ||
|
||
// and also whenever you set a label grid size limit, make sure you increase the buffer size so no | ||
// label grid squares will be the consistent between adjacent tiles | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This GRID_SIZE sequence could be simplified, but needs to match the zoom steps in the GRID_LIMIT sequence below.