port getAnchors from -js
This commit is contained in:
@@ -1,63 +0,0 @@
|
||||
#include <mbgl/geometry/resample.hpp>
|
||||
|
||||
#include <mbgl/util/interpolate.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
const float minScale = 0.5f;
|
||||
const std::array<std::vector<float>, 4> minScaleArrays = {{
|
||||
/*1:*/ { minScale },
|
||||
/*2:*/ { minScale, 2 },
|
||||
/*4:*/ { minScale, 4, 2, 4 },
|
||||
/*8:*/ { minScale, 8, 4, 8, 2, 8, 4, 8 }
|
||||
}};
|
||||
|
||||
|
||||
Anchors resample(const std::vector<Coordinate> &vertices, float spacing,
|
||||
const float /*minScale*/, float maxScale, const float tilePixelRatio,
|
||||
float offset) {
|
||||
|
||||
maxScale = std::round(std::fmax(std::fmin(8.0f, maxScale / 2.0f), 1.0f));
|
||||
spacing *= tilePixelRatio / maxScale;
|
||||
offset *= tilePixelRatio;
|
||||
const size_t index = util::clamp<size_t>(std::floor(std::log(maxScale) / std::log(2)), 0, minScaleArrays.size() - 1);
|
||||
const std::vector<float> &minScales = minScaleArrays[index];
|
||||
const size_t len = minScales.size();
|
||||
|
||||
float distance = 0.0f;
|
||||
float markedDistance = offset != 0.0f ? offset - spacing : offset;
|
||||
int added = 0;
|
||||
|
||||
Anchors points;
|
||||
|
||||
auto end = vertices.end() - 1;
|
||||
int i = 0;
|
||||
for (auto it = vertices.begin(); it != end; it++, i++) {
|
||||
const Coordinate &a = *(it), b = *(it + 1);
|
||||
|
||||
float segmentDist = util::dist<float>(a, b);
|
||||
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),
|
||||
s = minScales[added % len];
|
||||
|
||||
if (x >= 0 && x < 4096 && y >= 0 && y < 4096) {
|
||||
points.emplace_back(x, y, angle, s, i);
|
||||
}
|
||||
|
||||
added++;
|
||||
}
|
||||
|
||||
distance += segmentDist;
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#ifndef MBGL_GEOMETRY_INTERPOLATE
|
||||
#define MBGL_GEOMETRY_INTERPOLATE
|
||||
|
||||
#include <mbgl/geometry/anchor.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
Anchors resample(const std::vector<Coordinate> &vertices, float spacing,
|
||||
float minScale, float maxScale, float tilePixelRatio, float offset);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <mbgl/geometry/glyph_atlas.hpp>
|
||||
#include <mbgl/geometry/sprite_atlas.hpp>
|
||||
#include <mbgl/geometry/anchor.hpp>
|
||||
#include <mbgl/geometry/resample.hpp>
|
||||
#include <mbgl/text/get_anchors.hpp>
|
||||
#include <mbgl/renderer/painter.hpp>
|
||||
#include <mbgl/text/glyph_store.hpp>
|
||||
#include <mbgl/text/quads.hpp>
|
||||
@@ -257,11 +257,11 @@ void SymbolBucket::addFeature(const std::vector<std::vector<Coordinate>> &lines,
|
||||
const float fontScale = layout.text.max_size / glyphSize;
|
||||
const float textBoxScale = collision.tilePixelRatio * fontScale;
|
||||
const float iconBoxScale = collision.tilePixelRatio * layout.icon.max_size;
|
||||
//const float symbolSpacing = collision.tilePixelRatio * layout.min_distance;
|
||||
const float symbolSpacing = collision.tilePixelRatio * layout.min_distance;
|
||||
const bool avoidEdges = layout.avoid_edges && layout.placement != PlacementType::Line;
|
||||
const float textPadding = layout.text.padding * collision.tilePixelRatio;
|
||||
const float iconPadding = layout.icon.padding * collision.tilePixelRatio;
|
||||
//const float textMaxAngle = layout.text.max_angle * M_PI / 180;
|
||||
const float textMaxAngle = layout.text.max_angle * M_PI / 180;
|
||||
const bool textAlongLine =
|
||||
layout.text.rotation_alignment == RotationAlignmentType::Map &&
|
||||
layout.placement == PlacementType::Line;
|
||||
@@ -276,7 +276,7 @@ void SymbolBucket::addFeature(const std::vector<std::vector<Coordinate>> &lines,
|
||||
|
||||
// Calculate the anchor points around which you want to place labels
|
||||
Anchors anchors = layout.placement == PlacementType::Line ?
|
||||
resample(line, layout.min_distance, minScale, 2.0f, collision.tilePixelRatio, 0.0f) :
|
||||
getAnchors(line, symbolSpacing, textMaxAngle, shapedText.left, shapedText.right, glyphSize, textBoxScale, 1.0f) :
|
||||
Anchors({ Anchor(float(line[0].x), float(line[0].y), 0, minScale) });
|
||||
|
||||
|
||||
|
||||
79
src/mbgl/text/get_anchors.cpp
Normal file
79
src/mbgl/text/get_anchors.cpp
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
14
src/mbgl/text/get_anchors.hpp
Normal file
14
src/mbgl/text/get_anchors.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef MBGL_TEXT_GETANCHORS
|
||||
#define MBGL_TEXT_GETANCHORS
|
||||
|
||||
#include <mbgl/geometry/anchor.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -58,7 +58,7 @@ class Shaping {
|
||||
public:
|
||||
inline explicit Shaping() : top(0), bottom(0), left(0), right(0) {}
|
||||
inline explicit Shaping(float x, float y)
|
||||
: top(-y), bottom(y), left(-x), right(x) {}
|
||||
: top(y), bottom(y), left(x), right(x) {}
|
||||
std::vector<PositionedGlyph> positionedGlyphs;
|
||||
int32_t top;
|
||||
int32_t bottom;
|
||||
|
||||
@@ -40,7 +40,7 @@ const Shaping FontStack::getShaping(const std::u32string &string, const float ma
|
||||
const float spacing, const vec2<float> &translate) const {
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
|
||||
Shaping shaping(translate.x, translate.y);
|
||||
Shaping shaping(translate.x * 24, translate.y * 24);
|
||||
|
||||
// the y offset *should* be part of the font metadata
|
||||
const int32_t yOffset = -17;
|
||||
|
||||
Reference in New Issue
Block a user