diff options
author | Chris Loer <chris.loer@gmail.com> | 2017-10-26 13:45:47 -0700 |
---|---|---|
committer | Chris Loer <chris.loer@gmail.com> | 2017-10-31 10:25:57 -0700 |
commit | 304d8b3d6ed44c4a5162a730532ed92189cbf86e (patch) | |
tree | e9305d2aa4b3dea86fe8c22aa6d5ab8944f945dc | |
parent | 353b3fb5eaa780460683f62bbd3124d0e69c18c2 (diff) | |
download | qtlocation-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.cpp | 26 | ||||
-rw-r--r-- | src/mbgl/renderer/buckets/symbol_bucket.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/text/collision_feature.hpp | 6 | ||||
-rw-r--r-- | src/mbgl/text/collision_index.cpp | 12 |
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. |