diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index eaea1114d..1f4b73323 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -157,7 +157,7 @@ void Placement::placeSymbolBucket(const BucketPlacementData& params, std::set() == style::AlignmentType::Map; const bool pitchIconWithMap = layout.get() == style::AlignmentType::Map; - + const style::SymbolPlacementType placementType = layout.get(); const mat4& posMatrix = renderTile.matrix; mat4 textLabelPlaneMatrix = @@ -538,8 +538,12 @@ void Placement::placeSymbolBucket(const BucketPlacementData& params, std::setsecond, placementType, textBoxes, iconBoxes); seenCrossTileIDs.insert(symbolInstance.crossTileID); }; @@ -1159,6 +1163,7 @@ const RetainedQueryData& Placement::getQueryData(uint32_t bucketInstanceId) cons return it->second; } +/// Placement for Static map mode. class StaticPlacement : public Placement { public: explicit StaticPlacement(std::shared_ptr updateParameters_) @@ -1179,6 +1184,8 @@ void StaticPlacement::commit() { JointOpacityState(jointPlacement.second.text, jointPlacement.second.icon, jointPlacement.second.skipFade)); } } + +/// Placement for Tile map mode. class TilePlacement : public StaticPlacement { public: explicit TilePlacement(std::shared_ptr updateParameters_) @@ -1186,23 +1193,33 @@ public: private: void placeLayers(const RenderLayerReferences&) override; + void collectPlacedSymbolData(bool enable) override { collectData = enable; } + const std::vector& getPlacedSymbolsData() const override { return placedSymbolsData; } optional getAvoidEdges(const SymbolBucket&, const mat4&) override; SymbolInstanceReferences getSortedSymbols(const BucketPlacementData&, float pixelRatio) override; bool stickToFirstVariableAnchor(const CollisionBox& box, Point shift, const mat4& posMatrix, float textPixelRatio) override; + void newSymbolPlaced(const SymbolInstance&, + const JointPlacement&, + style::SymbolPlacementType, + const std::vector&, + const std::vector&) override; std::unordered_map locationCache; optional tileBorders; std::set seenCrossTileIDs; - bool onlyLabelsIntersectingTileBorders; + std::vector placedSymbolsData; + bool onlyLabelsIntersectingTileBorders = false; + bool collectData = false; }; void TilePlacement::placeLayers(const RenderLayerReferences& layers) { // In order to avoid label cut-offs, at first, place the labels, // which cross tile boundaries. onlyLabelsIntersectingTileBorders = true; + placedSymbolsData.clear(); seenCrossTileIDs.clear(); for (auto it = layers.crbegin(); it != layers.crend(); ++it) { placeLayer(*it, seenCrossTileIDs); @@ -1343,6 +1360,36 @@ bool TilePlacement::stickToFirstVariableAnchor(const CollisionBox& box, return collisionIndex.intersectsTileEdges(box, shift, posMatrix, textPixelRatio, *tileBorders); } +void TilePlacement::newSymbolPlaced(const SymbolInstance& symbol, + const JointPlacement& placement, + style::SymbolPlacementType placementType, + const std::vector& textBoxes, + const std::vector& iconBoxes) { + if (!collectData || placementType != style::SymbolPlacementType::Point) return; + + optional> textCollisionBox; + if (!textBoxes.empty()) { + assert(textBoxes.size() == 1u); + auto& box = textBoxes.front(); + assert(box.isBox()); + textCollisionBox = box.box(); + } + optional> iconCollisionBox; + if (!iconBoxes.empty()) { + assert(iconBoxes.size() == 1u); + auto& box = iconBoxes.front(); + assert(box.isBox()); + iconCollisionBox = box.box(); + } + PlacedSymbolData symbolData{symbol.key, + textCollisionBox, + iconCollisionBox, + placement.text, + placement.icon, + !placement.skipFade && onlyLabelsIntersectingTileBorders}; + placedSymbolsData.emplace_back(std::move(symbolData)); +} + // static Mutable Placement::create(std::shared_ptr updateParameters_, optional> prevPlacement) { diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp index af60f1a66..7fb5f7459 100644 --- a/src/mbgl/text/placement.hpp +++ b/src/mbgl/text/placement.hpp @@ -144,6 +144,11 @@ protected: void placeSymbolBucket(const BucketPlacementData&, std::set& seenCrossTileIDs); void placeLayer(const RenderLayer&, std::set&); virtual void commit(); + virtual void newSymbolPlaced(const SymbolInstance&, + const JointPlacement&, + style::SymbolPlacementType, + const std::vector& /*textBoxes*/, + const std::vector& /*iconBoxes*/) {} // Implentation specific hooks, which get called during a symbol bucket placement. virtual optional getAvoidEdges(const SymbolBucket&, const mat4& /*posMatrix*/) { return nullopt;