Skip to content
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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

nvkelso
Copy link
Collaborator

@nvkelso nvkelso commented Sep 18, 2024

Fixes #287 and fixes #116 and related to label flickering in #286 and #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.

@nvkelso
Copy link
Collaborator Author

nvkelso commented Sep 18, 2024

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
ca-zoom-6-before

Zoom 6 after

  • arguably a few cities are being dropped that shouldn't be, but overall the effect is an improvement
ca-zoom-6-after

Zoom 7 before
ca-zoom-7-before

Zoom 7 after
ca-zoom-7-after

Zoom 8 before
ca-zoom-8-before

Zoom 8 after
ca-zoom-8-after

Zoom 9 before
ca-zoom-9-before

Zoom 9 after
ca-zoom-9-after

Zoom 10 before
ca-zoom-10-before

Zoom 10 after
ca-zoom-10-after

Zoom 11 before
ca-zoom-11-before

Zoom 11 after
ca-zoom-11-after

Zoom 12 before
ca-zoom-12-before

Zoom 12 after
ca-zoom-12-after

Zoom 13 before
ca-zoom-13-before

Zoom 13 after
ca-zoom-13-after

@nvkelso nvkelso requested a review from bdon September 18, 2024 05:51
@@ -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,
Copy link
Collaborator Author

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.

10, 1,
11, 1,
14, 2,
15, 3
Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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

@@ -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);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The 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

Copy link
Member

Choose a reason for hiding this comment

The 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?

Copy link
Contributor

@msbarry msbarry Sep 18, 2024

Choose a reason for hiding this comment

The 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 FeatureMerge.removePointsOutsideBuffer in postProcess

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the min buffer pixel limit should be label grid size - gcd(256, label grid size) - I should probably update planetiler to use that limit and post-filter to whatever you set here so users don't need to now or care about that implementation detail...

@bdon
Copy link
Member

bdon commented Sep 23, 2024

@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

@bdon
Copy link
Member

bdon commented Sep 24, 2024

@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

@bdon
Copy link
Member

bdon commented Sep 24, 2024

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)

@nvkelso
Copy link
Collaborator Author

nvkelso commented Sep 24, 2024

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.

@nvkelso
Copy link
Collaborator Author

nvkelso commented Sep 24, 2024

I need to do more testing to understand why the preview you linked to mostly looks the same...

@bdon
Copy link
Member

bdon commented Sep 24, 2024

@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...

@bdon
Copy link
Member

bdon commented Sep 24, 2024

@nvkelso the Maperture link has been updated - should be able to "view boxes" and visualize a significant improvement in hidden labels.

@nvkelso
Copy link
Collaborator Author

nvkelso commented Sep 26, 2024

@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:

image image image

@bdon
Copy link
Member

bdon commented Sep 26, 2024

There are some test failures related to the issue @msbarry pointed out, will merge this in for 4.1...

@nvkelso
Copy link
Collaborator Author

nvkelso commented Sep 27, 2024

@msbarry is there an easy way to limit the grid thinning to certain zooms? I'd prefer it not start until say zoom 7.

@msbarry
Copy link
Contributor

msbarry commented Sep 27, 2024

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.

@nvkelso
Copy link
Collaborator Author

nvkelso commented Oct 2, 2024

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.

@msbarry
Copy link
Contributor

msbarry commented Oct 2, 2024

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))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Label density can be optimized at z8 Too many places visible at zoom 8, 9, and 10
3 participants