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

Add icon-overlap, text-overlap layout properties #347

Merged
merged 18 commits into from
Jan 26, 2022

Conversation

drwestco
Copy link
Contributor

@drwestco drwestco commented Sep 16, 2021

This change allows for finer control of symbol overlap behavior than offered by icon-allow-overlap, text-allow-overlap. It meets my needs, but I'm offering this draft PR for further refinement - do the changes make sense in general, are there clearer ways to present these options, etc.

I still need to add tests for this new behavior. But wanted to get some eyes on this before spending time doing so.

This new feature is to address #249

Current overlap behavior

When a symbol is placed, and collides with a previously-placed symbol, one of two things will happen:

  1. If the new symbol has -allow-overlap: false, the placement is rejected.
  2. If the new symbol has -allow-overlap: true, the placement is accepted, and the new symbol overlaps the old. This happens regardless of whether the previously-placed symbol has -allow-overlap or not.

So collision is a one-way process. A symbol in a foreground layer gets placed first. A symbol in a background layer gets placed second. The foreground symbol has no say in whether the background symbol overlaps (underlaps) or not.

New overlap behavior

icon-overlap/text-overlap has three states: never, always, and cooperative. When a symbol is placed, and collides with a previously-placed symbol, there are now three options:

  1. If the new symbol has -overlap: 'never', the placement is rejected (same as -allow-overlap: false).
  2. If the new symbol has -overlap: 'always', the placement is accepted (same as -allow-overlap: true).
  3. If the new symbol has -overlap: 'cooperative', the overlap mode of the previously-placed symbol is checked. The placement is accepted if the previously-placed symbol is also using -overlap: 'cooperative' or -overlap: 'always'. If the previously-placed symbol is using -overlap: 'never', the new symbol's placement is rejected.

The new behavior is opt-in. If -overlap is set, it's used; otherwise the code falls back to the existing -allow-overlap properties.

@github-actions
Copy link
Contributor

github-actions bot commented Sep 16, 2021

Bundle size report:

Size Change: +252 B
Total Size Before: 193 kB
Total Size After: 194 kB

