summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Loer <chris.loer@gmail.com>2017-10-26 13:45:47 -0700
committerChris Loer <chris.loer@gmail.com>2017-10-31 10:25:57 -0700
commit304d8b3d6ed44c4a5162a730532ed92189cbf86e (patch)
treee9305d2aa4b3dea86fe8c22aa6d5ab8944f945dc
parent353b3fb5eaa780460683f62bbd3124d0e69c18c2 (diff)
downloadqtlocation-mapboxgl-304d8b3d6ed44c4a5162a730532ed92189cbf86e.tar.gz
Hook up tile distance calculation.
Collision circles should now agree with labels pretty well even in pitched views.
-rw-r--r--src/mbgl/layout/symbol_layout.cpp26
-rw-r--r--src/mbgl/renderer/buckets/symbol_bucket.hpp5
-rw-r--r--src/mbgl/text/collision_feature.hpp6
-rw-r--r--src/mbgl/text/collision_index.cpp12
4 files changed, 35 insertions, 14 deletions
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp
index 09d01ba876..534c9f5035 100644
--- a/src/mbgl/layout/symbol_layout.cpp
+++ b/src/mbgl/layout/symbol_layout.cpp
@@ -391,6 +391,28 @@ bool SymbolLayout::anchorIsTooClose(const std::u16string& text, const float repe
return false;
}
+// TODO: this is a weird naive port of JS code; think harder about what makes sense in native
+std::vector<float> CalculateTileDistances(const GeometryCoordinates& line, const Anchor& anchor) {
+ std::vector<float> tileDistances(line.size());
+ if (anchor.segment != -1) {
+ auto sumForwardLength = util::dist<float>(anchor.point, line[anchor.segment + 1]);
+ auto sumBackwardLength = util::dist<float>(anchor.point, line[anchor.segment]);
+ for (size_t i = anchor.segment + 1; i < line.size(); i++) {
+ tileDistances[i] = sumForwardLength;
+ if (i < line.size() - 1) {
+ sumForwardLength += util::dist<float>(line[i + 1], line[i]);
+ }
+ }
+ for (auto i = anchor.segment; i >= 0; i--) {
+ tileDistances[i] = sumBackwardLength;
+ if (i > 0) {
+ sumBackwardLength += util::dist<float>(line[i - 1], line[i]);
+ }
+ }
+ }
+ return tileDistances;
+}
+
std::unique_ptr<SymbolBucket> SymbolLayout::place() {
auto bucket = std::make_unique<SymbolBucket>(layout, layerPaintProperties, textSize, iconSize, zoom, sdfIcons, iconsNeedLinear, symbolInstances);
@@ -420,7 +442,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place() {
const bool useVerticalMode = false; // TODO: Add both versions of glyphs to buckets
const Range<float> sizeData = bucket->textSizeBinder->getVertexSizeData(feature);
bucket->text.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max,
- symbolInstance.textOffset, useVerticalMode, symbolInstance.line);
+ symbolInstance.textOffset, useVerticalMode, symbolInstance.line, CalculateTileDistances(symbolInstance.line, symbolInstance.anchor));
symbolInstance.placedTextIndices.push_back(bucket->text.placedSymbols.size() - 1);
for (const auto& symbol : symbolInstance.glyphQuads) {
@@ -434,7 +456,7 @@ std::unique_ptr<SymbolBucket> SymbolLayout::place() {
if (symbolInstance.iconQuad) {
const Range<float> sizeData = bucket->iconSizeBinder->getVertexSizeData(feature);
bucket->icon.placedSymbols.emplace_back(symbolInstance.anchor.point, symbolInstance.anchor.segment, sizeData.min, sizeData.max,
- symbolInstance.iconOffset, false, symbolInstance.line);
+ symbolInstance.iconOffset, false, symbolInstance.line, std::vector<float>());
symbolInstance.placedIconIndices.push_back(bucket->icon.placedSymbols.size() - 1);
addSymbol(
bucket->icon, sizeData, *symbolInstance.iconQuad,
diff --git a/src/mbgl/renderer/buckets/symbol_bucket.hpp b/src/mbgl/renderer/buckets/symbol_bucket.hpp
index f57d2ff7ed..c18f89078d 100644
--- a/src/mbgl/renderer/buckets/symbol_bucket.hpp
+++ b/src/mbgl/renderer/buckets/symbol_bucket.hpp
@@ -19,13 +19,12 @@ namespace mbgl {
class PlacedSymbol {
public:
PlacedSymbol(Point<float> anchorPoint_, uint16_t segment_, float lowerSize_, float upperSize_,
- std::array<float, 2> lineOffset_, bool useVerticalMode_, GeometryCoordinates line_) :
+ std::array<float, 2> lineOffset_, bool useVerticalMode_, const GeometryCoordinates& line_, const std::vector<float>& tileDistances_) :
anchorPoint(anchorPoint_), segment(segment_), lowerSize(lowerSize_), upperSize(upperSize_),
- lineOffset(lineOffset_), useVerticalMode(useVerticalMode_), line(std::move(line_))
+ lineOffset(lineOffset_), useVerticalMode(useVerticalMode_), line(line_), tileDistances(tileDistances_)
{
// TODO WIP hook these up
writingMode = WritingModeType::None;
- tileDistances = std::vector<float>(line.size());
hidden = false;
}
Point<float> anchorPoint;
diff --git a/src/mbgl/text/collision_feature.hpp b/src/mbgl/text/collision_feature.hpp
index 8094f13a54..99a17693ae 100644
--- a/src/mbgl/text/collision_feature.hpp
+++ b/src/mbgl/text/collision_feature.hpp
@@ -11,8 +11,8 @@ namespace mbgl {
class CollisionBox {
public:
- CollisionBox(Point<float> _anchor, Point<float> _offset, float _x1, float _y1, float _x2, float _y2, float _tileUnitDistanceToAnchor = 0, float _radius = 0) :
- anchor(std::move(_anchor)), offset(_offset), x1(_x1), y1(_y1), x2(_x2), y2(_y2), used(true), tileUnitDistanceToAnchor(_tileUnitDistanceToAnchor), radius(_radius) {}
+ CollisionBox(Point<float> _anchor, Point<float> _offset, float _x1, float _y1, float _x2, float _y2, float _signedDistanceFromAnchor = 0, float _radius = 0) :
+ anchor(std::move(_anchor)), offset(_offset), x1(_x1), y1(_y1), x2(_x2), y2(_y2), used(true), signedDistanceFromAnchor(_signedDistanceFromAnchor), radius(_radius) {}
// the box is centered around the anchor point
Point<float> anchor;
@@ -36,7 +36,7 @@ public:
float py;
bool used;
- float tileUnitDistanceToAnchor;
+ float signedDistanceFromAnchor;
float radius;
};
diff --git a/src/mbgl/text/collision_index.cpp b/src/mbgl/text/collision_index.cpp
index 3eaf28bb8f..2b970ee278 100644
--- a/src/mbgl/text/collision_index.cpp
+++ b/src/mbgl/text/collision_index.cpp
@@ -130,10 +130,10 @@ bool CollisionIndex::placeLineFeature(CollisionFeature& feature,
bool atLeastOneCirclePlaced = false;
for (size_t i = 0; i < feature.boxes.size(); i++) {
CollisionBox& circle = feature.boxes[i];
- const float boxDistanceToAnchor = circle.tileUnitDistanceToAnchor;
+ const float boxSignedDistanceFromAnchor = circle.signedDistanceFromAnchor;
if (!firstAndLastGlyph ||
- (boxDistanceToAnchor < -firstTileDistance) ||
- (boxDistanceToAnchor > lastTileDistance)) {
+ (boxSignedDistanceFromAnchor < -firstTileDistance) ||
+ (boxSignedDistanceFromAnchor > lastTileDistance)) {
// The label either doesn't fit on its line or we
// don't need to use this circle because the label
// doesn't extend this far. Either way, mark the circle unused.
@@ -160,9 +160,9 @@ bool CollisionIndex::placeLineFeature(CollisionFeature& feature,
const bool atLeastOneMoreCircle = (i + 1) < feature.boxes.size();
if (atLeastOneMoreCircle) {
const CollisionBox& nextCircle = feature.boxes[i + 1];
- const float nextBoxDistanceToAnchor = nextCircle.tileUnitDistanceToAnchor;
- if ((nextBoxDistanceToAnchor > -firstTileDistance) &&
- (nextBoxDistanceToAnchor < lastTileDistance)) {
+ const float nextBoxDistanceFromAnchor = nextCircle.signedDistanceFromAnchor;
+ if ((nextBoxDistanceFromAnchor > -firstTileDistance) &&
+ (nextBoxDistanceFromAnchor < lastTileDistance)) {
// Hide significantly overlapping circles, unless this is the last one we can
// use, in which case we want to keep it in place even if it's tightly packed
// with the one before it.