mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.14k stars 2.22k forks source link

Variable symbol placement state not flushed when map restyled #10891

Open stevage opened 3 years ago

stevage commented 3 years ago

mapbox-gl-js version: 2.3.1

browser: MacOS FF

Steps to Trigger Behavior

  1. Create a symbol layer with text-variable-anchor ['left','top'] and text-radial-offset 1, such that a preferred placement (left) is generally not used and top is.
  2. Increase text-radial-offset to 3.

Expectation: anchors recalculated so that left is generally used now.

Actually: top is still used everywhere, just further away.

You can force it to recalculate only by modifying text-variable-anchor so that the previous anchor (top) is not possible anymore.

Screenshot 2021-07-22 at 2 29 34 PM Screenshot 2021-07-22 at 2 30 07 PM Screenshot 2021-07-22 at 2 30 25 PM Screenshot 2021-07-22 at 2 30 37 PM

The result after the 4th image is what I expect to see in the 2nd image.

rreusser commented 3 years ago

Thanks for filing the issue, @stevage. I had to dig a little, but I believe it's the placedOrientation field of symbols that stores the current placement state. I believe the reason for this behavior is to minimize visual changes when interacting with the map:

text-variable-anchor https://jsfiddle.net/6x1u7e0j/1/ (See marker 7 above, for example. The decision making behind marker 4 is a little less clear to me)

In other words, it's maybe like a one-way ratchet? Variable-placement symbols will improve placement if a label can't be displayed, but they won't revert to a more preferred placement if both placements become once again equally viable.

This behavior seems defensible, but perhaps what you've noticed is that this is persistent even when the style properties controlling it are modified. I wonder if it could flush the persistent state when the controlling properties are modified.

In short, I think I see and can reproduce what you're looking at, but if you'll permit me to ask, can you elaborate on your goal? I can imagine sticky state like this producing frustration while designing a map, and that's worth thinking about how to improve. Does it result in runtime issues for the end-user experience?

stevage commented 3 years ago

Yeah, I had sort of guessed it was a deliberate choice to avoid distracting visual changes. But yes, I think the state should be flushed when the style changes.

My goal? I don't really use Studio - I do all my style tweaking in JavaScript, often in the console. And I, hopefully not unreasonably, expect that any call to setLayoutProperty actually changes the style in the way it promises.

Does it result in runtime issues for the end-user experience?

Not directly.