summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2020-03-26 13:18:08 +0200
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2020-04-02 11:50:52 +0300
commit3412331e4a3ae340e65ee7f9c3548b3127c23d2a (patch)
treebc247d44ec0797195106e2afa9f1f246f2eac785
parent5f4e33b1a3d14cdbebbfe724e51bdcba11f44437 (diff)
downloadqtlocation-mapboxgl-3412331e4a3ae340e65ee7f9c3548b3127c23d2a.tar.gz
[core][tile mode] Implement API to collect placed symbols data
-rw-r--r--src/mbgl/text/placement.cpp55
-rw-r--r--src/mbgl/text/placement.hpp5
2 files changed, 56 insertions, 4 deletions
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index eaea1114d6..1f4b73323e 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<ui
const bool rotateIconWithMap = layout.get<style::IconRotationAlignment>() == style::AlignmentType::Map;
const bool pitchIconWithMap = layout.get<style::IconPitchAlignment>() == style::AlignmentType::Map;
-
+ const style::SymbolPlacementType placementType = layout.get<style::SymbolPlacement>();
const mat4& posMatrix = renderTile.matrix;
mat4 textLabelPlaneMatrix =
@@ -538,8 +538,12 @@ void Placement::placeSymbolBucket(const BucketPlacementData& params, std::set<ui
// Erase it so that the placement result from the non-fading tile supersedes it
placements.erase(symbolInstance.crossTileID);
}
-
- placements.emplace(symbolInstance.crossTileID, JointPlacement(placeText || alwaysShowText, placeIcon || alwaysShowIcon, offscreen || bucket.justReloaded));
+
+ auto pair = placements.emplace(
+ symbolInstance.crossTileID,
+ JointPlacement(placeText || alwaysShowText, placeIcon || alwaysShowIcon, offscreen || bucket.justReloaded));
+ assert(pair.second);
+ newSymbolPlaced(symbolInstance, pair.first->second, 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<const UpdateParameters> 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<const UpdateParameters> updateParameters_)
@@ -1186,23 +1193,33 @@ public:
private:
void placeLayers(const RenderLayerReferences&) override;
+ void collectPlacedSymbolData(bool enable) override { collectData = enable; }
+ const std::vector<PlacedSymbolData>& getPlacedSymbolsData() const override { return placedSymbolsData; }
optional<CollisionBoundaries> getAvoidEdges(const SymbolBucket&, const mat4&) override;
SymbolInstanceReferences getSortedSymbols(const BucketPlacementData&, float pixelRatio) override;
bool stickToFirstVariableAnchor(const CollisionBox& box,
Point<float> shift,
const mat4& posMatrix,
float textPixelRatio) override;
+ void newSymbolPlaced(const SymbolInstance&,
+ const JointPlacement&,
+ style::SymbolPlacementType,
+ const std::vector<ProjectedCollisionBox>&,
+ const std::vector<ProjectedCollisionBox>&) override;
std::unordered_map<uint32_t, bool> locationCache;
optional<CollisionBoundaries> tileBorders;
std::set<uint32_t> seenCrossTileIDs;
- bool onlyLabelsIntersectingTileBorders;
+ std::vector<PlacedSymbolData> 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<ProjectedCollisionBox>& textBoxes,
+ const std::vector<ProjectedCollisionBox>& iconBoxes) {
+ if (!collectData || placementType != style::SymbolPlacementType::Point) return;
+
+ optional<mapbox::geometry::box<float>> textCollisionBox;
+ if (!textBoxes.empty()) {
+ assert(textBoxes.size() == 1u);
+ auto& box = textBoxes.front();
+ assert(box.isBox());
+ textCollisionBox = box.box();
+ }
+ optional<mapbox::geometry::box<float>> 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> Placement::create(std::shared_ptr<const UpdateParameters> updateParameters_,
optional<Immutable<Placement>> prevPlacement) {
diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp
index af60f1a66b..7fb5f74599 100644
--- a/src/mbgl/text/placement.hpp
+++ b/src/mbgl/text/placement.hpp
@@ -144,6 +144,11 @@ protected:
void placeSymbolBucket(const BucketPlacementData&, std::set<uint32_t>& seenCrossTileIDs);
void placeLayer(const RenderLayer&, std::set<uint32_t>&);
virtual void commit();
+ virtual void newSymbolPlaced(const SymbolInstance&,
+ const JointPlacement&,
+ style::SymbolPlacementType,
+ const std::vector<ProjectedCollisionBox>& /*textBoxes*/,
+ const std::vector<ProjectedCollisionBox>& /*iconBoxes*/) {}
// Implentation specific hooks, which get called during a symbol bucket placement.
virtual optional<CollisionBoundaries> getAvoidEdges(const SymbolBucket&, const mat4& /*posMatrix*/) {
return nullopt;