Line features with same text-field but different icon-image should not be merged
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 12.4k
- Forks
- 2.4k
- PR merge metrics
- No merged PRs in 30d
Description
**mapbox-gl-js version**: 0.27.0
When the map is overzoomed, line features with identical `text-field` values but different `icon-image` values are incorrectly merged together.
For [this OpenStreetMap diary entry](http://www.openstreetmap.org/user/Minh%20Nguyen/diary/39123), I created a style based on the Mapbox Streets source that shows a different state route shield for the U.S. states of Ohio, Kentucky, and Indiana. The shield image is selected by assigning an `icon-image` of `us-state-{reflen}-{iso_3166_2}`.

In this screenshot, everything west of the state line should have the rectangular Indiana shield, while everything to the east of the state line should have the Ohio-shaped Ohio shield. Unfortunately, at zoom levels 16 and above – that is, beyond the Mapbox Streets source’s maximum zoom level – GL JS shows the Ohio shield on part of SR 252 on the Indiana side.
In OpenStreetMap, SR 252 is actually two ways: [210557386](http://www.openstreetmap.org/way/210557386) comes near the state line but doesn’t cross it, while the much shorter [203231052](http://www.openstreetmap.org/way/203231052) is a bridge that crosses the state line. Because the bridge’s center lies within Ohio, the entirety of 203231052 is tagged `iso_3166_2=US-OH` in the Mapbox Streets source. But 210557386 should always show the Indiana shield, because it’s tagged `iso_3166_2=US-IN` in the source.
@ajashton helped me track down the issue to mapbox/mapbox-gl-js#683, in which label lines are merged based on their text. In this case, both lines are apparently merged because they have the same text (`252`). However, each would have a different icon image, so they shouldn’t have been merged.
You can see the problem more clearly in this reduced test case: mapbox/mapbox-gl-test-suite@fdc08ed94f364a4fc76718aa12fbe1c13947d5bb. In this test case, I set `icon-image` to `bogus-{reflen}-{iso_3166_2}-18` and `text-field` to `{ref}`, similar to the style above. (I also set `text-opacity` to 0 for effect.) We should see the S’s give way to U’s as we go east to west:

However, I actually see S’s all the way across:

In fact, I generated the “expected” screenshot above by removing the `text-field` property. In the absence of `text-field`, either no merging occurs or the merging algorithm is more thorough somehow.
My use case requires a custom style, but it’s also the main use case for ISO 3166-2 codes on roads in the Mapbox Streets source. It’s also entirely possible that there are cases where this issue reproduces in an unmodified Mapbox Streets style. Suppose a U.S. route 25 has been decommissioned up to a state line, reverting to State Route 25 on one side, per standard practice. This would mean two adjoining lines would both have a `text-field` of `25`, but one would have a `shield` of `us-highway` while the other has `us-state`.
This issue also reproduces in gl-native master as of mapbox/mapbox-gl-native@f7db6cf7601e5d97492622cab76ed38ce692b37c.
/cc @mourner @jfirebaugh
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the reduced test case at mapbox/mapbox-gl-test-suite@fdc08ed94f364a4fc76718aa12fbe1c13947d5bb and compare its behavior with mapbox-gl-js#683. Trace the label-line merging path described in the issue, checking why identical text-field values override different icon-image values. Done means adjacent lines retain their distinct shields at overzoomed levels, including the expected S-to-U transition.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- computer-graphics, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100