maplibre / maplibre-gl-js

MapLibre GL JS - Interactive vector tile maps in the browser
https://maplibre.org/maplibre-gl-js/docs/
Other
6.67k stars 716 forks source link

Interpolated text-size incorrectly applied to line symbols #949

Open drwestco opened 2 years ago

drwestco commented 2 years ago

maplibre-gl-js version: 1.15+, 2.1.0+ (all)

browser: Chrome (all?)

Steps to Trigger Behavior

  1. Add symbol layer with symbol-placement=line, text-size=interpolate...
  2. Set the end point of the interpolation to a high zoom level and large font size
  3. Set the mid point of the interpolation to a mid-range zoom and small font size
  4. View the map at the mid-range zoom level
  5. Change the end point of the interpolation to a small font size, and refresh the map

Link to Demonstration

https://jsbin.com/votudaq/edit?html,output

Expected Behavior

The text-size at zoom level 13 is 10, so there should be plenty of room to show the label.

Actual Behavior

It looks like the maximum text size (15, at zoom level 18) is used to calculate the maximum text width, and this is compared against the current line length at zoom level 13, so the label is rejected.

There's this comment in symbol_layout, addFeature. So this may be intentional, though it's a very odd decision.


    // To reduce the number of labels that jump around when zooming we need
    // to use a text-size value that is the same for all zoom levels.
    // bucket calculates text-size at a high zoom level so that all tiles can
    // use the same value when calculating anchor positions.
    let textMaxSize = sizes.textMaxSize.evaluate(feature, {});
    if (textMaxSize === undefined) {
        textMaxSize = layoutTextSize;
    }
xabbu42 commented 2 years ago

I also stumbled over this. We precalculate label placements and only send a line geometry long enough for the actual placement we want. This heuristic for the automatic client side label placements limits what we can do with this approach.

That said I understand the given reasoning and that the current approach is in some cases better for automatic label placement. Next steps should be to reproduce the negative behavior they describe and think about possible config options to make this code more flexibel.

github-actions[bot] commented 2 years ago

This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 30 days.

birkskyum commented 2 years ago

keep

zerda-ocm commented 1 year ago

I just want to give this issue a little bit more awareness: I want to scale a text the same amount as the map, but since my line where i placed the text is "to short", texts disappear way to early. Since I will allow overlapping texts, labels that jump around shouldn't be an issue (at least for me). A quick hack or workaround would be acceptable for now and I could try to implement it myself, but I have no idea where to start.

xabbu42 commented 1 year ago

I think you want to change https://github.com/maplibre/maplibre-gl-js/blob/bd6c8745eac7709e10a053914dd49d59ccc0390b/src/symbol/symbol_layout.ts#L383 so that textMaxSize is always set to layoutTextSize. Let me know if that does what you want.

zerda-ocm commented 1 year ago

I think you want to change

https://github.com/maplibre/maplibre-gl-js/blob/bd6c8745eac7709e10a053914dd49d59ccc0390b/src/symbol/symbol_layout.ts#L383

so that textMaxSize is always set to layoutTextSize. Let me know if that does what you want.

That sounds about right.