allow crosstile labels and add symbol-avoid-edges
This commit is contained in:
committed by
Konstantin Käfer
parent
69f71e9431
commit
6c45972502
@@ -2,30 +2,23 @@
|
||||
#include <mbgl/text/rotation_range.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#ifndef __clang__
|
||||
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
#include <boost/geometry.hpp>
|
||||
#include <boost/geometry/geometries/point.hpp>
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
#include <boost/geometry/index/rtree.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
namespace mbgl {
|
||||
namespace bg = boost::geometry;
|
||||
namespace bgm = bg::model;
|
||||
namespace bgi = bg::index;
|
||||
typedef bgm::point<float, 2, bg::cs::cartesian> Point;
|
||||
typedef bgm::box<Point> Box;
|
||||
typedef std::pair<Box, PlacementBox> PlacementValue;
|
||||
typedef bgi::rtree<PlacementValue, bgi::rstar<16>> Tree;
|
||||
}
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
Box getBox(const CollisionAnchor &anchor, const CollisionRect &bbox, float minScale,
|
||||
float maxScale) {
|
||||
return Box{
|
||||
Point{
|
||||
anchor.x + util::min(bbox.tl.x / minScale, bbox.tl.x / maxScale),
|
||||
anchor.y + util::min(bbox.tl.y / minScale, bbox.tl.y / maxScale),
|
||||
},
|
||||
Point{
|
||||
anchor.x + util::max(bbox.br.x / minScale, bbox.br.x / maxScale),
|
||||
anchor.y + util::max(bbox.br.y / minScale, bbox.br.y / maxScale),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
Collision::~Collision() {
|
||||
delete ((Tree *)cTree);
|
||||
delete ((Tree *)hTree);
|
||||
@@ -52,32 +45,51 @@ Collision::Collision(float zoom, float tileExtent, float tileSize, float placeme
|
||||
const float m = 4096;
|
||||
const float edge = m * tilePixelRatio * 2;
|
||||
|
||||
// Hack to prevent cross-tile labels
|
||||
insert(
|
||||
/* glyphs */ {
|
||||
GlyphBox{/* box */ CollisionRect{CollisionPoint{-edge, -edge}, CollisionPoint{0, edge}},
|
||||
/* minScale */ 0,
|
||||
/* padding */ 2},
|
||||
GlyphBox{/* box */ CollisionRect{CollisionPoint{-edge, -edge}, CollisionPoint{edge, 0}},
|
||||
/* minScale */ 0,
|
||||
/* padding */ 2}},
|
||||
/* anchor */ CollisionAnchor(0, 0),
|
||||
/* placementScale */ 1,
|
||||
/* placementRange */ {{M_PI * 2, 0}},
|
||||
/* horizontal */ false);
|
||||
|
||||
insert(
|
||||
/* glyphs */ {
|
||||
GlyphBox{/* box*/ CollisionRect{CollisionPoint{-edge, 0}, CollisionPoint{edge, edge}},
|
||||
/* minScale */ 0,
|
||||
/* padding */ 2},
|
||||
GlyphBox{/* box */ CollisionRect{CollisionPoint{0, -edge}, CollisionPoint{edge, edge}},
|
||||
/* minScale */ 0,
|
||||
/* padding */ 2}},
|
||||
/* anchor */ CollisionAnchor(m, m),
|
||||
/* placementScale */ 1,
|
||||
/* placementRange */ {{M_PI * 2, 0}},
|
||||
/* horizontal */ false);
|
||||
PlacementBox left;
|
||||
left.anchor = CollisionAnchor{ 0.0f, 0.0f };
|
||||
left.box = CollisionRect{CollisionPoint{-edge, -edge}, CollisionPoint{0, edge}};
|
||||
left.placementRange = {{ 2.0f * M_PI, 0.0f }};
|
||||
left.placementScale = 0.5f;
|
||||
left.maxScale = std::numeric_limits<float>::infinity();
|
||||
left.padding = 0.0f;
|
||||
leftEdge = PlacementValue{
|
||||
getBox(left.anchor, left.box, left.placementScale, left.maxScale),
|
||||
left};
|
||||
|
||||
PlacementBox top;
|
||||
top.anchor = CollisionAnchor{ 0.0f, 0.0f };
|
||||
top.box = CollisionRect{CollisionPoint{-edge, -edge}, CollisionPoint{edge, 0}};
|
||||
top.placementRange = {{ 2.0f * M_PI, 0.0f }};
|
||||
top.placementScale = 0.5f;
|
||||
top.maxScale = std::numeric_limits<float>::infinity();
|
||||
top.padding = 0.0f;
|
||||
topEdge = PlacementValue{
|
||||
getBox(top.anchor, top.box, top.placementScale, top.maxScale),
|
||||
top};
|
||||
|
||||
PlacementBox bottom;
|
||||
bottom.anchor = CollisionAnchor{ m, m };
|
||||
bottom.box = CollisionRect{CollisionPoint{-edge, 0}, CollisionPoint{edge, edge}};
|
||||
bottom.placementRange = {{ 2.0f * M_PI, 0.0f }};
|
||||
bottom.placementScale = 0.5f;
|
||||
bottom.maxScale = std::numeric_limits<float>::infinity();
|
||||
bottom.padding = 0.0f;
|
||||
bottomEdge = PlacementValue{
|
||||
getBox(bottom.anchor, bottom.box, bottom.placementScale, bottom.maxScale),
|
||||
bottom};
|
||||
|
||||
PlacementBox right;
|
||||
right.anchor = CollisionAnchor{ m, m };
|
||||
right.box = CollisionRect{CollisionPoint{0, -edge}, CollisionPoint{edge, edge}};
|
||||
right.placementRange = {{ 2.0f * M_PI, 0.0f }};
|
||||
right.placementScale = 0.5f;
|
||||
right.maxScale = std::numeric_limits<float>::infinity();
|
||||
right.padding = 0.0f;
|
||||
rightEdge = PlacementValue{
|
||||
getBox(right.anchor, right.box, right.placementScale, right.maxScale),
|
||||
right};
|
||||
|
||||
}
|
||||
|
||||
GlyphBox getMergedGlyphs(const GlyphBoxes &boxes, const CollisionAnchor &anchor) {
|
||||
@@ -99,21 +111,7 @@ GlyphBox getMergedGlyphs(const GlyphBoxes &boxes, const CollisionAnchor &anchor)
|
||||
return mergedGlyphs;
|
||||
}
|
||||
|
||||
Box getBox(const CollisionAnchor &anchor, const CollisionRect &bbox, float minScale,
|
||||
float maxScale) {
|
||||
return Box{
|
||||
Point{
|
||||
anchor.x + util::min(bbox.tl.x / minScale, bbox.tl.x / maxScale),
|
||||
anchor.y + util::min(bbox.tl.y / minScale, bbox.tl.y / maxScale),
|
||||
},
|
||||
Point{
|
||||
anchor.x + util::max(bbox.br.x / minScale, bbox.br.x / maxScale),
|
||||
anchor.y + util::max(bbox.br.y / minScale, bbox.br.y / maxScale),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
float Collision::getPlacementScale(const GlyphBoxes &glyphs, float minPlacementScale) {
|
||||
float Collision::getPlacementScale(const GlyphBoxes &glyphs, float minPlacementScale, bool avoidEdges) {
|
||||
|
||||
for (const GlyphBox &glyph : glyphs) {
|
||||
const CollisionRect &box = glyph.box;
|
||||
@@ -121,6 +119,7 @@ float Collision::getPlacementScale(const GlyphBoxes &glyphs, float minPlacementS
|
||||
const CollisionAnchor &anchor = glyph.anchor;
|
||||
const float pad = glyph.padding;
|
||||
|
||||
|
||||
if (anchor.x < 0 || anchor.x > 4096 || anchor.y < 0 || anchor.y > 4096) {
|
||||
return 0;
|
||||
}
|
||||
@@ -139,6 +138,13 @@ float Collision::getPlacementScale(const GlyphBoxes &glyphs, float minPlacementS
|
||||
((Tree *)hTree)->query(bgi::intersects(searchBox), std::back_inserter(blocking));
|
||||
((Tree *)cTree)->query(bgi::intersects(searchBox), std::back_inserter(blocking));
|
||||
|
||||
if (avoidEdges) {
|
||||
if (searchBox.min_corner().get<0>() < 0) blocking.emplace_back(leftEdge);
|
||||
if (searchBox.min_corner().get<1>() < 0) blocking.emplace_back(topEdge);
|
||||
if (searchBox.max_corner().get<0>() >= 4096) blocking.emplace_back(rightEdge);
|
||||
if (searchBox.max_corner().get<1>() >= 4096) blocking.emplace_back(bottomEdge);
|
||||
}
|
||||
|
||||
if (blocking.size()) {
|
||||
const CollisionAnchor &na = anchor; // new anchor
|
||||
const CollisionRect &nb = box; // new box
|
||||
|
||||
Reference in New Issue
Block a user