basemaps icon indicating copy to clipboard operation
basemaps copied to clipboard

Pre-collide places layer point features and reduce density / overlaps

Open nvkelso opened this issue 1 year ago • 14 comments

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.

nvkelso avatar Sep 18 '24 05:09 nvkelso

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 avatar Sep 18 '24 05:09 nvkelso

@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 avatar Sep 23 '24 08:09 bdon

@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 avatar Sep 24 '24 04:09 bdon

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)

bdon avatar Sep 24 '24 07:09 bdon

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 avatar Sep 24 '24 07:09 nvkelso

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

nvkelso avatar Sep 24 '24 07:09 nvkelso

@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 avatar Sep 24 '24 07:09 bdon

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

bdon avatar Sep 24 '24 16:09 bdon

@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

nvkelso avatar Sep 26 '24 06:09 nvkelso

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

bdon avatar Sep 26 '24 07:09 bdon

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

nvkelso avatar Sep 27 '24 05:09 nvkelso

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.

msbarry avatar Sep 27 '24 09:09 msbarry

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.

nvkelso avatar Oct 02 '24 04:10 nvkelso

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

msbarry avatar Oct 02 '24 09:10 msbarry

I have ported your code over to #437, closing...

wipfli avatar Apr 02 '25 09:04 wipfli