From 88337c23f7abd71a8a12401b2e24312f32846634 Mon Sep 17 00:00:00 2001 From: Mikhail Pozdnyakov Date: Mon, 6 Apr 2020 16:56:57 +0300 Subject: [PATCH] [core][tile mode] Improve placement algorithm for variable labels --- src/mbgl/text/placement.cpp | 31 +++++++++++++++++++------------ src/mbgl/text/placement.hpp | 12 +++++++----- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index e825fc330..fa7436cfc 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -390,7 +390,6 @@ void Placement::placeSymbol(const SymbolInstance& symbolInstance, const size_t placementAttempts = ctx.textAllowOverlap ? anchorsSize * 2 : anchorsSize; for (size_t i = 0u; i < placementAttempts; ++i) { auto anchor = variableTextAnchors[i % anchorsSize]; - const bool isFirstAnchor = (anchor == variableTextAnchors.front()); const bool allowOverlap = (i >= anchorsSize); shift = calculateVariableLayoutOffset(anchor, width, @@ -401,9 +400,8 @@ void Placement::placeSymbol(const SymbolInstance& symbolInstance, ctx.pitchTextWithMap, ctx.getTransformState().getBearing()); textBoxes.clear(); - if (!isFirstAnchor && - stickToFirstVariableAnchor( - symbolInstance.textCollisionFeature.boxes.front(), shift, posMatrix, ctx.pixelRatio)) { + if (!canPlaceAtVariableAnchor( + textBox, anchor, shift, variableTextAnchors, posMatrix, ctx.pixelRatio)) { continue; } @@ -1263,10 +1261,12 @@ private: const std::vector& getPlacedSymbolsData() const override { return placedSymbolsData; } optional getAvoidEdges(const SymbolBucket&, const mat4&) override; - bool stickToFirstVariableAnchor(const CollisionBox& box, - Point shift, - const mat4& posMatrix, - float textPixelRatio) override; + bool canPlaceAtVariableAnchor(const CollisionBox& box, + TextVariableAnchorType anchor, + Point shift, + std::vector& anchors, + const mat4& posMatrix, + float textPixelRatio) override; void newSymbolPlaced(const SymbolInstance&, const JointPlacement&, style::SymbolPlacementType, @@ -1438,12 +1438,19 @@ void TilePlacement::placeSymbolBucket(const BucketPlacementData& params, std::se } } -bool TilePlacement::stickToFirstVariableAnchor(const CollisionBox& box, - Point shift, - const mat4& posMatrix, - float textPixelRatio) { +bool TilePlacement::canPlaceAtVariableAnchor(const CollisionBox& box, + TextVariableAnchorType anchor, + Point shift, + std::vector& anchors, + const mat4& posMatrix, + float textPixelRatio) { assert(tileBorders); auto status = collisionIndex.intersectsTileEdges(box, shift, posMatrix, textPixelRatio, *tileBorders); + if (status.flags == IntersectStatus::None) return true; + + if (anchor != anchors.front()) return false; + + status = collisionIndex.intersectsTileEdges(box, {}, posMatrix, textPixelRatio, *tileBorders); return status.flags != IntersectStatus::None; } diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp index 12a147e98..e62d2bdf3 100644 --- a/src/mbgl/text/placement.hpp +++ b/src/mbgl/text/placement.hpp @@ -157,11 +157,13 @@ protected: return nullopt; } SymbolInstanceReferences getSortedSymbols(const BucketPlacementData&, float pixelRatio); - virtual bool stickToFirstVariableAnchor(const CollisionBox&, - Point /*shift*/, - const mat4& /*posMatrix*/, - float /*textPixelRatio*/) { - return false; + virtual bool canPlaceAtVariableAnchor(const CollisionBox&, + style::TextVariableAnchorType, + Point /*shift*/, + std::vector&, + const mat4& /*posMatrix*/, + float /*textPixelRatio*/) { + return true; } // Returns `true` if bucket vertices were updated; returns `false` otherwise.