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

Label collision detection preventing labels not shown on the map but according to clamped min-zoom #5776

Closed
dieterdreist opened this issue Nov 30, 2017 · 6 comments
Labels

Comments

@dieterdreist
Copy link

There's maybe a bug in mapbox-gl-js/v0.42.2 (and maybe earlier versions), where the collission detection for labels prevents the rendering of labels in a lower layer where there is a different layer with the same features above, but the features are not rendered (excluded by float Min-Zoom of 8.8)

Description of the situation:
There is a layer B which selects a subset of the features in Layer A.
Layer A is above Layer B in MB Studio.
Layer A has its zoom limited from z8.8 to z14.
Layer B has its zoom limited from z6.5 to z15.

I've triple checked the zoom-dependent styling, and it has nothing to do with it.

Features from Layer B display from z6.5 to z.8.
Then they disappear and reappear when zoom 8.8 is reached (because now it is Layer A which displays them). I can see that disappearing of features in Layer B is caused by Layer A because the features re-appear in Layer B (in Zoom 8-8.8 and above) when I disable Layer A or disable collision prevention in Layer B. Unfortunately, disabling collision prevention is not an option for me. For now I workaround by setting the min-zoom for the source to 9 rather than 8.8

@dieterdreist
Copy link
Author

Looking at it, the problem could be more concisely rephrased like this:
a layer minzoom float is treated as a clamped integer in collision detection when interacting with other layers, but working fine when it comes to visibility in rendering.

The specs state:

minzoom
Optional number between 0 and 24 inclusive.
The minimum zoom level on which the layer gets parsed and appears on.

A number is "A number value, often an integer or floating point (decimal number).", so this is likely a bug.

@eulo
Copy link

eulo commented Dec 5, 2017

map.setLayoutProperty('text-layer', 'text-ignore-placement', true);
map.setLayoutProperty('text-layer', 'text-allow-overlap', true);

Fixed this issue for me

@ChrisLoer
Copy link
Contributor

Thanks for the detailed report @dieterdreist -- I'm not sure if this is new, but it's definitely something that would be affected by the recent #5150 PR. Sorry it took me so long to see this issue. Would you be able to put together a JSFiddle or a Codepen that shows the behavior?

I'll try to investigate next week.

/cc @ansis

@ChrisLoer
Copy link
Contributor

I can reproduce this using just two layers with fractional minzooms that draw a single point from a GeoJSON source (so no need to worry about the interaction with Studio, I think).

It looks like the current behavior was introduced with the fix to issue #2929 in v0.40. Before that there was a different problem, which would cause Layer B in the example above to display over all of the zoom range [8,9), and then Layer A would take over at zoom 9. If Layer A and Layer B were styled the same way, you wouldn't notice that the shift from A to B happened at the wrong zoom.

After @asheemmamoowala's fix to support fractional zoom levels, what happens at zoom 8.2 is that the minzoom filter prevents Layer A from drawing, but it doesn't prevent Layer A from being added to the collision index. Layer B is allowed to draw, but it gets collided out by the "phantom" layer A label.

I think this should be a pretty straightforward fix -- just a matter of testing for fractional min/maxzooms at the time we do collision detection.

@ChrisLoer
Copy link
Contributor

We should double check once we have a regression test for this, but it looks like gl-native mostly isn't affected by this problem because the layer->needsRendering() check will filter the layer out of the set of layers that placement is run against.

The one caveat is that there will be a small (<300ms) delay between one layer disappearing and the other starting to appear, and there will be cross-fading between the two layers, which may look like "flicker".

@ChrisLoer
Copy link
Contributor

Fixed in #5974. Thanks again for the report, @dieterdreist! Let us know if there's still a case that causes trouble.

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

No branches or pull requests

3 participants