Output file Before After Change
maplibre-gl.js 184 kB 184 kB +252 B
maplibre-gl.css 9.49 kB 9.49 kB 0 B
ℹ️ View Details
Source file Before After Change
rollup/build/tsc/src/symbol/grid_index.js 1.26 kB 1.35 kB +96 B
rollup/build/tsc/src/util/evented.js 3.84 kB 3.9 kB +52 B
rollup/build/tsc/src/symbol/placement.js 4.65 kB 4.71 kB +51 B
rollup/build/tsc/src/style/style_layer/symbol_style_layer.js 973 B 1.01 kB +42 B
rollup/build/tsc/src/symbol/collision_index.js 1.58 kB 1.61 kB +30 B
rollup/build/tsc/src/data/bucket/symbol_bucket.js 4.24 kB 4.26 kB +19 B
rollup/build/tsc/src/util/ajax.js 2.31 kB 2.32 kB +13 B
rollup/build/tsc/src/style/style_layer/symbol_style_layer_properties.js 645 B 652 B +7 B
rollup/build/tsc/src/render/draw_symbol.js 2.48 kB 2.49 kB +4 B
rollup/build/tsc/src/geo/lng_lat.js 583 B 584 B +1 B
rollup/build/tsc/src/geo/lng_lat_bounds.js 613 B 614 B +1 B
rollup/build/tsc/src/data/feature_index.js 1.7 kB 1.7 kB +1 B
rollup/build/tsc/src/symbol/projection.js 1.78 kB 1.78 kB +1 B
rollup/build/tsc/src/symbol/cross_tile_symbol_index.js 1.13 kB 1.14 kB +1 B
rollup/build/tsc/src/render/draw_fill.js 977 B 978 B +1 B
rollup/build/tsc/src/render/draw_raster.js 1 kB 1 kB +1 B
rollup/build/tsc/src/render/draw_debug.js 1.11 kB 1.11 kB +1 B
rollup/build/tsc/src/render/draw_heatmap.js 1.04 kB 1.04 kB +1 B
rollup/build/tsc/src/render/draw_background.js 528 B 529 B +1 B
rollup/build/tsc/src/util/primitives.js 977 B 978 B +1 B
rollup/build/tsc/src/ui/handler/handler_util.js 99 B 100 B +1 B
rollup/build/tsc/src/ui/handler/tap_zoom.js 365 B 366 B +1 B
rollup/build/tsc/src/ui/handler/touch_pan.js 436 B 437 B +1 B
rollup/build/tsc/src/ui/handler/click_zoom.js 240 B 241 B +1 B
rollup/build/tsc/src/ui/handler/shim/drag_pan.js 222 B 223 B +1 B
rollup/build/tsc/src/ui/default_locale.js 283 B 284 B +1 B
rollup/build/tsc/src/ui/control/scale_control.js 741 B 742 B +1 B
rollup/build/tsc/src/style/style.js 6.56 kB 6.56 kB -1 B
rollup/build/tsc/src/data/pos_attributes.js 7.07 kB 7.07 kB -1 B
rollup/build/tsc/src/render/program.js 912 B 911 B -1 B
rollup/build/tsc/src/render/program/fill_extrusion_program.js 801 B 800 B -1 B
rollup/build/tsc/src/render/program/raster_program.js 565 B 564 B -1 B
rollup/build/tsc/src/render/painter.js 3.31 kB 3.3 kB -1 B
rollup/build/tsc/src/geo/edge_insets.js 432 B 431 B -1 B
rollup/build/tsc/src/geo/transform.js 3.78 kB 3.78 kB -1 B
rollup/build/tsc/src/ui/handler/mouse.js 554 B 553 B -1 B
rollup/build/tsc/src/ui/map.js 6.16 kB 6.16 kB -1 B
rollup/build/tsc/src/util/smart_wrap.js 234 B 233 B -1 B
rollup/build/tsc/src/source/tile_id.js 1.1 kB 1.1 kB -2 B
rollup/build/tsc/src/index.js 674 B 672 B -2 B
rollup/build/tsc/src/ui/handler_inertia.js 825 B 822 B -3 B
rollup/build/tsc/src/ui/popup.js 1.91 kB 1.91 kB -3 B

debug/symbols.html Outdated Show resolved Hide resolved
@HarelM
Copy link
Collaborator

HarelM commented Sep 16, 2021

A few things to note here:

  1. There was a process of updating the style which allowed updating the code by running some codegen script. This broke when migrating to typescript and out of flow. I think this is an opportunity to revisit this part and decide how to proceed with this.
  2. If we are changing the spec we need to make sure other platforms are following (native, ios, android, etc)
  3. I'm not sure the terms are intuitive, in not sure I can think of better terms, but we might need to refine the definition.
  4. This doesn't break existing styles, right?

I haven't looked deep into the code, but I saw some good changes related to typings, kudos!

Overall, I think this is a good step forward! I guess it's worth talking about it in the committee.

@drwestco
Copy link
Contributor Author

Existing styles should be unaffected. -allow-overlap behaves the same as before, and the new -overlap properties are optional add-ons. I'm not thrilled with the property values either; happy to entertain other suggestions.

@HarelM
Copy link
Collaborator

HarelM commented Nov 2, 2021

Can you please resolve conflicts.
Also I think the procedure of cradling code from the style spec should be functional again, it works be good to make sure it handles this case as well, look for codegen in packake.json file.
Once everything is ready I'll be happy to review this.
Thanks for the effort!!

Add new symbol layout properties to allow finer control over symbol overlap behavior. New 'cooperative' mode allows opt-in behavior for overlap. A 'cooperative' symbol may only overlap another symbol that also uses 'cooperative' or 'full' overlap modes.
Default should be undefined, not literal string 'unset'.
@drwestco drwestco marked this pull request as ready for review November 2, 2021 22:52
@ghost
Copy link

ghost commented Nov 3, 2021

I have trouble thinking of a use-case for this, and I wonder if there might already be other existing mechanisms to support this.

Wasn't https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#layout-symbol-symbol-sort-key meant to affect behaviour like this? That said, there appears to be some criticism there, too: mapbox/mapbox-gl-js#9368, and it requires modifications of the data to add the sort-key to each feature.

