summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2015-10-26 15:45:32 +0100
committerKonstantin Käfer <mail@kkaefer.com>2015-10-26 16:44:55 +0100
commit75dec6ffac6f3e79e5a173cd8a3f98d374ed1c09 (patch)
treedd3e2752cfe2c1ea741ac1b97d38e5e4bc4aa008 /src
parentc0c554e36fd43bfe57ef13fe60f9cd50b5c018fd (diff)
downloadqtlocation-mapboxgl-75dec6ffac6f3e79e5a173cd8a3f98d374ed1c09.tar.gz
[core] always reparse with the freshest possible placement config
Fixes an issue where updates to stale tiles would remove labels altogether until the map was rotated.
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/map/live_tile_data.cpp64
-rw-r--r--src/mbgl/map/live_tile_data.hpp10
-rw-r--r--src/mbgl/map/source.cpp10
-rw-r--r--src/mbgl/map/tile_data.hpp3
-rw-r--r--src/mbgl/map/tile_worker.cpp24
-rw-r--r--src/mbgl/map/tile_worker.hpp10
-rw-r--r--src/mbgl/map/vector_tile_data.cpp78
-rw-r--r--src/mbgl/map/vector_tile_data.hpp19
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp24
-rw-r--r--src/mbgl/text/collision_tile.cpp13
-rw-r--r--src/mbgl/text/collision_tile.hpp38
-rw-r--r--src/mbgl/text/placement_config.hpp28
-rw-r--r--src/mbgl/util/worker.cpp24
-rw-r--r--src/mbgl/util/worker.hpp6
14 files changed, 226 insertions, 125 deletions
diff --git a/src/mbgl/map/live_tile_data.cpp b/src/mbgl/map/live_tile_data.cpp
index fb8e6c3605..89b1d6fda4 100644
--- a/src/mbgl/map/live_tile_data.cpp
+++ b/src/mbgl/map/live_tile_data.cpp
@@ -14,17 +14,12 @@ using namespace mbgl;
LiveTileData::LiveTileData(const TileID& id_,
std::unique_ptr<AnnotationTile> tile_,
- Style& style_,
- const SourceInfo& source_,
+ Style& style,
+ const SourceInfo& source,
std::function<void()> callback)
: TileData(id_),
- worker(style_.workers),
- tileWorker(id_,
- source_.source_id,
- style_,
- style_.layers,
- state,
- std::make_unique<CollisionTile>(0, 0, false)),
+ worker(style.workers),
+ tileWorker(id, source.source_id, style, style.layers, state),
tile(std::move(tile_)) {
state = State::loaded;
@@ -41,25 +36,41 @@ bool LiveTileData::parsePending(std::function<void()> callback) {
return false;
}
- workRequest = worker.parseLiveTile(tileWorker, *tile, [this, callback] (TileParseResult result) {
+ workRequest.reset();
+ workRequest = worker.parseLiveTile(tileWorker, *tile, targetConfig, [this, callback, config = targetConfig] (TileParseResult result) {
workRequest.reset();
if (result.is<TileParseResultBuckets>()) {
auto& resultBuckets = result.get<TileParseResultBuckets>();
state = resultBuckets.state;
+ // Persist the configuration we just placed so that we can later check whether we need
+ // to place again in case the configuration has changed.
+ placedConfig = config;
+
// Move over all buckets we received in this parse request, potentially overwriting
// existing buckets in case we got a refresh parse.
for (auto& bucket : resultBuckets.buckets) {
buckets[bucket.first] = std::move(bucket.second);
}
+ // The target configuration could have changed since we started placement. In this case,
+ // we're starting another placement run.
+ if (placedConfig != targetConfig) {
+ redoPlacement();
+ }
} else {
error = result.get<std::string>();
state = State::obsolete;
}
callback();
+
+ // The target configuration could have changed since we started placement. In this case,
+ // we're starting another placement run.
+ if (!workRequest && placedConfig != targetConfig) {
+ redoPlacement();
+ }
});
return true;
@@ -87,3 +98,36 @@ void LiveTileData::cancel() {
state = State::obsolete;
workRequest.reset();
}
+
+void LiveTileData::redoPlacement(const PlacementConfig newConfig) {
+ if (newConfig != placedConfig) {
+ targetConfig = newConfig;
+
+ if (!workRequest) {
+ // Don't start a new placement request when the current one hasn't completed yet, or
+ // when we are parsing buckets.
+ redoPlacement();
+ }
+ }
+}
+
+void LiveTileData::redoPlacement() {
+ workRequest.reset();
+ workRequest = worker.redoPlacement(tileWorker, buckets, targetConfig, [this, config = targetConfig] {
+ workRequest.reset();
+
+ // Persist the configuration we just placed so that we can later check whether we need to
+ // place again in case the configuration has changed.
+ placedConfig = config;
+
+ for (auto& bucket : buckets) {
+ bucket.second->swapRenderData();
+ }
+
+ // The target configuration could have changed since we started placement. In this case,
+ // we're starting another placement run.
+ if (placedConfig != targetConfig) {
+ redoPlacement();
+ }
+ });
+}
diff --git a/src/mbgl/map/live_tile_data.hpp b/src/mbgl/map/live_tile_data.hpp
index 568892216c..958f1db50a 100644
--- a/src/mbgl/map/live_tile_data.hpp
+++ b/src/mbgl/map/live_tile_data.hpp
@@ -22,6 +22,9 @@ public:
bool parsePending(std::function<void ()> callback) override;
+ void redoPlacement(PlacementConfig config) override;
+ void redoPlacement();
+
void cancel() override;
Bucket* getBucket(const StyleLayer&) override;
@@ -34,6 +37,13 @@ private:
// Contains all the Bucket objects for the tile. Buckets are render
// objects and they get added by tile parsing operations.
std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
+
+ // Stores the placement configuration of the text that is currently placed on the screen.
+ PlacementConfig placedConfig;
+
+ // Stores the placement configuration of how the text should be placed. This isn't necessarily
+ // the one that is being displayed.
+ PlacementConfig targetConfig;
};
}
diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp
index c79ef4b3b6..8a7f97d963 100644
--- a/src/mbgl/map/source.cpp
+++ b/src/mbgl/map/source.cpp
@@ -286,8 +286,7 @@ TileData::State Source::addTile(MapData& data,
// If we don't find working tile data, we're just going to load it.
if (info.type == SourceType::Vector) {
- auto tileData = std::make_shared<VectorTileData>(normalized_id, style, info,
- transformState.getAngle(), transformState.getPitch(), data.getCollisionDebug());
+ auto tileData = std::make_shared<VectorTileData>(normalized_id, style, info);
tileData->request(data.pixelRatio, callback);
new_tile.data = tileData;
} else if (info.type == SourceType::Raster) {
@@ -296,7 +295,7 @@ TileData::State Source::addTile(MapData& data,
new_tile.data = tileData;
} else if (info.type == SourceType::Annotations) {
new_tile.data = std::make_shared<LiveTileData>(normalized_id,
- data.getAnnotationManager()->getTile(normalized_id), style, info, callback);
+ data.getAnnotationManager()->getTile(normalized_id), style, info, callback);
} else {
throw std::runtime_error("source type not implemented");
}
@@ -510,7 +509,8 @@ bool Source::update(MapData& data,
updateTilePtrs();
for (auto& tilePtr : tilePtrs) {
- tilePtr->data->redoPlacement(transformState.getAngle(), transformState.getPitch(), data.getCollisionDebug());
+ tilePtr->data->redoPlacement(
+ { transformState.getAngle(), transformState.getPitch(), data.getCollisionDebug() });
}
updated = data.getAnimationTime();
@@ -560,7 +560,7 @@ void Source::tileLoadingCompleteCallback(const TileID& normalized_id, const Tran
return;
}
- data->redoPlacement(transformState.getAngle(), transformState.getPitch(), collisionDebug);
+ data->redoPlacement({ transformState.getAngle(), transformState.getPitch(), collisionDebug });
emitTileLoaded(true);
}
diff --git a/src/mbgl/map/tile_data.hpp b/src/mbgl/map/tile_data.hpp
index 44f0304c8d..d9895ce01a 100644
--- a/src/mbgl/map/tile_data.hpp
+++ b/src/mbgl/map/tile_data.hpp
@@ -4,6 +4,7 @@
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/map/tile_id.hpp>
#include <mbgl/renderer/bucket.hpp>
+#include <mbgl/text/placement_config.hpp>
#include <atomic>
#include <string>
@@ -76,7 +77,7 @@ public:
virtual Bucket* getBucket(const StyleLayer&) = 0;
virtual bool parsePending(std::function<void ()>) { return true; }
- virtual void redoPlacement(float, float, bool) {}
+ virtual void redoPlacement(PlacementConfig) {}
bool isReady() const {
return isReadyState(state);
diff --git a/src/mbgl/map/tile_worker.cpp b/src/mbgl/map/tile_worker.cpp
index c7836c4ba9..88bbf16a3f 100644
--- a/src/mbgl/map/tile_worker.cpp
+++ b/src/mbgl/map/tile_worker.cpp
@@ -19,15 +19,13 @@ TileWorker::TileWorker(TileID id_,
std::string sourceID_,
Style& style_,
std::vector<util::ptr<StyleLayer>> layers_,
- const std::atomic<TileData::State>& state_,
- std::unique_ptr<CollisionTile> collision_)
+ const std::atomic<TileData::State>& state_)
: layers(std::move(layers_)),
id(id_),
sourceID(sourceID_),
parameters(id.z),
style(style_),
- state(state_),
- collisionTile(std::move(collision_)) {
+ state(state_) {
assert(style.sprite);
}
@@ -35,10 +33,14 @@ TileWorker::~TileWorker() {
style.glyphAtlas->removeGlyphs(reinterpret_cast<uintptr_t>(this));
}
-TileParseResult TileWorker::parseAllLayers(const GeometryTile& geometryTile) {
+TileParseResult TileWorker::parseAllLayers(const GeometryTile& geometryTile,
+ PlacementConfig config) {
// We're doing a fresh parse of the tile, because the underlying data has changed.
pending.clear();
+ // Reset the collision tile so we have a clean slate; we're placing all features anyway.
+ collisionTile = std::make_unique<CollisionTile>(config);
+
// We're storing a list of buckets we've parsed to avoid parsing a bucket twice that is
// referenced from more than one layer
std::set<StyleBucket*> parsed;
@@ -84,12 +86,10 @@ TileParseResult TileWorker::parsePendingLayers() {
void TileWorker::redoPlacement(
const std::unordered_map<std::string, std::unique_ptr<Bucket>>* buckets,
- float angle,
- float pitch,
- bool collisionDebug) {
+ PlacementConfig config) {
// Reset the collision tile so we have a clean slate; we're placing all features anyway.
- collisionTile = std::make_unique<CollisionTile>(angle, pitch, collisionDebug);
+ collisionTile = std::make_unique<CollisionTile>(config);
for (auto i = layers.rbegin(); i != layers.rend(); i++) {
const auto it = buckets->find((*i)->id);
@@ -268,11 +268,17 @@ void TileWorker::createSymbolBucket(const GeometryTileLayer& layer,
bucket->parseFeatures(layer, styleBucket.filter);
+ assert(style.glyphStore);
+ assert(style.sprite);
const bool needsDependencies = bucket->needsDependencies(*style.glyphStore, *style.sprite);
if (needsDependencies) {
// We cannot parse this bucket yet. Instead, we're saving it for later.
pending.emplace_back(styleBucket, std::move(bucket));
} else {
+ assert(style.spriteAtlas);
+ assert(style.glyphAtlas);
+ assert(style.glyphStore);
+ assert(collisionTile);
bucket->addFeatures(reinterpret_cast<uintptr_t>(this), *style.spriteAtlas,
*style.glyphAtlas, *style.glyphStore, *collisionTile);
insertBucket(styleBucket.name, std::move(bucket));
diff --git a/src/mbgl/map/tile_worker.hpp b/src/mbgl/map/tile_worker.hpp
index f7cfa57ac6..27fc0d37fe 100644
--- a/src/mbgl/map/tile_worker.hpp
+++ b/src/mbgl/map/tile_worker.hpp
@@ -8,6 +8,7 @@
#include <mbgl/util/ptr.hpp>
#include <mbgl/style/filter_expression.hpp>
#include <mbgl/style/style_calculation_parameters.hpp>
+#include <mbgl/text/placement_config.hpp>
#include <string>
#include <memory>
@@ -42,16 +43,13 @@ public:
std::string sourceID,
Style&,
std::vector<util::ptr<StyleLayer>>,
- const std::atomic<TileData::State>&,
- std::unique_ptr<CollisionTile>);
+ const std::atomic<TileData::State>&);
~TileWorker();
- TileParseResult parseAllLayers(const GeometryTile&);
+ TileParseResult parseAllLayers(const GeometryTile&, PlacementConfig);
TileParseResult parsePendingLayers();
void redoPlacement(const std::unordered_map<std::string, std::unique_ptr<Bucket>>*,
- float angle,
- float pitch,
- bool collisionDebug);
+ PlacementConfig);
std::vector<util::ptr<StyleLayer>> layers;
diff --git a/src/mbgl/map/vector_tile_data.cpp b/src/mbgl/map/vector_tile_data.cpp
index c3115cdb88..3c831250c5 100644
--- a/src/mbgl/map/vector_tile_data.cpp
+++ b/src/mbgl/map/vector_tile_data.cpp
@@ -14,23 +14,15 @@ using namespace mbgl;
VectorTileData::VectorTileData(const TileID& id_,
Style& style_,
- const SourceInfo& source_,
- float angle,
- float pitch,
- bool collisionDebug)
+ const SourceInfo& source_)
: TileData(id_),
worker(style_.workers),
tileWorker(id_,
source_.source_id,
style_,
style_.layers,
- state,
- std::make_unique<CollisionTile>(angle, pitch, collisionDebug)),
- source(source_),
- lastAngle(angle),
- currentAngle(angle),
- currentPitch(pitch),
- currentCollisionDebug(collisionDebug) {
+ state),
+ source(source_) {
}
VectorTileData::~VectorTileData() {
@@ -81,7 +73,7 @@ void VectorTileData::parse(std::function<void ()> callback) {
// when tile data changed. Replacing the workdRequest will cancel a pending work
// request in case there is one.
workRequest.reset();
- workRequest = worker.parseVectorTile(tileWorker, data, [this, callback] (TileParseResult result) {
+ workRequest = worker.parseVectorTile(tileWorker, data, targetConfig, [this, callback, config = targetConfig] (TileParseResult result) {
workRequest.reset();
if (state == State::obsolete) {
return;
@@ -91,11 +83,21 @@ void VectorTileData::parse(std::function<void ()> callback) {
auto& resultBuckets = result.get<TileParseResultBuckets>();
state = resultBuckets.state;
+ // Persist the configuration we just placed so that we can later check whether we need to
+ // place again in case the configuration has changed.
+ placedConfig = config;
+
// Move over all buckets we received in this parse request, potentially overwriting
// existing buckets in case we got a refresh parse.
for (auto& bucket : resultBuckets.buckets) {
buckets[bucket.first] = std::move(bucket.second);
}
+
+ // The target configuration could have changed since we started placement. In this case,
+ // we're starting another placement run.
+ if (placedConfig != targetConfig) {
+ redoPlacement();
+ }
} else {
std::stringstream message;
message << "Failed to parse [" << std::string(id) << "]: " << result.get<std::string>();
@@ -129,6 +131,12 @@ bool VectorTileData::parsePending(std::function<void()> callback) {
for (auto& bucket : resultBuckets.buckets) {
buckets[bucket.first] = std::move(bucket.second);
}
+
+ // The target configuration could have changed since we started placement. In this case,
+ // we're starting another placement run.
+ if (placedConfig != targetConfig) {
+ redoPlacement();
+ }
} else {
std::stringstream message;
message << "Failed to parse [" << std::string(id) << "]: " << result.get<std::string>();
@@ -156,34 +164,36 @@ Bucket* VectorTileData::getBucket(const StyleLayer& layer) {
return it->second.get();
}
-void VectorTileData::redoPlacement(float angle, float pitch, bool collisionDebug) {
- if (angle == currentAngle && pitch == currentPitch && collisionDebug == currentCollisionDebug)
- return;
-
- lastAngle = angle;
- lastPitch = pitch;
- lastCollisionDebug = collisionDebug;
+void VectorTileData::redoPlacement(const PlacementConfig newConfig) {
+ if (newConfig != placedConfig) {
+ targetConfig = newConfig;
- if (workRequest) {
- // Don't start a new placement request when the current one hasn't completed yet, or when
- // we are parsing buckets.
- return;
+ if (!workRequest) {
+ // Don't start a new placement request when the current one hasn't completed yet, or when
+ // we are parsing buckets.
+ redoPlacement();
+ }
}
+}
- currentAngle = angle;
- currentPitch = pitch;
- currentCollisionDebug = collisionDebug;
-
+void VectorTileData::redoPlacement() {
workRequest.reset();
- workRequest = worker.redoPlacement(tileWorker, buckets, angle, pitch, collisionDebug, [this] {
+ workRequest = worker.redoPlacement(tileWorker, buckets, targetConfig, [this, config = targetConfig] {
workRequest.reset();
- for (const auto& layer : tileWorker.layers) {
- auto bucket = getBucket(*layer);
- if (bucket) {
- bucket->swapRenderData();
- }
+
+ // Persist the configuration we just placed so that we can later check whether we need to
+ // place again in case the configuration has changed.
+ placedConfig = config;
+
+ for (auto& bucket : buckets) {
+ bucket.second->swapRenderData();
+ }
+
+ // The target configuration could have changed since we started placement. In this case,
+ // we're starting another placement run.
+ if (placedConfig != targetConfig) {
+ redoPlacement();
}
- redoPlacement(lastAngle, lastPitch, lastCollisionDebug);
});
}
diff --git a/src/mbgl/map/vector_tile_data.hpp b/src/mbgl/map/vector_tile_data.hpp
index 8497323e52..9faffab83f 100644
--- a/src/mbgl/map/vector_tile_data.hpp
+++ b/src/mbgl/map/vector_tile_data.hpp
@@ -4,6 +4,7 @@
#include <mbgl/map/tile_data.hpp>
#include <mbgl/map/tile_worker.hpp>
#include <mbgl/storage/request_holder.hpp>
+#include <mbgl/text/placement_config.hpp>
#include <atomic>
@@ -17,7 +18,7 @@ class Request;
class VectorTileData : public TileData {
public:
VectorTileData(
- const TileID&, Style&, const SourceInfo&, float angle_, float pitch_, bool collisionDebug_);
+ const TileID&, Style&, const SourceInfo&);
~VectorTileData();
Bucket* getBucket(const StyleLayer&) override;
@@ -27,7 +28,8 @@ public:
void parse(std::function<void()> callback);
bool parsePending(std::function<void()> callback) override;
- void redoPlacement(float angle, float pitch, bool collisionDebug) override;
+ void redoPlacement(PlacementConfig config) override;
+ void redoPlacement();
void cancel() override;
@@ -43,12 +45,13 @@ private:
const SourceInfo& source;
RequestHolder req;
std::shared_ptr<const std::string> data;
- float lastAngle = 0;
- float currentAngle;
- float lastPitch = 0;
- float currentPitch;
- bool lastCollisionDebug = 0;
- bool currentCollisionDebug = 0;
+
+ // Stores the placement configuration of the text that is currently placed on the screen.
+ PlacementConfig placedConfig;
+
+ // Stores the placement configuration of how the text should be placed. This isn't necessarily
+ // the one that is being displayed.
+ PlacementConfig targetConfig;
};
} // namespace mbgl
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index d85dbaf858..281888d9c5 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -382,8 +382,8 @@ void SymbolBucket::placeFeatures(CollisionTile& collisionTile, bool swapImmediat
// Don't sort symbols that won't overlap because it isn't necessary and
// because it causes more labels to pop in and out when rotating.
if (mayOverlap) {
- float sin = std::sin(collisionTile.angle);
- float cos = std::cos(collisionTile.angle);
+ const float sin = std::sin(collisionTile.config.angle);
+ const float cos = std::cos(collisionTile.config.angle);
std::sort(symbolInstances.begin(), symbolInstances.end(), [sin, cos](SymbolInstance &a, SymbolInstance &b) {
const float aRotated = sin * a.x + cos * a.y;
@@ -426,8 +426,9 @@ void SymbolBucket::placeFeatures(CollisionTile& collisionTile, bool swapImmediat
collisionTile.insertFeature(symbolInstance.textCollisionFeature, glyphScale);
}
if (glyphScale < collisionTile.maxScale) {
- addSymbols<SymbolRenderData::TextBuffer, TextElementGroup>(renderDataInProgress->text,
- symbolInstance.glyphQuads, glyphScale, layout.text.keep_upright, textAlongLine, collisionTile.angle);
+ addSymbols<SymbolRenderData::TextBuffer, TextElementGroup>(
+ renderDataInProgress->text, symbolInstance.glyphQuads, glyphScale,
+ layout.text.keep_upright, textAlongLine, collisionTile.config.angle);
}
}
@@ -436,13 +437,16 @@ void SymbolBucket::placeFeatures(CollisionTile& collisionTile, bool swapImmediat
collisionTile.insertFeature(symbolInstance.iconCollisionFeature, iconScale);
}
if (iconScale < collisionTile.maxScale) {
- addSymbols<SymbolRenderData::IconBuffer, IconElementGroup>(renderDataInProgress->icon,
- symbolInstance.iconQuads, iconScale, layout.icon.keep_upright, iconAlongLine, collisionTile.angle);
+ addSymbols<SymbolRenderData::IconBuffer, IconElementGroup>(
+ renderDataInProgress->icon, symbolInstance.iconQuads, iconScale,
+ layout.icon.keep_upright, iconAlongLine, collisionTile.config.angle);
}
}
}
- if (collisionTile.getDebug()) addToDebugBuffers(collisionTile);
+ if (collisionTile.config.debug) {
+ addToDebugBuffers(collisionTile);
+ }
if (swapImmediately) swapRenderData();
}
@@ -513,7 +517,7 @@ void SymbolBucket::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float
void SymbolBucket::addToDebugBuffers(CollisionTile &collisionTile) {
const float yStretch = collisionTile.yStretch;
- const float angle = collisionTile.angle;
+ const float angle = collisionTile.config.angle;
float angle_sin = std::sin(-angle);
float angle_cos = std::cos(-angle);
std::array<float, 4> matrix = {{angle_cos, -angle_sin, angle_sin, angle_cos}};
@@ -562,7 +566,9 @@ void SymbolBucket::addToDebugBuffers(CollisionTile &collisionTile) {
}
void SymbolBucket::swapRenderData() {
- renderData = std::move(renderDataInProgress);
+ if (renderDataInProgress) {
+ renderData = std::move(renderDataInProgress);
+ }
}
void SymbolBucket::drawGlyphs(SDFShader &shader) {
diff --git a/src/mbgl/text/collision_tile.cpp b/src/mbgl/text/collision_tile.cpp
index d18860ccf5..ecd615a520 100644
--- a/src/mbgl/text/collision_tile.cpp
+++ b/src/mbgl/text/collision_tile.cpp
@@ -3,17 +3,16 @@
namespace mbgl {
-CollisionTile::CollisionTile(const float angle_, const float pitch, bool debug_) :
- angle(angle_), debug(debug_) {
+CollisionTile::CollisionTile(PlacementConfig config_) : config(config_) {
tree.clear();
- // Compute the transformation matrix.
- float angle_sin = std::sin(angle);
- float angle_cos = std::cos(angle);
- rotationMatrix = {{angle_cos, -angle_sin, angle_sin, angle_cos}};
+ // Compute the transformation matrix.
+ const float angle_sin = std::sin(config.angle);
+ const float angle_cos = std::cos(config.angle);
+ rotationMatrix = { { angle_cos, -angle_sin, angle_sin, angle_cos } };
// Stretch boxes in y direction to account for the map tilt.
- const float _yStretch = 1.0f / std::cos(pitch);
+ const float _yStretch = 1.0f / std::cos(config.pitch);
// The amount the map is squished depends on the y position.
// Sort of account for this by making all boxes a bit bigger.
diff --git a/src/mbgl/text/collision_tile.hpp b/src/mbgl/text/collision_tile.hpp
index 3fd1b0a4c8..edd5eb61a0 100644
--- a/src/mbgl/text/collision_tile.hpp
+++ b/src/mbgl/text/collision_tile.hpp
@@ -2,6 +2,7 @@
#define MBGL_TEXT_COLLISION_TILE
#include <mbgl/text/collision_feature.hpp>
+#include <mbgl/text/placement_config.hpp>
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
@@ -24,39 +25,34 @@
namespace mbgl {
- namespace bg = boost::geometry;
- namespace bgm = bg::model;
- namespace bgi = bg::index;
- typedef bgm::point<float, 2, bg::cs::cartesian> CollisionPoint;
- typedef bgm::box<CollisionPoint> Box;
- typedef std::pair<Box, CollisionBox> CollisionTreeBox;
- typedef bgi::rtree<CollisionTreeBox, bgi::linear<16,4>> Tree;
+namespace bg = boost::geometry;
+namespace bgm = bg::model;
+namespace bgi = bg::index;
+typedef bgm::point<float, 2, bg::cs::cartesian> CollisionPoint;
+typedef bgm::box<CollisionPoint> Box;
+typedef std::pair<Box, CollisionBox> CollisionTreeBox;
+typedef bgi::rtree<CollisionTreeBox, bgi::linear<16, 4>> Tree;
class CollisionTile {
+public:
+ explicit CollisionTile(PlacementConfig);
- public:
- explicit CollisionTile(float angle_, float pitch_, bool debug_);
+ float placeFeature(const CollisionFeature& feature);
+ void insertFeature(CollisionFeature& feature, const float minPlacementScale);
- float placeFeature(const CollisionFeature &feature);
- void insertFeature(CollisionFeature &feature, const float minPlacementScale);
-
- bool getDebug() { return debug; }
-
- const float angle = 0;
+ const PlacementConfig config;
const float minScale = 0.5f;
const float maxScale = 2.0f;
float yStretch;
- private:
-
- Box getTreeBox(const vec2<float> &anchor, const CollisionBox &box);
+private:
+ Box getTreeBox(const vec2<float>& anchor, const CollisionBox& box);
Tree tree;
std::array<float, 4> rotationMatrix;
- bool debug;
-
};
-}
+
+} // namespace mbgl
#endif
diff --git a/src/mbgl/text/placement_config.hpp b/src/mbgl/text/placement_config.hpp
new file mode 100644
index 0000000000..6680f52449
--- /dev/null
+++ b/src/mbgl/text/placement_config.hpp
@@ -0,0 +1,28 @@
+#ifndef MBGL_TEXT_PLACEMENT_CONFIG
+#define MBGL_TEXT_PLACEMENT_CONFIG
+
+namespace mbgl {
+
+class PlacementConfig {
+public:
+ inline PlacementConfig(float angle_ = 0, float pitch_ = 0, bool debug_ = false)
+ : angle(angle_), pitch(pitch_), debug(debug_) {
+ }
+
+ inline bool operator==(const PlacementConfig& rhs) const {
+ return angle == rhs.angle && pitch == rhs.pitch && debug == rhs.debug;
+ }
+
+ inline bool operator!=(const PlacementConfig& rhs) const {
+ return !operator==(rhs);
+ }
+
+public:
+ float angle;
+ float pitch;
+ bool debug;
+};
+
+} // namespace mbgl
+
+#endif
diff --git a/src/mbgl/util/worker.cpp b/src/mbgl/util/worker.cpp
index 371766f096..4dd6740ec1 100644
--- a/src/mbgl/util/worker.cpp
+++ b/src/mbgl/util/worker.cpp
@@ -37,10 +37,11 @@ public:
void parseVectorTile(TileWorker* worker,
const std::shared_ptr<const std::string> data,
+ PlacementConfig config,
std::function<void(TileParseResult)> callback) {
try {
pbf tilePBF(reinterpret_cast<const unsigned char*>(data->data()), data->size());
- callback(worker->parseAllLayers(VectorTile(tilePBF)));
+ callback(worker->parseAllLayers(VectorTile(tilePBF), config));
} catch (const std::exception& ex) {
callback(TileParseResult(ex.what()));
}
@@ -57,9 +58,10 @@ public:
void parseLiveTile(TileWorker* worker,
const AnnotationTile* tile,
+ PlacementConfig config,
std::function<void(TileParseResult)> callback) {
try {
- callback(worker->parseAllLayers(*tile));
+ callback(worker->parseAllLayers(*tile, config));
} catch (const std::exception& ex) {
callback(TileParseResult(ex.what()));
}
@@ -67,11 +69,9 @@ public:
void redoPlacement(TileWorker* worker,
const std::unordered_map<std::string, std::unique_ptr<Bucket>>* buckets,
- float angle,
- float pitch,
- bool collisionDebug,
+ PlacementConfig config,
std::function<void()> callback) {
- worker->redoPlacement(buckets, angle, pitch, collisionDebug);
+ worker->redoPlacement(buckets, config);
callback();
}
};
@@ -97,10 +97,11 @@ Worker::parseRasterTile(std::unique_ptr<RasterBucket> bucket,
std::unique_ptr<WorkRequest>
Worker::parseVectorTile(TileWorker& worker,
const std::shared_ptr<const std::string> data,
+ PlacementConfig config,
std::function<void(TileParseResult)> callback) {
current = (current + 1) % threads.size();
return threads[current]->invokeWithCallback(&Worker::Impl::parseVectorTile, callback, &worker,
- data);
+ data, config);
}
std::unique_ptr<WorkRequest>
@@ -113,22 +114,21 @@ Worker::parsePendingVectorTileLayers(TileWorker& worker,
std::unique_ptr<WorkRequest> Worker::parseLiveTile(TileWorker& worker,
const AnnotationTile& tile,
+ PlacementConfig config,
std::function<void(TileParseResult)> callback) {
current = (current + 1) % threads.size();
return threads[current]->invokeWithCallback(&Worker::Impl::parseLiveTile, callback, &worker,
- &tile);
+ &tile, config);
}
std::unique_ptr<WorkRequest>
Worker::redoPlacement(TileWorker& worker,
const std::unordered_map<std::string, std::unique_ptr<Bucket>>& buckets,
- float angle,
- float pitch,
- bool collisionDebug,
+ PlacementConfig config,
std::function<void()> callback) {
current = (current + 1) % threads.size();
return threads[current]->invokeWithCallback(&Worker::Impl::redoPlacement, callback, &worker,
- &buckets, angle, pitch, collisionDebug);
+ &buckets, config);
}
} // end namespace mbgl
diff --git a/src/mbgl/util/worker.hpp b/src/mbgl/util/worker.hpp
index 7a92a09a51..3d2665e71c 100644
--- a/src/mbgl/util/worker.hpp
+++ b/src/mbgl/util/worker.hpp
@@ -37,6 +37,7 @@ public:
Request parseVectorTile(TileWorker&,
std::shared_ptr<const std::string> data,
+ PlacementConfig config,
std::function<void(TileParseResult)> callback);
Request parsePendingVectorTileLayers(TileWorker&,
@@ -44,13 +45,12 @@ public:
Request parseLiveTile(TileWorker&,
const AnnotationTile&,
+ PlacementConfig config,
std::function<void(TileParseResult)> callback);
Request redoPlacement(TileWorker&,
const std::unordered_map<std::string, std::unique_ptr<Bucket>>&,
- float angle,
- float pitch,
- bool collisionDebug,
+ PlacementConfig config,
std::function<void()> callback);
private: