Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[core][tile mode] Fix variable placement + icon-text-fit #16382

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@
- `getPlacedSymbolsData()`
if collecting of the placed symbols data is enabled, returns the reference to the `PlacedSymbolData` vector holding the collected data.

### 🐞 Bug fixes

- [core][tile mode] Reduce cut-off labels (part 2) ([#16369](https://github.com/mapbox/mapbox-gl-native/pull/16369))

Now, the intersecting symbols are placed across all layers _symbol by symbol_ according to the following rules:

1. First we look, which of the tile border(s) the symbol intersects and prioritize the the symbol placement accordingly (high priority -> low priority): `vertical & horizontal -> vertical -> horizontal`
2. For the symbols that intersect the same tile border(s), assuming the tile border split symbol into several sections, we look at the minimal section length. The symbol with a larger minimal section length is placed first.
3. For the symbols that intersect the same tile border(s), and have equal minimal section length, we look at the anchor coordinates.
4. Finally, if all the previous criteria are the same, we look at the symbol key hashes.

- [core][tile mode] Fix variable placement for labels with the `icon-text-fit` property set ([#16382](https://github.com/mapbox/mapbox-gl-native/pull/16382))

The `symbolIntersectsTileEdges()` util in `mbgl::TilePlacement` now considers icon shift for the variable symbols with enabled icon-text-fit setting, thus providing more accurate results.

## maps-v1.5.1

### 🐞 Bug fixes
Expand All @@ -31,15 +46,6 @@

When dem tiles are loaded, border in neighboring tiles is updated, too leading to bucket re-upload. if std::move moved indices / vertices previously, they are empty and we get crash. Re-upload requires that only DEM texture is re-uploaded, not the quad vertices and indices.

- [core][tile mode] Reduce cut-off labels (part 2) ([#16369](https://github.com/mapbox/mapbox-gl-native/pull/16369))

Now, the intersecting symbols are placed across all layers _symbol by symbol_ according to the following rules:

1. First we look, which of the tile border(s) the symbol intersects and prioritize the the symbol placement accordingly (high priority -> low priority): `vertical & horizontal -> vertical -> horizontal`
2. For the symbols that intersect the same tile border(s), assuming the tile border split symbol into several sections, we look at the minimal section length. The symbol with a larger minimal section length is placed first.
3. For the symbols that intersect the same tile border(s), and have equal minimal section length, we look at the anchor coordinates.
4. Finally, if all the previous criteria are the same, we look at the symbol key hashes.

## maps-v1.5.0

### ✨ New features
Expand Down
16 changes: 15 additions & 1 deletion src/mbgl/text/placement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,7 @@ void TilePlacement::placeSymbolBucket(const BucketPlacementData& params, std::se
variableAnchor,
pitchTextWithMap = ctx.pitchTextWithMap,
rotateTextWithMap = ctx.rotateTextWithMap,
variableIconPlacement = ctx.hasIconTextFit && !ctx.iconAllowOverlap,
bearing = ctx.getTransformState().getBearing()
](const SymbolInstance& symbol) noexcept->IntersectStatus {
IntersectStatus result;
Expand All @@ -1430,7 +1431,20 @@ void TilePlacement::placeSymbolBucket(const BucketPlacementData& params, std::se

if (!symbol.iconCollisionFeature.boxes.empty()) {
const auto& iconCollisionBox = symbol.iconCollisionFeature.boxes.front();
auto iconIntersects = collisionBoxIntersectsTileEdges(iconCollisionBox, {});
Point<float> offset{};
if (variableAnchor && variableIconPlacement) {
float width = iconCollisionBox.x2 - iconCollisionBox.x1;
float height = iconCollisionBox.y2 - iconCollisionBox.y1;
offset = calculateVariableLayoutOffset(*variableAnchor,
width,
height,
symbol.variableTextOffset,
symbol.textBoxScale,
rotateTextWithMap,
pitchTextWithMap,
bearing);
}
auto iconIntersects = collisionBoxIntersectsTileEdges(iconCollisionBox, offset);
result.flags |= iconIntersects.flags;
result.minSectionLength = std::max(result.minSectionLength, iconIntersects.minSectionLength);
}
Expand Down