Skip to content

Commit

Permalink
[core][tile mode] Further improve the label prioritization
Browse files Browse the repository at this point in the history
The most important variable labels a placed right away at
"populate intersections" phase, even if they do not actually
intersect the tile borders.
  • Loading branch information
pozdnyakov committed Apr 28, 2020
1 parent 2bf1610 commit b84449e
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions src/mbgl/text/placement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1279,15 +1279,15 @@ class TilePlacement : public StaticPlacement {
std::vector<PlacedSymbolData> placedSymbolsData;
std::vector<Intersection> intersections;
bool populateIntersections = false;
std::size_t intersectionPriority{};
std::size_t currentIntersectionPriority{};
bool collectData = false;
};

void TilePlacement::placeLayers(const RenderLayerReferences& layers) {
placedSymbolsData.clear();
seenCrossTileIDs.clear();
intersections.clear();
intersectionPriority = 0u;
currentIntersectionPriority = 0u;
// Populale intersections.
populateIntersections = true;
for (auto it = layers.crbegin(); it != layers.crend(); ++it) {
Expand Down Expand Up @@ -1319,11 +1319,10 @@ void TilePlacement::placeLayers(const RenderLayerReferences& layers) {
for (const auto& intersection : intersections) {
const SymbolInstance& symbol = intersection.symbol;
const PlacementContext& ctx = intersection.ctx;
currentIntersectionPriority = intersection.priority;
if (seenCrossTileIDs.count(symbol.crossTileID) != 0u) continue;
JointPlacement placement = placeSymbol(symbol, ctx);
if (shouldRetryPlacement(placement, ctx)) {
continue;
}
if (shouldRetryPlacement(placement, ctx)) continue;
seenCrossTileIDs.insert(symbol.crossTileID);
}
// Place the rest labels.
Expand Down Expand Up @@ -1464,10 +1463,10 @@ void TilePlacement::placeSymbolBucket(const BucketPlacementData& params, std::se
for (const SymbolInstance& symbol : symbolInstances) {
auto intersectStatus = symbolIntersectsTileEdges(symbol);
if (intersectStatus.flags == IntersectStatus::None) continue;
intersections.emplace_back(symbol, ctx, intersectStatus, intersectionPriority);
intersections.emplace_back(symbol, ctx, intersectStatus, currentIntersectionPriority);
}

++intersectionPriority;
++currentIntersectionPriority;
}

bool TilePlacement::canPlaceAtVariableAnchor(const CollisionBox& box,
Expand All @@ -1479,11 +1478,16 @@ bool TilePlacement::canPlaceAtVariableAnchor(const CollisionBox& box,
assert(tileBorders);
if (populateIntersections) {
// A variable label is only allowed to intersect tile border with the first anchor.
if (anchor != anchors.front()) return false;
// Check, that the label would intersect the tile borders even without shift, otherwise intersection
// is not allowed (preventing cut-offs in case the shift is lager than the buffer size).
auto status = collisionIndex.intersectsTileEdges(box, {}, posMatrix, textPixelRatio, *tileBorders);
return status.flags != IntersectStatus::None;
if (anchor == anchors.front()) {
// Check, that the label would intersect the tile borders even without shift, otherwise intersection
// is not allowed (preventing cut-offs in case the shift is lager than the buffer size).
auto status = collisionIndex.intersectsTileEdges(box, {}, posMatrix, textPixelRatio, *tileBorders);
if (status.flags != IntersectStatus::None) return true;
}
// The most important labels shall be placed first anyway, so we continue trying
// the following variable anchors for them; less priority labels
// will wait for the second round (when `populateIntersections` is `false`).
if (currentIntersectionPriority > 0u) return false;
}
// Can be placed, if it does not intersect tile borders.
auto status = collisionIndex.intersectsTileEdges(box, shift, posMatrix, textPixelRatio, *tileBorders);
Expand Down

0 comments on commit b84449e

Please sign in to comment.