Pre-collide places layer point features and reduce density / overlaps
Fixes #287 and fixes #116 and related to label flickering in https://github.com/protomaps/basemaps/issues/286 and https://github.com/protomaps/basemaps/issues/256.
Adjusts the collision grid size and sort functions.
Testing in on the california make target, we see dramatic reduction in features from zooms 5 to 13, with the most reduction in zooms 8, 9, and 10:
z0 z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 z11 z12 z13 z14 z15 all
places after 0 858 2.6k 2.6k 3.4k 6.6k 5.5k 7.6k 7.3k 7.4k 5.2k 5.3k 5.4k 3k 2k 1.6k 7.6k
places before 0 1.8k 2.6k 2.9k 4.3k 8.9k 6.5k 10k 16k 10k 7.3k 5.9k 6.9k 4.1k 2.2k 1.7k 16k
The archive size and feature count remained constant.
Some screenshots before (white halo) and after (no halo). Some cities are labeled more than once in QGIS visualization because of the non-zero tile buffer.
Zoom 6 before
Zoom 6 after
- arguably a few cities are being dropped that shouldn't be, but overall the effect is an improvement
Zoom 7 before
Zoom 7 after
Zoom 8 before
Zoom 8 after
Zoom 9 before
Zoom 9 after
Zoom 10 before
Zoom 10 after
Zoom 11 before
Zoom 11 after
Zoom 12 before
Zoom 12 after
Zoom 13 before
Zoom 13 after
@nvkelso here is a Maperture example with the default style (light).
It seems like the effect on the style is negligible, but tiles should be much lighter now. Other styles (like Mamata's) or raw unfiltered display in QGIS will have less places because their style filters based around minzoom are different. Is that the intended effect? Otherwise LGTM
@nvkelso I may have mis-evaluated the above, how are you viewing zoom levels in QGIS? suspect that may not be consistent with either Leaflet/Tangram or MapLibre GL
I'm using https://github.com/kgjenkins/qgis-zoom-level and I believe it displays Leaflet zoom levels (256x256 display pixels) and not maplibre / tile data ones (512x512 display pixels)
I'm using https://github.com/kgjenkins/qgis-zoom-level and I believe it displays Leaflet zoom levels (256x256 display pixels) and not maplibre / tile data ones (512x512 display pixels)
Same, 256px display pixels so Leaflet zooms.
I need to do more testing to understand why the preview you linked to mostly looks the same...
@nvkelso yes, I confirmed that it looks thinned out in QGIS. let me double check the tileset from that Maperture link was the right branch...
@nvkelso the Maperture link has been updated - should be able to "view boxes" and visualize a significant improvement in hidden labels.
@bdon New Mapeture link where I've shrunk the texts and icon padding.
I tried floating the text around the townspot but that adds too many text labels for an apples to apples comparison, and shows poorly in dense areas with long names like around New York city.
Adding sort-key solved the flickering in New York and Barcelona etc. But to also solve in Delhi where the min_zoom is correct but the population_rank is wrong, you'd want to modify this to use the min_zoom value first (multiplied by 100) and then added to population_rank and then multiplied by -1 so reverse sort it, though to solve the Delhi problem.
Something like (see src though):
"symbol-sort-key": [
"*",
-1,
[
"get",
"population_rank"
]
],
"text-padding": [
"interpolate",
[
"linear"
],
[
"zoom"
],
5,
2,
8,
2,
12,
2
],
"icon-padding": [
"interpolate",
[
"linear"
],
[
"zoom"
],
0,
0,
8,
2,
10,
2,
12,
2,
22,
2
],
"text-variable-anchor": {
"stops": [
[
7,
[
"top",
"top",
"left",
"right"
]
],
[8, ["center"]]
]
},
A few before and afters:
There are some test failures related to the issue @msbarry pointed out, will merge this in for 4.1...
@msbarry is there an easy way to limit the grid thinning to certain zooms? I'd prefer it not start until say zoom 7.
Yeah
@msbarry is there an easy way to limit the grid thinning to certain zooms? I'd prefer it not start until say zoom 7.
You mean you want at zoom <= 7 right? There's a feature.setPointLabelGridSizeAndLimit(int maxzoom, double size, int limit) method that limits label grid filtering to <= maxzoom.
You mean you want at zoom <= 7 right? There's a feature.setPointLabelGridSizeAndLimit(int maxzoom, double size, int limit) method that limits label grid filtering to <= maxzoom.
@msbarry No, zoom > 7 as the early zooms are highly curated and it's OK for say Oakland and San Francisco to appear next to each other in the same collision grid cell.
ah OK so if you want to apply to zooms >= 7 you can do something like feature.setPointLabelGridSize(ZoomFunction.minZoom(7, size)).setPointLabelGridLimit(ZoomFunction.minZoom(7, limit))
I have ported your code over to #437, closing...