summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2019-12-04 12:20:09 +0200
committerMikhail Pozdnyakov <mikhail.pozdnyakov@mapbox.com>2020-01-08 12:43:26 +0200
commit7e5dc5608a34c691660160ae68746477662b5425 (patch)
tree44ec24d0438fe30b274d5fadbc6f4cc8993419a4
parent07194f7fa55985aec36f7bd46ceda84ca60503b5 (diff)
downloadqtlocation-mapboxgl-7e5dc5608a34c691660160ae68746477662b5425.tar.gz
[core] Pre-defined variable anchor at tile borders
In tile mode, stick to the first variable anchor if the label intersects tile borders.
-rw-r--r--src/mbgl/text/collision_index.cpp2
-rw-r--r--src/mbgl/text/placement.cpp67
2 files changed, 49 insertions, 20 deletions
diff --git a/src/mbgl/text/collision_index.cpp b/src/mbgl/text/collision_index.cpp
index c99eb3da39..7f22d884c9 100644
--- a/src/mbgl/text/collision_index.cpp
+++ b/src/mbgl/text/collision_index.cpp
@@ -108,7 +108,7 @@ bool CollisionIndex::featureIntersectsTileBorders(const CollisionFeature& featur
float px2 = (box.x2 + shift.x) * tileToViewport + projectedPoint.first.x;
float py2 = (box.y2 + shift.y) * tileToViewport + projectedPoint.first.y;
- return !intersectsTileBorders(px1, py1, px2, py2, tileEdges);
+ return intersectsTileBorders(px1, py1, px2, py2, tileEdges);
}
std::pair<bool,bool> CollisionIndex::placeFeature(const CollisionFeature& feature,
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index 8fa91c24a7..5e59e91465 100644
--- a/src/mbgl/text/placement.cpp
+++ b/src/mbgl/text/placement.cpp
@@ -174,11 +174,13 @@ void Placement::placeBucket(
auto partiallyEvaluatedTextSize = bucket.textSizeBinder->evaluateForZoom(state.getZoom());
auto partiallyEvaluatedIconSize = bucket.iconSizeBinder->evaluateForZoom(state.getZoom());
+ optional<CollisionTileBoundaries> tileBorders;
optional<CollisionTileBoundaries> avoidEdges;
- if (mapMode == MapMode::Tile && (layout.get<style::SymbolAvoidEdges>() ||
- layout.get<style::SymbolPlacement>() == style::SymbolPlacementType::Line ||
- !layout.get<style::TextVariableAnchor>().empty())) {
- avoidEdges = collisionIndex.projectTileBoundaries(posMatrix);
+ if (mapMode == MapMode::Tile) tileBorders = collisionIndex.projectTileBoundaries(posMatrix);
+
+ if (tileBorders && (layout.get<style::SymbolAvoidEdges>() ||
+ layout.get<style::SymbolPlacement>() == style::SymbolPlacementType::Line)) {
+ avoidEdges = tileBorders;
}
const bool textAllowOverlap = layout.get<style::TextAllowOverlap>();
@@ -262,14 +264,23 @@ void Placement::placeBucket(
// Line or point label placement
if (variableTextAnchors.empty()) {
- const auto placeFeature = [&] (const CollisionFeature& collisionFeature, style::TextWritingModeType orientation) {
+ const auto placeFeature = [&](const CollisionFeature& collisionFeature,
+ style::TextWritingModeType orientation) {
textBoxes.clear();
- auto placedFeature = collisionIndex.placeFeature(collisionFeature, {},
- posMatrix, textLabelPlaneMatrix, pixelRatio,
- placedSymbol, scale, fontSize,
+ auto placedFeature = collisionIndex.placeFeature(collisionFeature,
+ {},
+ posMatrix,
+ textLabelPlaneMatrix,
+ pixelRatio,
+ placedSymbol,
+ scale,
+ fontSize,
layout.get<style::TextAllowOverlap>(),
pitchWithMap,
- params.showCollisionBoxes, avoidEdges, collisionGroup.second, textBoxes);
+ params.showCollisionBoxes,
+ avoidEdges,
+ collisionGroup.second,
+ textBoxes);
if (placedFeature.first) {
placedOrientations.emplace(symbolInstance.crossTileID, orientation);
}
@@ -329,8 +340,13 @@ void Placement::placeBucket(
std::pair<bool, bool> placedFeature = {false, false};
const size_t anchorsSize = variableTextAnchors.size();
const size_t placementAttempts = textAllowOverlap ? anchorsSize * 2 : anchorsSize;
+ const bool stickToFirstAnchor = tileBorders && !avoidEdges;
+
for (size_t i = 0u; i < placementAttempts; ++i) {
auto anchor = variableTextAnchors[i % anchorsSize];
+ const auto& avoidEdgesForVariableAnchor =
+ (stickToFirstAnchor && anchor != variableTextAnchors.front()) ? tileBorders : avoidEdges;
+
const bool allowOverlap = (i >= anchorsSize);
shift = calculateVariableLayoutOffset(anchor,
width,
@@ -352,7 +368,7 @@ void Placement::placeBucket(
allowOverlap,
pitchWithMap,
params.showCollisionBoxes,
- avoidEdges,
+ avoidEdgesForVariableAnchor,
collisionGroup.second,
textBoxes);
@@ -368,7 +384,7 @@ void Placement::placeBucket(
iconAllowOverlap,
pitchWithMap,
params.showCollisionBoxes,
- avoidEdges,
+ avoidEdgesForVariableAnchor,
collisionGroup.second,
iconBoxes);
iconBoxes.clear();
@@ -454,14 +470,21 @@ void Placement::placeBucket(
const auto& iconBuffer = symbolInstance.hasSdfIcon() ? bucket.sdfIcon : bucket.icon;
const PlacedSymbol& placedSymbol = iconBuffer.placedSymbols.at(*symbolInstance.placedIconIndex);
const float fontSize = evaluateSizeForFeature(partiallyEvaluatedIconSize, placedSymbol);
- const auto& placeIconFeature = [&] (const CollisionFeature& collisionFeature) {
- return collisionIndex.placeFeature(collisionFeature, shift,
- posMatrix, iconLabelPlaneMatrix, pixelRatio,
- placedSymbol, scale, fontSize,
+ const auto& placeIconFeature = [&](const CollisionFeature& collisionFeature) {
+ return collisionIndex.placeFeature(collisionFeature,
+ shift,
+ posMatrix,
+ iconLabelPlaneMatrix,
+ pixelRatio,
+ placedSymbol,
+ scale,
+ fontSize,
layout.get<style::IconAllowOverlap>(),
pitchWithMap,
- params.showCollisionBoxes, avoidEdges,
- collisionGroup.second, iconBoxes);
+ params.showCollisionBoxes,
+ avoidEdges,
+ collisionGroup.second,
+ iconBoxes);
};
std::pair<bool, bool> placedIcon = {false, false};
@@ -890,7 +913,13 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket,
bucket.iconCollisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex);
};
- auto updateTextCollisionBox = [this, &bucket, &symbolInstance, &state, variablePlacement, rotateWithMap, pitchWithMap](const auto& feature, const bool placed) {
+ auto updateTextCollisionBox = [this,
+ &bucket,
+ &symbolInstance,
+ &state,
+ variablePlacement,
+ rotateWithMap,
+ pitchWithMap](const auto& feature, const bool placed) {
Point<float> shift{0.0f, 0.0f};
if (feature.alongLine) {
return shift;
@@ -923,7 +952,7 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket,
bucket.textCollisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex);
return shift;
};
-
+
auto updateCollisionCircles = [&](const auto& feature, const bool placed, bool isText) {
if (!feature.alongLine) {
return;