port SymbolBucket::placeFeatures
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
#include <mbgl/util/token.hpp>
|
||||
#include <mbgl/geometry/glyph_atlas.hpp>
|
||||
#include <mbgl/text/glyph_store.hpp>
|
||||
#include <mbgl/text/collision.hpp>
|
||||
#include <mbgl/text/collision_tile.hpp>
|
||||
#include <mbgl/text/glyph.hpp>
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
@@ -43,7 +43,7 @@ TileParser::TileParser(const GeometryTile& geometryTile_,
|
||||
glyphStore(glyphStore_),
|
||||
spriteAtlas(spriteAtlas_),
|
||||
sprite(sprite_),
|
||||
collision(util::make_unique<Collision>(tile.id.z, 4096, tile.source.tile_size, tile.depth)) {
|
||||
collision(util::make_unique<CollisionTile>(tile.id.z, 4096, tile.source.tile_size)) {
|
||||
assert(style);
|
||||
assert(sprite);
|
||||
assert(collision);
|
||||
|
||||
@@ -30,7 +30,7 @@ class StyleLayoutLine;
|
||||
class StyleLayoutSymbol;
|
||||
class StyleLayerGroup;
|
||||
class VectorTileData;
|
||||
class Collision;
|
||||
class CollisionTile;
|
||||
|
||||
class TileParser : private util::noncopyable {
|
||||
public:
|
||||
@@ -69,7 +69,7 @@ private:
|
||||
SpriteAtlas& spriteAtlas;
|
||||
util::ptr<Sprite> sprite;
|
||||
|
||||
std::unique_ptr<Collision> collision;
|
||||
std::unique_ptr<CollisionTile> collision;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <mbgl/text/glyph_store.hpp>
|
||||
#include <mbgl/text/quads.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/text/collision.hpp>
|
||||
#include <mbgl/text/collision_tile.hpp>
|
||||
#include <mbgl/map/sprite.hpp>
|
||||
|
||||
#include <mbgl/util/utf.hpp>
|
||||
@@ -46,7 +46,7 @@ SymbolInstance::SymbolInstance(Anchor &anchor, const std::vector<Coordinate> &li
|
||||
iconCollisionFeature(line, anchor, shapedIcon, iconBoxScale, iconPadding, iconAlongLine) {};
|
||||
|
||||
|
||||
SymbolBucket::SymbolBucket(std::unique_ptr<const StyleLayoutSymbol> styleLayout_, Collision &collision_)
|
||||
SymbolBucket::SymbolBucket(std::unique_ptr<const StyleLayoutSymbol> styleLayout_, CollisionTile &collision_)
|
||||
: styleLayout(std::move(styleLayout_)), collision(collision_) {
|
||||
assert(styleLayout);
|
||||
}
|
||||
@@ -263,10 +263,10 @@ void SymbolBucket::addFeature(const std::vector<std::vector<Coordinate>> &lines,
|
||||
const float iconPadding = layout.icon.padding * collision.tilePixelRatio;
|
||||
//const float textMaxAngle = layout.text.max_angle * M_PI / 180;
|
||||
const bool textAlongLine =
|
||||
layout.text.rotation_alignment != RotationAlignmentType::Viewport &&
|
||||
layout.text.rotation_alignment == RotationAlignmentType::Map &&
|
||||
layout.placement == PlacementType::Line;
|
||||
const bool iconAlongLine =
|
||||
layout.icon.rotation_alignment != RotationAlignmentType::Viewport &&
|
||||
layout.icon.rotation_alignment == RotationAlignmentType::Map &&
|
||||
layout.placement == PlacementType::Line;
|
||||
|
||||
// TODO clip lines here
|
||||
@@ -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, collision.maxPlacementScale, collision.tilePixelRatio, 0.0f) :
|
||||
resample(line, layout.min_distance, minScale, 2.0f, collision.tilePixelRatio, 0.0f) :
|
||||
Anchors({ Anchor(float(line[0].x), float(line[0].y), 0, minScale) });
|
||||
|
||||
|
||||
@@ -297,33 +297,67 @@ void SymbolBucket::addFeature(const std::vector<std::vector<Coordinate>> &lines,
|
||||
|
||||
void SymbolBucket::placeFeatures() {
|
||||
|
||||
//auto &layout = *styleLayout;
|
||||
// Calculate which labels can be shown and when they can be shown and
|
||||
// create the bufers used for rendering.
|
||||
|
||||
auto &layout = *styleLayout;
|
||||
|
||||
/*
|
||||
const bool textAlongLine =
|
||||
layout.text.rotation_alignment == RotationAlignmentType::Map &&
|
||||
layout.placement == PlacementType::Line;
|
||||
const bool iconAlongLine =
|
||||
layout.icon.rotation_alignment == RotationAlignmentType::Map &&
|
||||
layout.placement == PlacementType::Line;
|
||||
*/
|
||||
|
||||
for (SymbolInstance &symbolInstance : symbolInstances) {
|
||||
|
||||
const bool hasText = symbolInstance.hasText;
|
||||
const bool hasIcon = symbolInstance.hasIcon;
|
||||
|
||||
float glyphScale = 0.5f;
|
||||
float iconScale = 0.5f;
|
||||
const bool iconWithoutText = layout.text.optional || !hasText;
|
||||
const bool textWithoutIcon = layout.icon.optional || !hasIcon;
|
||||
|
||||
/*
|
||||
if (!iconWithoutText && !textWithoutIcon) {
|
||||
iconScale = glyphScale = util::max(iconScale, glyphScale);
|
||||
} else if (!textWithoutIcon && glyphScale) {
|
||||
glyphScale = util::max(iconScale, glyphScale);
|
||||
} else if (!iconWithoutText && iconScale) {
|
||||
iconScale = util::max(iconScale, glyphScale);
|
||||
}
|
||||
*/
|
||||
|
||||
// Insert final placement into collision tree and add glyphs/icons to buffers
|
||||
if (hasText && std::isfinite(glyphScale)) {
|
||||
addSymbols<TextBuffer, TextElementGroup>(text, symbolInstance.glyphQuads, glyphScale);
|
||||
// Calculate the scales at which the text and icon can be placed without collision.
|
||||
|
||||
float glyphScale = hasText && !layout.text.allow_overlap ?
|
||||
collision.placeFeature(symbolInstance.textCollisionFeature) : collision.minScale;
|
||||
float iconScale = hasIcon && !layout.icon.allow_overlap ?
|
||||
collision.placeFeature(symbolInstance.iconCollisionFeature) : collision.minScale;
|
||||
|
||||
//if (glyphScale) fprintf(stderr, "glyphScale %f\n", glyphScale);
|
||||
|
||||
// Combine the scales for icons and text.
|
||||
|
||||
if (!iconWithoutText && !textWithoutIcon) {
|
||||
iconScale = glyphScale = util::max(iconScale, glyphScale);
|
||||
} else if (!textWithoutIcon && glyphScale) {
|
||||
glyphScale = util::max(iconScale, glyphScale);
|
||||
} else if (!iconWithoutText && iconScale) {
|
||||
iconScale = util::max(iconScale, glyphScale);
|
||||
}
|
||||
|
||||
if (hasIcon && std::isfinite(iconScale)) {
|
||||
addSymbols<IconBuffer, IconElementGroup>(icon, symbolInstance.iconQuads, iconScale);
|
||||
|
||||
// Insert final placement into collision tree and add glyphs/icons to buffers
|
||||
|
||||
if (hasText) {
|
||||
if (!layout.text.ignore_placement) {
|
||||
collision.insertFeature(symbolInstance.textCollisionFeature, glyphScale);
|
||||
}
|
||||
if (glyphScale < collision.maxScale) {
|
||||
addSymbols<TextBuffer, TextElementGroup>(text, symbolInstance.glyphQuads, glyphScale);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasIcon) {
|
||||
if (!layout.icon.ignore_placement) {
|
||||
collision.insertFeature(symbolInstance.iconCollisionFeature, iconScale);
|
||||
}
|
||||
if (iconScale < collision.maxScale) {
|
||||
addSymbols<IconBuffer, IconElementGroup>(icon, symbolInstance.iconQuads, iconScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class SDFShader;
|
||||
class IconShader;
|
||||
class CollisionBoxShader;
|
||||
class DotShader;
|
||||
class Collision;
|
||||
class CollisionTile;
|
||||
class SpriteAtlas;
|
||||
class Sprite;
|
||||
class GlyphAtlas;
|
||||
@@ -55,8 +55,8 @@ class SymbolInstance {
|
||||
const bool hasIcon;
|
||||
const PlacedGlyphs glyphQuads;
|
||||
const PlacedGlyphs iconQuads;
|
||||
const CollisionFeature textCollisionFeature;
|
||||
const CollisionFeature iconCollisionFeature;
|
||||
CollisionFeature textCollisionFeature;
|
||||
CollisionFeature iconCollisionFeature;
|
||||
};
|
||||
|
||||
class SymbolBucket : public Bucket {
|
||||
@@ -65,7 +65,7 @@ class SymbolBucket : public Bucket {
|
||||
typedef ElementGroup<1> CollisionBoxElementGroup;
|
||||
|
||||
public:
|
||||
SymbolBucket(std::unique_ptr<const StyleLayoutSymbol> styleLayout, Collision &collision);
|
||||
SymbolBucket(std::unique_ptr<const StyleLayoutSymbol> styleLayout, CollisionTile &collision);
|
||||
~SymbolBucket() override;
|
||||
|
||||
void render(Painter &painter, const StyleLayer &layer_desc, const Tile::ID &id,
|
||||
@@ -109,7 +109,7 @@ public:
|
||||
bool sdfIcons = false;
|
||||
|
||||
private:
|
||||
Collision &collision;
|
||||
CollisionTile &collision;
|
||||
std::vector<SymbolInstance> symbolInstances;
|
||||
|
||||
struct TextBuffer {
|
||||
|
||||
@@ -6,6 +6,8 @@ CollisionFeature::CollisionFeature(const std::vector<Coordinate> &line, const An
|
||||
const float top, const float bottom, const float left, const float right,
|
||||
const float boxScale, const float padding, const bool alongLine) {
|
||||
|
||||
if (top == 0 && bottom == 0 && left == 0 && right == 0) return;
|
||||
|
||||
const float y1 = top * boxScale - padding;
|
||||
const float y2 = bottom * boxScale + padding;
|
||||
const float x1 = left * boxScale - padding;
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
const float minScale = 0.5f;
|
||||
const float maxScale = 2.0f;
|
||||
|
||||
void CollisionTile::reset(const float _angle, const float pitch) {
|
||||
tree.clear();
|
||||
angle = _angle;
|
||||
@@ -23,7 +20,7 @@ void CollisionTile::reset(const float _angle, const float pitch) {
|
||||
yStretch = std::pow(_yStretch, 1.3);
|
||||
}
|
||||
|
||||
float CollisionTile::placeFeature(CollisionFeature &feature) {
|
||||
float CollisionTile::placeFeature(const CollisionFeature &feature) {
|
||||
|
||||
float minPlacementScale = minScale;
|
||||
|
||||
@@ -47,7 +44,7 @@ float CollisionTile::placeFeature(CollisionFeature &feature) {
|
||||
if (std::isnan(s1) || std::isnan(s2)) s1 = s2 = 1;
|
||||
if (std::isnan(s3) || std::isnan(s4)) s3 = s4 = 1;
|
||||
|
||||
float collisionFreeScale = std::fmin(std::fmax(s1, s3), std::fmax(s3, s4));
|
||||
float collisionFreeScale = std::fmin(std::fmax(s1, s2), std::fmax(s3, s4));
|
||||
|
||||
if (collisionFreeScale > blocking.maxScale) {
|
||||
// After a box's maxScale the label has shrunk enough that the box is no longer needed to cover it,
|
||||
|
||||
@@ -35,16 +35,19 @@ class CollisionTile {
|
||||
|
||||
public:
|
||||
inline explicit CollisionTile(float _zoom, float tileExtent, float tileSize) :
|
||||
zoom(_zoom), tilePixelRatio(tileExtent / tileSize) {}
|
||||
zoom(_zoom), tilePixelRatio(tileExtent / tileSize) { reset(0, 0); }
|
||||
|
||||
void reset(const float angle, const float pitch);
|
||||
float placeFeature(CollisionFeature &feature);
|
||||
float placeFeature(const CollisionFeature &feature);
|
||||
void insertFeature(CollisionFeature &feature, const float minPlacementScale);
|
||||
|
||||
const float zoom;
|
||||
const float tilePixelRatio;
|
||||
float angle = 0;
|
||||
|
||||
const float minScale = 0.5f;
|
||||
const float maxScale = 2.0f;
|
||||
|
||||
private:
|
||||
|
||||
Box getTreeBox(const Anchor &anchor, const CollisionBox &box);
|
||||
|
||||
Reference in New Issue
Block a user