summaryrefslogtreecommitdiff
path: root/src/mbgl/text/get_anchors.cpp
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2015-04-01 20:31:25 -0700
committerAnsis Brammanis <brammanis@gmail.com>2015-04-01 20:31:25 -0700
commitc49e1ac733f70d869eae91c5f825828c14168a31 (patch)
tree9895718fb84715da19dff07083db47b0f6a101ac /src/mbgl/text/get_anchors.cpp
parent1d50485e5b824d2608aeba2568f71ff5e4ec217d (diff)
downloadqtlocation-mapboxgl-c49e1ac733f70d869eae91c5f825828c14168a31.tar.gz
port getAnchors from -js
Diffstat (limited to 'src/mbgl/text/get_anchors.cpp')
-rw-r--r--src/mbgl/text/get_anchors.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/mbgl/text/get_anchors.cpp b/src/mbgl/text/get_anchors.cpp
new file mode 100644
index 0000000000..fa5f81ba46
--- /dev/null
+++ b/src/mbgl/text/get_anchors.cpp
@@ -0,0 +1,79 @@
+#include <mbgl/text/get_anchors.hpp>
+
+#include <mbgl/util/interpolate.hpp>
+
+#include <cmath>
+
+namespace mbgl {
+
+Anchors resample(const std::vector<Coordinate> &line, const float offset, const float spacing,
+ const float angleWindowSize, const float maxAngle, const float labelLength, const bool placeAtMiddle) {
+
+ float distance = 0;
+ float markedDistance = offset != 0.0f ? offset - spacing : 0;
+
+ Anchors anchors;
+
+ auto end = line.end() - 1;
+ int i = 0;
+ for (auto it = line.begin(); it != end; it++, i++) {
+ const Coordinate &a = *(it);
+ const Coordinate &b = *(it + 1);
+
+ const float segmentDist = util::dist<float>(a, b);
+ const float angle = util::angle_to(b, a);
+
+ while (markedDistance + spacing < distance + segmentDist) {
+ markedDistance += spacing;
+
+ float t = (markedDistance - distance) / segmentDist,
+ x = util::interpolate(a.x, b.x, t),
+ y = util::interpolate(a.y, b.y, t);
+
+ if (x >= 0 && x < 4096 && y >= 0 && y < 4096) {
+ Anchor anchor(x, y, angle, 0.5f, i);
+
+ if (!angleWindowSize || true) {
+ anchors.push_back(anchor);
+ }
+ //if (!angleWindowSize || checkMaxAngle(line, anchor, labelLength, angleWindowSize, maxAngle)) {
+ }
+ }
+
+ distance += segmentDist;
+ }
+
+ if (!placeAtMiddle && !anchors.size()) {
+ // The first attempt at finding anchors at which labels can be placed failed.
+ // Try again, but this time just try placing one anchor at the middle of the line.
+ // This has the most effect for short lines in overscaled tiles, since the
+ // initial offset used in overscaled tiles is calculated to align labels with positions in
+ // parent tiles instead of placing the label as close to the beginning as possible.
+ anchors = std::move(resample(line, distance / 2, spacing, angleWindowSize, maxAngle, labelLength, true));
+ }
+
+ return anchors;
+}
+
+Anchors getAnchors(const std::vector<Coordinate> &line, float spacing,
+ const bool maxAngle, const float left, const float right,
+ const float glyphSize, const float boxScale, const float overscaling) {
+
+ // Resample a line to get anchor points for labels and check that each
+ // potential label passes text-max-angle check and has enough froom to fit
+ // on the line.
+
+ const float angleWindowSize = left - right != 0.0f ?
+ 3 / 5 * glyphSize * boxScale :
+ 0;
+
+ // Offset the first anchor by half the label length (or half the spacing distance for icons).
+ // Add a bit of extra offset to avoid collisions at T intersections.
+ const float labelLength = right - left ? right - left : spacing;
+ const float extraOffset = glyphSize * 2;
+ const float offset = std::fmod((labelLength / 2 + extraOffset) * boxScale * overscaling, spacing);
+
+ return resample(line, offset, spacing, angleWindowSize, maxAngle, labelLength * boxScale, false);
+}
+
+}