summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-12-20 17:29:30 +0200
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2020-03-12 23:35:55 +0200
commit7a2126bebb080c6f7b013dbe94ca4cd242b71136 (patch)
tree65dfdc73be790065a5b3c5089860dfc0df3998a5
parent04d840de53e4cbdff886a35c1b8e3d7877fa6281 (diff)
downloadqtlocation-mapboxgl-7a2126bebb080c6f7b013dbe94ca4cd242b71136.tar.gz
[core] Place already visible symbols first and hidden symbols last
-rw-r--r--src/mbgl/text/placement.cpp27
-rw-r--r--src/mbgl/text/placement.hpp3
2 files changed, 29 insertions, 1 deletions
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index d6d6e269bc..f5e0be0829 100644
--- a/src/mbgl/text/placement.cpp
+++ b/src/mbgl/text/placement.cpp
@@ -662,7 +662,25 @@ void Placement::placeSymbolBucket(const BucketPlacementData& params, std::set<ui
}
} else {
- for (const SymbolInstance& symbol : bucket.getSymbols(params.sortKeyRange)) {
+ auto sortedSymbols = bucket.getSymbols(params.sortKeyRange);
+ if (auto* previousPlacement = getPrevPlacement()) {
+ std::stable_sort(
+ sortedSymbols.begin(), sortedSymbols.end(), [&](const SymbolInstance& a, const SymbolInstance& b) {
+ auto* aPlacement = previousPlacement->getSymbolPlacement(a);
+ auto* bPlacement = previousPlacement->getSymbolPlacement(b);
+ if (!aPlacement) {
+ // a < b, if 'a' is new and if 'b' was previously hidden.
+ return bPlacement && !bPlacement->placed();
+ }
+ if (!bPlacement) {
+ // a < b, if 'b' is new and 'a' was previously shown.
+ return aPlacement && aPlacement->placed();
+ }
+ // a < b, if 'a' was shown and 'b' was hidden.
+ return aPlacement->placed() && !bPlacement->placed();
+ });
+ }
+ for (const SymbolInstance& symbol : sortedSymbols) {
placeSymbol(symbol);
}
}
@@ -1203,6 +1221,13 @@ float Placement::zoomAdjustment(const float zoom) const {
return std::max(0.0, (placementZoom - zoom) / 1.5);
}
+const JointPlacement* Placement::getSymbolPlacement(const SymbolInstance& symbol) const {
+ assert(symbol.crossTileID != 0);
+ auto found = placements.find(symbol.crossTileID);
+ if (found == placements.end()) return nullptr;
+ return &found->second;
+}
+
Duration Placement::getUpdatePeriod(const float zoom) const {
// Even if transitionOptions.duration is set to a value < 300ms, we still wait for this default transition duration
// before attempting another placement operation.
diff --git a/src/mbgl/text/placement.hpp b/src/mbgl/text/placement.hpp
index df7345d4cc..b2ad5d62e0 100644
--- a/src/mbgl/text/placement.hpp
+++ b/src/mbgl/text/placement.hpp
@@ -49,6 +49,8 @@ public:
: text(text_), icon(icon_), skipFade(skipFade_)
{}
+ bool placed() const { return text || icon; }
+
const bool text;
const bool icon;
// skipFade = outside viewport, but within CollisionIndex::viewportPadding px of the edge
@@ -119,6 +121,7 @@ public:
Duration getUpdatePeriod(const float zoom) const;
float zoomAdjustment(const float zoom) const;
+ const JointPlacement* getSymbolPlacement(const SymbolInstance&) const;
const RetainedQueryData& getQueryData(uint32_t bucketInstanceId) const;