summaryrefslogtreecommitdiff
path: root/src/mbgl/text/placement.cpp
diff options
context:
space:
mode:
authorChris Loer <chris.loer@gmail.com>2018-04-18 16:33:37 -0700
committerChris Loer <chris.loer@mapbox.com>2018-04-25 14:39:03 -0700
commita62745edf9ee2da1f6ebda07acfd8260f3696e50 (patch)
tree3a756eecca1f9bbd03d588f3926425df43333dc7 /src/mbgl/text/placement.cpp
parenteb39c80604935deb666907f90ddc31f50865f828 (diff)
downloadqtlocation-mapboxgl-a62745edf9ee2da1f6ebda07acfd8260f3696e50.tar.gz
Port global symbol query from GL JS:
- Symbol querying is now global instead of per-tile - Symbols that bleed over tile boundaries no longer missed in queries - Symbol results now sorted based on rendering order (ie overlapping symbols change their sort order when a bearing change causes their render order to change) - Placement::retainedQueryData now responsible for maintaining symbol querying data for buckets that may no longer be in the TilePyramid.
Diffstat (limited to 'src/mbgl/text/placement.cpp')
-rw-r--r--src/mbgl/text/placement.cpp36
1 files changed, 28 insertions, 8 deletions
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index 54b2b7539b..daf996356e 100644
--- a/src/mbgl/text/placement.cpp
+++ b/src/mbgl/text/placement.cpp
@@ -46,11 +46,13 @@ void Placement::placeLayer(RenderSymbolLayer& symbolLayer, const mat4& projMatri
std::unordered_set<uint32_t> seenCrossTileIDs;
for (RenderTile& renderTile : symbolLayer.renderTiles) {
- if (!renderTile.tile.isRenderable()) {
+ if (!renderTile.tile.isRenderable() || !dynamic_cast<GeometryTile*>(&renderTile.tile)) {
continue;
}
-
- auto bucket = renderTile.tile.getBucket(*symbolLayer.baseImpl);
+ GeometryTile& geometryTile = static_cast<GeometryTile&>(renderTile.tile);
+
+
+ auto bucket = geometryTile.getBucket(*symbolLayer.baseImpl);
assert(dynamic_cast<SymbolBucket*>(bucket));
SymbolBucket& symbolBucket = *reinterpret_cast<SymbolBucket*>(bucket);
@@ -58,8 +60,8 @@ void Placement::placeLayer(RenderSymbolLayer& symbolLayer, const mat4& projMatri
const float pixelsToTileUnits = renderTile.id.pixelsToTileUnits(1, state.getZoom());
- const float scale = std::pow(2, state.getZoom() - renderTile.tile.id.overscaledZ);
- const float textPixelRatio = (util::tileSize * renderTile.tile.id.overscaleFactor()) / util::EXTENT;
+ const float scale = std::pow(2, state.getZoom() - geometryTile.id.overscaledZ);
+ const float textPixelRatio = (util::tileSize * geometryTile.id.overscaleFactor()) / util::EXTENT;
mat4 posMatrix;
state.matrixFor(posMatrix, renderTile.id);
@@ -76,7 +78,14 @@ void Placement::placeLayer(RenderSymbolLayer& symbolLayer, const mat4& projMatri
layout.get<style::IconRotationAlignment>() == style::AlignmentType::Map,
state,
pixelsToTileUnits);
-
+
+
+ // As long as this placement lives, we have to hold onto this bucket's
+ // matching FeatureIndex/data for querying purposes
+ retainedQueryData.emplace(std::piecewise_construct,
+ std::forward_as_tuple(symbolBucket.bucketInstanceId),
+ std::forward_as_tuple(symbolBucket.bucketInstanceId, geometryTile.getFeatureIndex(), geometryTile.id));
+
placeLayerBucket(symbolBucket, posMatrix, textLabelPlaneMatrix, iconLabelPlaneMatrix, scale, textPixelRatio, showCollisionBoxes, seenCrossTileIDs, renderTile.tile.holdForFade());
}
}
@@ -150,11 +159,11 @@ void Placement::placeLayerBucket(
}
if (placeText) {
- collisionIndex.insertFeature(symbolInstance.textCollisionFeature, bucket.layout.get<style::TextIgnorePlacement>());
+ collisionIndex.insertFeature(symbolInstance.textCollisionFeature, bucket.layout.get<style::TextIgnorePlacement>(), bucket.bucketInstanceId);
}
if (placeIcon) {
- collisionIndex.insertFeature(symbolInstance.iconCollisionFeature, bucket.layout.get<style::IconIgnorePlacement>());
+ collisionIndex.insertFeature(symbolInstance.iconCollisionFeature, bucket.layout.get<style::IconIgnorePlacement>(), bucket.bucketInstanceId);
}
assert(symbolInstance.crossTileID != 0);
@@ -305,6 +314,9 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>&
bucket.updateOpacity();
bucket.sortFeatures(state.getAngle());
+ if (retainedQueryData.find(bucket.bucketInstanceId) != retainedQueryData.end()) {
+ retainedQueryData.find(bucket.bucketInstanceId)->second.featureSortOrder = bucket.featureSortOrder;
+ }
}
float Placement::symbolFadeChange(TimePoint now) const {
@@ -337,5 +349,13 @@ void Placement::setStale() {
const CollisionIndex& Placement::getCollisionIndex() const {
return collisionIndex;
}
+
+const RetainedQueryData& Placement::getQueryData(uint32_t bucketInstanceId) const {
+ auto it = retainedQueryData.find(bucketInstanceId);
+ if (it == retainedQueryData.end()) {
+ throw std::runtime_error("Placement::getQueryData with unrecognized bucketInstanceId");
+ }
+ return it->second;
+}
} // namespace mbgl