src/symbol/grid_index.ts Outdated Show resolved Hide resolved
@drwestco
Copy link
Contributor Author

Had an alternate idea for "icon-overlap": "cooperative". A more flexible approach would be "icon-overlap": "group", meaning symbols would be allowed to overlap other symbols within the same group or symbols using the always overlap property. This would require an additional numeric/string property (symbol-overlap-group or similar) to indicate the group, though, so the additional complexity may outweigh the flexibility?

@HarelM
Copy link
Collaborator

HarelM commented Nov 29, 2021

For me this seems too complicated, but other people who might have more complicated cases may need this flexibility, I don't know.
If we can have both cooperative and group (as in both would have distinct definition), maybe we can add group in the future as non breaking change - I.e. Enhancement...?

@drwestco
Copy link
Contributor Author

Having both cooperative and group is confusing. cooperative is essentially just group, where all symbols using cooperative are part of the same group. That would be the same as specifying group and not specifying a group name/ID - so all symbols are in the default group.

So if the idea is to add a new group name/ID property later, I'd still rename cooperative to group now.

Also happy to just leave it as-is...

@HarelM
Copy link
Collaborator

HarelM commented Dec 7, 2021

I think the code is good, I'm just not sure how to signal the library users that something is now deprecated, and they should start migrating to the new "syntax", that's the only concern I got related to this PR.

@wipfli
Copy link
Contributor

wipfli commented Dec 12, 2021

The style specification has seen a series of feature deprecations and breaking changes. A lot happened around version 8.0.0, see https://github.com/maplibre/maplibre-gl-js/blob/main/src/style-spec/CHANGELOG.md#800. From reading the style spec changelog, it seems the way to go about feature deprecation is to add a note in the changelog. Once the feature gets removed, the major version of the style spec has to increment, the changelog has to include a note about the breaking change, and the gl-style-migrate script has to be updated to give users an automated migration path.

@wipfli
Copy link
Contributor

wipfli commented Dec 12, 2021

@drwestco TODOs are:

  • include note about new feature in style spec changelog
  • include note about deprecation in style spec changelog
  • bump minor version of changelog

@drwestco
Copy link
Contributor Author

Noticed this wasn't included in the 2.0.0 release. What's the next step for getting it merged?

@wipfli
Copy link
Contributor

wipfli commented Jan 20, 2022

I would say we should merge this and bump to v2.1.0, what do you think @HarelM?

@HarelM
Copy link
Collaborator

HarelM commented Jan 20, 2022

Sure :-)

@wipfli
Copy link
Contributor

wipfli commented Jan 21, 2022

@drwestco, can you add a render test for this new functionality?

https://github.com/maplibre/maplibre-gl-js/tree/main/test/integration#writing-new-tests

],
"sdk-support": {
"basic functionality": {
"js": "2.0.0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HarelM can we merge this pull request for v2.0.6? Or should it be v2.1.0?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In any case, when we merge this pull request, we should probably release a new version of GL JS and bump the version number in package.json

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2.1.0 is better I think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, let's use 2.1.0. @drwestco please change the version here to 2.1.0 here. Also increment the version in package.json to 2.1.0:

"version": "2.0.5",

And add a note in the changelog under a new subsection called 2.1.0 (https://github.com/maplibre/maplibre-gl-js/blob/main/CHANGELOG.md#main)

@wipfli
Copy link
Contributor

wipfli commented Jan 25, 2022

Thanks @drwestco for the render tests.

Copy link
Collaborator

@HarelM HarelM left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some files here that require better indentation, I suggest to do it in a separate PR though...

@HarelM
Copy link
Collaborator

HarelM commented Jan 26, 2022

You need to resolve conflicts...

CHANGELOG.md Show resolved Hide resolved
@HarelM HarelM mentioned this pull request Jan 26, 2022
@wipfli
Copy link
Contributor

wipfli commented Mar 14, 2022

Regarding deprecating features: Mapbox took the stance to effectively never deprecate features or introduce breaking changes to the style specification. Whether or not we want to do the same is up to us. See mapbox/mapbox-gl-js#6584

@drwestco drwestco deleted the symbol-overlap branch March 22, 2022 20:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants