summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2015-04-01 15:14:49 -0700
committerAnsis Brammanis <brammanis@gmail.com>2015-04-01 16:11:48 -0700
commite1059e71257aea559776f979f801ba666fc47a44 (patch)
tree4a4b8b4bd31ddbf8e380aa955207d582588de9b9 /src
parentfd526ae68ec193574fb69ca22df59134d3ec13ca (diff)
downloadqtlocation-mapboxgl-e1059e71257aea559776f979f801ba666fc47a44.tar.gz
port SymbolBucket::placeFeatures
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/map/tile_parser.cpp4
-rw-r--r--src/mbgl/map/tile_parser.hpp4
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp78
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp10
-rw-r--r--src/mbgl/text/collision_feature.cpp2
-rw-r--r--src/mbgl/text/collision_tile.cpp7
-rw-r--r--src/mbgl/text/collision_tile.hpp7
7 files changed, 74 insertions, 38 deletions
diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp
index fa7f4c093f..45f6c0e6a9 100644
--- a/src/mbgl/map/tile_parser.cpp
+++ b/src/mbgl/map/tile_parser.cpp
@@ -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);
diff --git a/src/mbgl/map/tile_parser.hpp b/src/mbgl/map/tile_parser.hpp
index 0ad42fdc91..1abd0ec1c9 100644
--- a/src/mbgl/map/tile_parser.hpp
+++ b/src/mbgl/map/tile_parser.hpp
@@ -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;
};
}
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index 2b65d1fefb..15cb5b1b74 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -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;
-
- /*
- 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);
- }
- */
+ const bool iconWithoutText = layout.text.optional || !hasText;
+ const bool textWithoutIcon = layout.icon.optional || !hasIcon;
+
+
+ // 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);
+ }
+
// Insert final placement into collision tree and add glyphs/icons to buffers
- if (hasText && std::isfinite(glyphScale)) {
- addSymbols<TextBuffer, TextElementGroup>(text, symbolInstance.glyphQuads, glyphScale);
+
+ 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 && std::isfinite(iconScale)) {
- addSymbols<IconBuffer, IconElementGroup>(icon, symbolInstance.iconQuads, iconScale);
+ if (hasIcon) {
+ if (!layout.icon.ignore_placement) {
+ collision.insertFeature(symbolInstance.iconCollisionFeature, iconScale);
+ }
+ if (iconScale < collision.maxScale) {
+ addSymbols<IconBuffer, IconElementGroup>(icon, symbolInstance.iconQuads, iconScale);
+ }
}
}
diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp
index 0b506021a7..1b730ced88 100644
--- a/src/mbgl/renderer/symbol_bucket.hpp
+++ b/src/mbgl/renderer/symbol_bucket.hpp
@@ -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 {
diff --git a/src/mbgl/text/collision_feature.cpp b/src/mbgl/text/collision_feature.cpp
index f2205da09b..610fefa205 100644
--- a/src/mbgl/text/collision_feature.cpp
+++ b/src/mbgl/text/collision_feature.cpp
@@ -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;
diff --git a/src/mbgl/text/collision_tile.cpp b/src/mbgl/text/collision_tile.cpp
index a6ae4682ad..88a3c6bdd1 100644
--- a/src/mbgl/text/collision_tile.cpp
+++ b/src/mbgl/text/collision_tile.cpp
@@ -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,
diff --git a/src/mbgl/text/collision_tile.hpp b/src/mbgl/text/collision_tile.hpp
index b9f8446b15..b64fcdca30 100644
--- a/src/mbgl/text/collision_tile.hpp
+++ b/src/mbgl/text/collision_tile.hpp
@@ -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);