summaryrefslogtreecommitdiff
path: root/src/mbgl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl')
-rw-r--r--src/mbgl/annotation/annotation_tile.cpp2
-rw-r--r--src/mbgl/annotation/annotation_tile.hpp2
-rw-r--r--src/mbgl/geometry/feature_index.cpp2
-rw-r--r--src/mbgl/gfx/vertex_vector.hpp10
-rw-r--r--src/mbgl/layout/pattern_layout.hpp2
-rw-r--r--src/mbgl/layout/symbol_feature.hpp6
-rw-r--r--src/mbgl/renderer/layers/render_circle_layer.cpp2
-rw-r--r--src/mbgl/renderer/layers/render_line_layer.cpp35
-rw-r--r--src/mbgl/renderer/layers/render_raster_layer.cpp6
-rw-r--r--src/mbgl/renderer/render_layer.cpp1
-rw-r--r--src/mbgl/renderer/render_orchestrator.cpp19
-rw-r--r--src/mbgl/renderer/tile_pyramid.cpp1
-rw-r--r--src/mbgl/style/expression/compound_expression.cpp3
-rw-r--r--src/mbgl/style/expression/expression.cpp3
-rw-r--r--src/mbgl/text/placement.cpp80
-rw-r--r--src/mbgl/tile/geojson_tile_data.hpp18
-rw-r--r--src/mbgl/tile/geometry_tile.cpp2
-rw-r--r--src/mbgl/tile/geometry_tile_data.cpp35
-rw-r--r--src/mbgl/tile/geometry_tile_data.hpp50
-rw-r--r--src/mbgl/tile/geometry_tile_worker.cpp2
-rw-r--r--src/mbgl/tile/vector_tile_data.cpp22
-rw-r--r--src/mbgl/tile/vector_tile_data.hpp6
-rw-r--r--src/mbgl/util/grid_index.cpp24
-rw-r--r--src/mbgl/util/grid_index.hpp10
24 files changed, 180 insertions, 163 deletions
diff --git a/src/mbgl/annotation/annotation_tile.cpp b/src/mbgl/annotation/annotation_tile.cpp
index 6c3c9eb617..a410adc95e 100644
--- a/src/mbgl/annotation/annotation_tile.cpp
+++ b/src/mbgl/annotation/annotation_tile.cpp
@@ -58,7 +58,7 @@ FeatureIdentifier AnnotationTileFeature::getID() const {
return data->id;
}
-GeometryCollection AnnotationTileFeature::getGeometries() const {
+const GeometryCollection& AnnotationTileFeature::getGeometries() const {
return data->geometries;
}
diff --git a/src/mbgl/annotation/annotation_tile.hpp b/src/mbgl/annotation/annotation_tile.hpp
index 1e23fdf98a..741b598a8c 100644
--- a/src/mbgl/annotation/annotation_tile.hpp
+++ b/src/mbgl/annotation/annotation_tile.hpp
@@ -28,7 +28,7 @@ public:
FeatureType getType() const override;
optional<Value> getValue(const std::string&) const override;
FeatureIdentifier getID() const override;
- GeometryCollection getGeometries() const override;
+ const GeometryCollection& getGeometries() const override;
private:
std::shared_ptr<const AnnotationTileFeatureData> data;
diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp
index 3675e8bc6e..b76e02be3f 100644
--- a/src/mbgl/geometry/feature_index.cpp
+++ b/src/mbgl/geometry/feature_index.cpp
@@ -159,7 +159,7 @@ void FeatureIndex::addFeature(
continue;
}
- result[layerID].push_back(convertFeature(*geometryTileFeature, tileID));
+ result[layerID].emplace_back(convertFeature(*geometryTileFeature, tileID));
}
}
diff --git a/src/mbgl/gfx/vertex_vector.hpp b/src/mbgl/gfx/vertex_vector.hpp
index f41f842294..59fe67586b 100644
--- a/src/mbgl/gfx/vertex_vector.hpp
+++ b/src/mbgl/gfx/vertex_vector.hpp
@@ -11,11 +11,13 @@ template <class V>
class VertexVector {
public:
using Vertex = V;
+ template<typename Arg>
+ void emplace_back(Arg&& vertex) {
+ v.emplace_back(std::forward<Arg>(vertex));
+ }
- template <class... Args>
- void emplace_back(Args&&... args) {
- static_assert(sizeof...(args) == 1, "wrong buffer element count");
- util::ignore({ (v.emplace_back(std::forward<Args>(args)), 0)... });
+ void extend(std::size_t n, const Vertex& val) {
+ v.resize(v.size() + n, val);
}
std::size_t elements() const {
diff --git a/src/mbgl/layout/pattern_layout.hpp b/src/mbgl/layout/pattern_layout.hpp
index 95f8b181fc..858d515347 100644
--- a/src/mbgl/layout/pattern_layout.hpp
+++ b/src/mbgl/layout/pattern_layout.hpp
@@ -106,7 +106,7 @@ public:
const auto i = patternFeature.i;
std::unique_ptr<GeometryTileFeature> feature = std::move(patternFeature.feature);
const PatternLayerMap& patterns = patternFeature.patterns;
- GeometryCollection geometries = feature->getGeometries();
+ const GeometryCollection& geometries = feature->getGeometries();
bucket->addFeature(*feature, geometries, patternPositions, patterns);
featureIndex->insert(geometries, i, sourceLayerID, bucketLeaderID);
diff --git a/src/mbgl/layout/symbol_feature.hpp b/src/mbgl/layout/symbol_feature.hpp
index 72f613d4b6..ed9c0783d0 100644
--- a/src/mbgl/layout/symbol_feature.hpp
+++ b/src/mbgl/layout/symbol_feature.hpp
@@ -13,14 +13,14 @@ class SymbolFeature : public GeometryTileFeature {
public:
SymbolFeature(std::unique_ptr<GeometryTileFeature> feature_) :
feature(std::move(feature_)),
- geometry(feature->getGeometries()) // we need a mutable copy of the geometry for mergeLines()
+ geometry(feature->getGeometries().clone()) // we need a mutable copy of the geometry for mergeLines()
{}
FeatureType getType() const override { return feature->getType(); }
optional<Value> getValue(const std::string& key) const override { return feature->getValue(key); };
- std::unordered_map<std::string,Value> getProperties() const override { return feature->getProperties(); };
+ const PropertyMap& getProperties() const override { return feature->getProperties(); };
FeatureIdentifier getID() const override { return feature->getID(); };
- GeometryCollection getGeometries() const override { return geometry; };
+ const GeometryCollection& getGeometries() const override { return geometry; };
friend bool operator < (const SymbolFeature& lhs, const SymbolFeature& rhs) {
return lhs.sortKey < rhs.sortKey;
diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp
index cf59319307..4f1620364f 100644
--- a/src/mbgl/renderer/layers/render_circle_layer.cpp
+++ b/src/mbgl/renderer/layers/render_circle_layer.cpp
@@ -167,7 +167,7 @@ bool RenderCircleLayer::queryIntersectsFeature(
projectQueryGeometry(translatedQueryGeometry, posMatrix, transformState.getSize());
auto transformedSize = alignWithMap ? size * pixelsToTileUnits : size;
- auto geometry = feature.getGeometries();
+ const auto& geometry = feature.getGeometries();
for (auto& ring : geometry) {
for (auto& point : ring) {
const GeometryCoordinate& transformedPoint = alignWithMap ? point : projectPoint(point, posMatrix, transformState.getSize());
diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp
index 5c56826bd7..fcd52b21df 100644
--- a/src/mbgl/renderer/layers/render_line_layer.cpp
+++ b/src/mbgl/renderer/layers/render_line_layer.cpp
@@ -214,16 +214,22 @@ void RenderLineLayer::render(PaintParameters& parameters) {
}
}
-optional<GeometryCollection> offsetLine(const GeometryCollection& rings, const double offset) {
- if (offset == 0) return {};
+namespace {
+
+GeometryCollection offsetLine(const GeometryCollection& rings, double offset) {
+ assert(offset != 0.0f);
+ assert(!rings.empty());
GeometryCollection newRings;
- Point<double> zero(0, 0);
+ newRings.reserve(rings.size());
+
+ const Point<double> zero(0, 0);
for (const auto& ring : rings) {
newRings.emplace_back();
auto& newRing = newRings.back();
+ newRing.reserve(ring.size());
- for (auto i = ring.begin(); i != ring.end(); i++) {
+ for (auto i = ring.begin(); i != ring.end(); ++i) {
auto& p = *i;
Point<double> aToB = i == ring.begin() ?
@@ -237,13 +243,15 @@ optional<GeometryCollection> offsetLine(const GeometryCollection& rings, const d
const double cosHalfAngle = extrude.x * bToC.x + extrude.y * bToC.y;
extrude *= (1.0 / cosHalfAngle);
- newRing.push_back(convertPoint<int16_t>(extrude * offset) + p);
+ newRing.emplace_back(convertPoint<int16_t>(extrude * offset) + p);
}
}
return newRings;
}
+} // namespace
+
bool RenderLineLayer::queryIntersectsFeature(
const GeometryCoordinates& queryGeometry,
const GeometryTileFeature& feature,
@@ -263,16 +271,21 @@ bool RenderLineLayer::queryIntersectsFeature(
// Evaluate function
auto offset = evaluated.get<style::LineOffset>()
.evaluate(feature, zoom, style::LineOffset::defaultValue()) * pixelsToTileUnits;
+ // Test intersection
+ const float halfWidth = getLineWidth(feature, zoom) / 2.0 * pixelsToTileUnits;
// Apply offset to geometry
- auto offsetGeometry = offsetLine(feature.getGeometries(), offset);
+ if (offset != 0.0f && !feature.getGeometries().empty()) {
+ return util::polygonIntersectsBufferedMultiLine(
+ translatedQueryGeometry.value_or(queryGeometry),
+ offsetLine(feature.getGeometries(), offset),
+ halfWidth);
+ }
- // Test intersection
- const float halfWidth = getLineWidth(feature, zoom) / 2.0 * pixelsToTileUnits;
return util::polygonIntersectsBufferedMultiLine(
- translatedQueryGeometry.value_or(queryGeometry),
- offsetGeometry.value_or(feature.getGeometries()),
- halfWidth);
+ translatedQueryGeometry.value_or(queryGeometry),
+ feature.getGeometries(),
+ halfWidth);
}
void RenderLineLayer::updateColorRamp() {
diff --git a/src/mbgl/renderer/layers/render_raster_layer.cpp b/src/mbgl/renderer/layers/render_raster_layer.cpp
index ecaee2985c..82d135b9ef 100644
--- a/src/mbgl/renderer/layers/render_raster_layer.cpp
+++ b/src/mbgl/renderer/layers/render_raster_layer.cpp
@@ -77,12 +77,14 @@ static std::array<float, 3> spinWeights(float spin) {
void RenderRasterLayer::prepare(const LayerPrepareParameters& params) {
renderTiles = params.source->getRenderTiles();
imageData = params.source->getImageRenderData();
- assert(renderTiles || imageData);
+ // It is possible image data is not available until the source loads it.
+ assert(renderTiles || imageData || !params.source->isEnabled());
}
void RenderRasterLayer::render(PaintParameters& parameters) {
- if (parameters.pass != RenderPass::Translucent)
+ if (parameters.pass != RenderPass::Translucent || (!renderTiles && !imageData)) {
return;
+ }
const auto& evaluated = static_cast<const RasterLayerProperties&>(*evaluatedProperties).evaluated;
RasterProgram::Binders paintAttributeData{ evaluated, 0 };
diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp
index f15dc7e6f4..c1ca1fd017 100644
--- a/src/mbgl/renderer/render_layer.cpp
+++ b/src/mbgl/renderer/render_layer.cpp
@@ -47,6 +47,7 @@ bool RenderLayer::supportsZoom(float zoom) const {
void RenderLayer::prepare(const LayerPrepareParameters& params) {
assert(params.source);
+ assert(params.source->isEnabled());
renderTiles = params.source->getRenderTiles();
addRenderPassesFromTiles();
}
diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp
index 4ce36434d2..5b6b27c185 100644
--- a/src/mbgl/renderer/render_orchestrator.cpp
+++ b/src/mbgl/renderer/render_orchestrator.cpp
@@ -274,9 +274,6 @@ std::unique_ptr<RenderTree> RenderOrchestrator::createRenderTree(const UpdatePar
// Reserve size for filteredLayersForSource if there are sources.
if (!sourceImpls->empty()) {
filteredLayersForSource.reserve(layerImpls->size());
- if (filteredLayersForSource.capacity() > layerImpls->size()) {
- filteredLayersForSource.shrink_to_fit();
- }
}
// Update all sources and initialize renderItems.
@@ -487,7 +484,12 @@ void RenderOrchestrator::queryRenderedSymbols(std::unordered_map<std::string, st
std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options, const std::unordered_map<std::string, const RenderLayer*>& layers) const {
std::unordered_set<std::string> sourceIDs;
+ std::unordered_map<std::string, const RenderLayer*> filteredLayers;
for (const auto& pair : layers) {
+ if (!pair.second->needsRendering() || !pair.second->supportsZoom(zoomHistory.lastZoom)) {
+ continue;
+ }
+ filteredLayers.emplace(pair);
sourceIDs.emplace(pair.second->baseImpl->source);
}
@@ -497,12 +499,12 @@ std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineS
std::unordered_map<std::string, std::vector<Feature>> resultsByLayer;
for (const auto& sourceID : sourceIDs) {
if (RenderSource* renderSource = getRenderSource(sourceID)) {
- auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
+ auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, filteredLayers, options, projMatrix);
std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
}
}
- queryRenderedSymbols(resultsByLayer, geometry, layers, options);
+ queryRenderedSymbols(resultsByLayer, geometry, filteredLayers, options);
std::vector<Feature> result;
@@ -511,11 +513,7 @@ std::vector<Feature> RenderOrchestrator::queryRenderedFeatures(const ScreenLineS
}
// Combine all results based on the style layer renderItems.
- for (const auto& pair : layers) {
- if (!pair.second->needsRendering() || !pair.second->supportsZoom(zoomHistory.lastZoom)) {
- continue;
- }
-
+ for (const auto& pair : filteredLayers) {
auto it = resultsByLayer.find(pair.second->baseImpl->id);
if (it != resultsByLayer.end()) {
std::move(it->second.begin(), it->second.end(), std::back_inserter(result));
@@ -560,6 +558,7 @@ FeatureExtensionValue RenderOrchestrator::queryFeatureExtensions(const std::stri
}
void RenderOrchestrator::reduceMemoryUse() {
+ filteredLayersForSource.shrink_to_fit();
for (const auto& entry : renderSources) {
entry.second->reduceMemoryUse();
}
diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp
index f47198e275..54e0b1eb26 100644
--- a/src/mbgl/renderer/tile_pyramid.cpp
+++ b/src/mbgl/renderer/tile_pyramid.cpp
@@ -293,6 +293,7 @@ std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRendered
}
LineString<double> queryGeometry;
+ queryGeometry.reserve(geometry.size());
for (const auto& p : geometry) {
queryGeometry.push_back(TileCoordinate::fromScreenCoordinate(
diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp
index 825307432b..6958b1d625 100644
--- a/src/mbgl/style/expression/compound_expression.cpp
+++ b/src/mbgl/style/expression/compound_expression.cpp
@@ -435,7 +435,8 @@ const auto& propertiesCompoundExpression() {
};
}
std::unordered_map<std::string, Value> result;
- const PropertyMap properties = params.feature->getProperties();
+ const PropertyMap& properties = params.feature->getProperties();
+ result.reserve(properties.size());
for (const auto& entry : properties) {
result[entry.first] = toExpressionValue(entry.second);
}
diff --git a/src/mbgl/style/expression/expression.cpp b/src/mbgl/style/expression/expression.cpp
index b3641b9448..eedc706633 100644
--- a/src/mbgl/style/expression/expression.cpp
+++ b/src/mbgl/style/expression/expression.cpp
@@ -15,9 +15,8 @@ public:
FeatureType getType() const override {
return apply_visitor(ToFeatureType(), feature.geometry);
}
- PropertyMap getProperties() const override { return feature.properties; }
+ const PropertyMap& getProperties() const override { return feature.properties; }
FeatureIdentifier getID() const override { return feature.id; }
- GeometryCollection getGeometries() const override { return {}; }
optional<mbgl::Value> getValue(const std::string& key) const override {
auto it = feature.properties.find(key);
if (it != feature.properties.end()) {
diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp
index b7d2189afd..79bb984aa2 100644
--- a/src/mbgl/text/placement.cpp
+++ b/src/mbgl/text/placement.cpp
@@ -545,46 +545,38 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
seenCrossTileIDs.insert(symbolInstance.crossTileID);
if (symbolInstance.hasText) {
- auto opacityVertex = SymbolSDFTextProgram::opacityVertex(opacityState.text.placed, opacityState.text.opacity);
+ size_t textOpacityVerticesSize = 0u;
+ const auto& opacityVertex = SymbolSDFTextProgram::opacityVertex(opacityState.text.placed, opacityState.text.opacity);
if (symbolInstance.placedRightTextIndex) {
- for (size_t i = 0; i < symbolInstance.rightJustifiedGlyphQuadsSize * 4; i++) {
- bucket.text.opacityVertices.emplace_back(opacityVertex);
- }
+ textOpacityVerticesSize += symbolInstance.rightJustifiedGlyphQuadsSize * 4;
PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedRightTextIndex];
placed.hidden = opacityState.isHidden();
}
if (symbolInstance.placedCenterTextIndex && !symbolInstance.singleLine) {
- for (size_t i = 0; i < symbolInstance.centerJustifiedGlyphQuadsSize * 4; i++) {
- bucket.text.opacityVertices.emplace_back(opacityVertex);
- }
+ textOpacityVerticesSize += symbolInstance.centerJustifiedGlyphQuadsSize * 4;
PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedCenterTextIndex];
placed.hidden = opacityState.isHidden();
}
if (symbolInstance.placedLeftTextIndex && !symbolInstance.singleLine) {
- for (size_t i = 0; i < symbolInstance.leftJustifiedGlyphQuadsSize * 4; i++) {
- bucket.text.opacityVertices.emplace_back(opacityVertex);
- }
+ textOpacityVerticesSize += symbolInstance.leftJustifiedGlyphQuadsSize * 4;
PlacedSymbol& placed = bucket.text.placedSymbols[*symbolInstance.placedLeftTextIndex];
placed.hidden = opacityState.isHidden();
}
if (symbolInstance.placedVerticalTextIndex) {
- for (size_t i = 0; i < symbolInstance.verticalGlyphQuadsSize * 4; i++) {
- bucket.text.opacityVertices.emplace_back(opacityVertex);
- }
+ textOpacityVerticesSize += symbolInstance.verticalGlyphQuadsSize * 4;
bucket.text.placedSymbols[*symbolInstance.placedVerticalTextIndex].hidden = opacityState.isHidden();
}
+ bucket.text.opacityVertices.extend(textOpacityVerticesSize, opacityVertex);
+
auto prevOffset = variableOffsets.find(symbolInstance.crossTileID);
if (prevOffset != variableOffsets.end()) {
markUsedJustification(bucket, prevOffset->second.anchor, symbolInstance);
}
}
if (symbolInstance.hasIcon) {
- auto opacityVertex = SymbolIconProgram::opacityVertex(opacityState.icon.placed, opacityState.icon.opacity);
- bucket.icon.opacityVertices.emplace_back(opacityVertex);
- bucket.icon.opacityVertices.emplace_back(opacityVertex);
- bucket.icon.opacityVertices.emplace_back(opacityVertex);
- bucket.icon.opacityVertices.emplace_back(opacityVertex);
+ const auto& opacityVertex = SymbolIconProgram::opacityVertex(opacityState.icon.placed, opacityState.icon.opacity);
+ bucket.icon.opacityVertices.extend(4, opacityVertex);
if (symbolInstance.placedIconIndex) {
bucket.icon.placedSymbols[*symbolInstance.placedIconIndex].hidden = opacityState.isHidden();
}
@@ -594,10 +586,8 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
if (feature.alongLine) {
return;
}
- auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, false, {});
- for (size_t i = 0; i < feature.boxes.size() * 4; i++) {
- bucket.collisionBox->dynamicVertices.emplace_back(dynamicVertex);
- }
+ const auto& dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, false, {});
+ bucket.collisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex);
};
auto updateCollisionTextBox = [this, &bucket, &symbolInstance, &state, variablePlacement, rotateWithMap, pitchWithMap](const auto& feature, const bool placed) {
@@ -629,10 +619,8 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
used = false;
}
}
- auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !used, shift);
- for (size_t i = 0; i < feature.boxes.size() * 4; i++) {
- bucket.collisionBox->dynamicVertices.emplace_back(dynamicVertex);
- }
+ const auto& dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !used, shift);
+ bucket.collisionBox->dynamicVertices.extend(feature.boxes.size() * 4, dynamicVertex);
};
auto updateCollisionCircles = [&](const auto& feature, const bool placed) {
@@ -640,11 +628,8 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
return;
}
for (const CollisionBox& box : feature.boxes) {
- auto dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !box.used, {});
- bucket.collisionCircle->dynamicVertices.emplace_back(dynamicVertex);
- bucket.collisionCircle->dynamicVertices.emplace_back(dynamicVertex);
- bucket.collisionCircle->dynamicVertices.emplace_back(dynamicVertex);
- bucket.collisionCircle->dynamicVertices.emplace_back(dynamicVertex);
+ const auto& dynamicVertex = CollisionBoxProgram::dynamicVertex(placed, !box.used, {});
+ bucket.collisionCircle->dynamicVertices.extend(4, dynamicVertex);
}
};
@@ -665,18 +650,29 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, const TransformState
}
}
+namespace {
+optional<size_t> justificationToIndex(style::TextJustifyType justify, const SymbolInstance& symbolInstance) {
+ switch(justify) {
+ case style::TextJustifyType::Right: return symbolInstance.placedRightTextIndex;
+ case style::TextJustifyType::Center: return symbolInstance.placedCenterTextIndex;
+ case style::TextJustifyType::Left: return symbolInstance.placedLeftTextIndex;
+ case style::TextJustifyType::Auto: break;
+ }
+ assert(false);
+ return nullopt;
+}
+
+const style::TextJustifyType justifyTypes[] = {style::TextJustifyType::Right, style::TextJustifyType::Center, style::TextJustifyType::Left};
+
+} // namespace
+
void Placement::markUsedJustification(SymbolBucket& bucket, style::TextVariableAnchorType placedAnchor, SymbolInstance& symbolInstance) {
- std::map<style::TextJustifyType, optional<size_t>> justificationToIndex {
- {style::TextJustifyType::Right, symbolInstance.placedRightTextIndex},
- {style::TextJustifyType::Center, symbolInstance.placedCenterTextIndex},
- {style::TextJustifyType::Left, symbolInstance.placedLeftTextIndex},
- };
- style::TextJustifyType justify = getAnchorJustification(placedAnchor);
- assert(justify == style::TextJustifyType::Right || justify == style::TextJustifyType::Center || justify == style::TextJustifyType::Left);
- const optional<size_t> autoIndex = justificationToIndex[justify];
-
- for (auto& pair : justificationToIndex) {
- const optional<size_t> index = pair.second;
+ style::TextJustifyType anchorJustify = getAnchorJustification(placedAnchor);
+ assert(anchorJustify != style::TextJustifyType::Auto);
+ const optional<size_t>& autoIndex = justificationToIndex(anchorJustify, symbolInstance);
+
+ for (auto& justify : justifyTypes) {
+ const optional<size_t> index = justificationToIndex(justify, symbolInstance);
if (index) {
assert(bucket.text.placedSymbols.size() > *index);
if (autoIndex && *index != *autoIndex) {
diff --git a/src/mbgl/tile/geojson_tile_data.hpp b/src/mbgl/tile/geojson_tile_data.hpp
index 3605af9690..5559965cd7 100644
--- a/src/mbgl/tile/geojson_tile_data.hpp
+++ b/src/mbgl/tile/geojson_tile_data.hpp
@@ -17,7 +17,7 @@ public:
return apply_visitor(ToFeatureType(), feature.geometry);
}
- PropertyMap getProperties() const override {
+ const PropertyMap& getProperties() const override {
return feature.properties;
}
@@ -25,15 +25,17 @@ public:
return feature.id;
}
- GeometryCollection getGeometries() const override {
- GeometryCollection geometry = apply_visitor(ToGeometryCollection(), feature.geometry);
+ const GeometryCollection& getGeometries() const override {
+ if (!geometry) {
+ geometry = apply_visitor(ToGeometryCollection(), feature.geometry);
- // https://github.com/mapbox/geojson-vt-cpp/issues/44
- if (getType() == FeatureType::Polygon) {
- geometry = fixupPolygons(geometry);
+ // https://github.com/mapbox/geojson-vt-cpp/issues/44
+ if (getType() == FeatureType::Polygon) {
+ geometry = fixupPolygons(*geometry);
+ }
}
- return geometry;
+ return *geometry;
}
optional<Value> getValue(const std::string& key) const override {
@@ -43,6 +45,8 @@ public:
}
return optional<Value>();
}
+
+ mutable optional<GeometryCollection> geometry;
};
class GeoJSONTileLayer : public GeometryTileLayer {
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 7f1bed49f4..a431ae423e 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -360,7 +360,7 @@ void GeometryTile::querySourceFeatures(
continue;
}
- result.push_back(convertFeature(*feature, id.canonical));
+ result.emplace_back(convertFeature(*feature, id.canonical));
}
}
}
diff --git a/src/mbgl/tile/geometry_tile_data.cpp b/src/mbgl/tile/geometry_tile_data.cpp
index 680f8d1497..5320df6893 100644
--- a/src/mbgl/tile/geometry_tile_data.cpp
+++ b/src/mbgl/tile/geometry_tile_data.cpp
@@ -57,32 +57,31 @@ std::vector<GeometryCollection> classifyRings(const GeometryCollection& rings) {
std::size_t len = rings.size();
if (len <= 1) {
- polygons.push_back(rings);
+ polygons.emplace_back(rings.clone());
return polygons;
}
GeometryCollection polygon;
int8_t ccw = 0;
- for (std::size_t i = 0; i < len; i++) {
- double area = signedArea(rings[i]);
-
- if (area == 0)
- continue;
+ for (const auto& ring : rings) {
+ double area = signedArea(ring);
+ if (area == 0) continue;
- if (ccw == 0)
+ if (ccw == 0) {
ccw = (area < 0 ? -1 : 1);
+ }
if (ccw == (area < 0 ? -1 : 1) && !polygon.empty()) {
- polygons.push_back(polygon);
- polygon.clear();
+ polygons.emplace_back(std::move(polygon));
}
- polygon.push_back(rings[i]);
+ polygon.emplace_back(ring);
}
- if (!polygon.empty())
- polygons.push_back(polygon);
+ if (!polygon.empty()) {
+ polygons.emplace_back(std::move(polygon));
+ }
return polygons;
}
@@ -112,7 +111,7 @@ static Feature::geometry_type convertGeometry(const GeometryTileFeature& geometr
);
};
- GeometryCollection geometries = geometryTileFeature.getGeometries();
+ const GeometryCollection& geometries = geometryTileFeature.getGeometries();
switch (geometryTileFeature.getType()) {
case FeatureType::Unknown: {
@@ -180,4 +179,14 @@ Feature convertFeature(const GeometryTileFeature& geometryTileFeature, const Can
return feature;
}
+const PropertyMap& GeometryTileFeature::getProperties() const {
+ static const PropertyMap dummy;
+ return dummy;
+}
+
+const GeometryCollection& GeometryTileFeature::getGeometries() const {
+ static const GeometryCollection dummy;
+ return dummy;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/tile/geometry_tile_data.hpp b/src/mbgl/tile/geometry_tile_data.hpp
index 6ce67a532e..5d43a68388 100644
--- a/src/mbgl/tile/geometry_tile_data.hpp
+++ b/src/mbgl/tile/geometry_tile_data.hpp
@@ -35,6 +35,13 @@ public:
GeometryCollection(Args&&... args) : std::vector<GeometryCoordinates>(std::forward<Args>(args)...) {}
GeometryCollection(std::initializer_list<GeometryCoordinates> args)
: std::vector<GeometryCoordinates>(std::move(args)) {}
+ GeometryCollection(GeometryCollection&&) = default;
+ GeometryCollection& operator=(GeometryCollection&&) = default;
+
+ GeometryCollection clone() const { return GeometryCollection(*this); }
+
+private:
+ GeometryCollection(const GeometryCollection&) = default;
};
class GeometryTileFeature {
@@ -42,9 +49,9 @@ public:
virtual ~GeometryTileFeature() = default;
virtual FeatureType getType() const = 0;
virtual optional<Value> getValue(const std::string& key) const = 0;
- virtual PropertyMap getProperties() const { return PropertyMap(); }
+ virtual const PropertyMap& getProperties() const;
virtual FeatureIdentifier getID() const { return NullValue {}; }
- virtual GeometryCollection getGeometries() const = 0;
+ virtual const GeometryCollection& getGeometries() const;
};
class GeometryTileLayer {
@@ -90,31 +97,16 @@ struct ToGeometryCollection {
return { { geom } };
}
GeometryCollection operator()(const mapbox::geometry::multi_point<int16_t>& geom) const {
- GeometryCoordinates coordinates;
- coordinates.reserve(geom.size());
- for (const auto& point : geom) {
- coordinates.emplace_back(point);
- }
- return { coordinates };
+ return { geom };
}
GeometryCollection operator()(const mapbox::geometry::line_string<int16_t>& geom) const {
- GeometryCoordinates coordinates;
- coordinates.reserve(geom.size());
- for (const auto& point : geom) {
- coordinates.emplace_back(point);
- }
- return { coordinates };
+ return { geom };
}
GeometryCollection operator()(const mapbox::geometry::multi_line_string<int16_t>& geom) const {
GeometryCollection collection;
collection.reserve(geom.size());
for (const auto& ring : geom) {
- GeometryCoordinates coordinates;
- coordinates.reserve(ring.size());
- for (const auto& point : ring) {
- coordinates.emplace_back(point);
- }
- collection.push_back(std::move(coordinates));
+ collection.emplace_back(ring);
}
return collection;
}
@@ -122,25 +114,15 @@ struct ToGeometryCollection {
GeometryCollection collection;
collection.reserve(geom.size());
for (const auto& ring : geom) {
- GeometryCoordinates coordinates;
- coordinates.reserve(ring.size());
- for (const auto& point : ring) {
- coordinates.emplace_back(point);
- }
- collection.push_back(std::move(coordinates));
+ collection.emplace_back(ring);
}
return collection;
}
GeometryCollection operator()(const mapbox::geometry::multi_polygon<int16_t>& geom) const {
GeometryCollection collection;
- for (auto& polygon : geom) {
- for (auto& ring : polygon) {
- GeometryCoordinates coordinates;
- coordinates.reserve(ring.size());
- for (auto& point : ring) {
- coordinates.emplace_back(point);
- }
- collection.push_back(std::move(coordinates));
+ for (const auto& polygon : geom) {
+ for (const auto& ring : polygon) {
+ collection.emplace_back(ring);
}
}
return collection;
diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp
index a69825d346..f4d57e5bfc 100644
--- a/src/mbgl/tile/geometry_tile_worker.cpp
+++ b/src/mbgl/tile/geometry_tile_worker.cpp
@@ -382,7 +382,7 @@ void GeometryTileWorker::parse() {
if (!filter(expression::EvaluationContext { static_cast<float>(this->id.overscaledZ), feature.get() }))
continue;
- GeometryCollection geometries = feature->getGeometries();
+ const GeometryCollection& geometries = feature->getGeometries();
bucket->addFeature(*feature, geometries, {}, PatternLayerMap ());
featureIndex->insert(geometries, i, sourceLayerID, leaderImpl.id);
}
diff --git a/src/mbgl/tile/vector_tile_data.cpp b/src/mbgl/tile/vector_tile_data.cpp
index 2d47515e0f..d53f1deba6 100644
--- a/src/mbgl/tile/vector_tile_data.cpp
+++ b/src/mbgl/tile/vector_tile_data.cpp
@@ -26,22 +26,26 @@ optional<Value> VectorTileFeature::getValue(const std::string& key) const {
return value->is<NullValue>() ? nullopt : std::move(value);
}
-std::unordered_map<std::string, Value> VectorTileFeature::getProperties() const {
- return feature.getProperties();
+const PropertyMap& VectorTileFeature::getProperties() const {
+ if (!properties) {
+ properties = feature.getProperties();
+ }
+ return *properties;
}
FeatureIdentifier VectorTileFeature::getID() const {
return feature.getID();
}
-GeometryCollection VectorTileFeature::getGeometries() const {
- const float scale = float(util::EXTENT) / feature.getExtent();
- auto lines = feature.getGeometries<GeometryCollection>(scale);
- if (feature.getVersion() >= 2 || feature.getType() != mapbox::vector_tile::GeomType::POLYGON) {
- return lines;
- } else {
- return fixupPolygons(lines);
+const GeometryCollection& VectorTileFeature::getGeometries() const {
+ if (!lines) {
+ const float scale = float(util::EXTENT) / feature.getExtent();
+ lines = feature.getGeometries<GeometryCollection>(scale);
+ if (feature.getVersion() < 2 && feature.getType() == mapbox::vector_tile::GeomType::POLYGON) {
+ lines = fixupPolygons(*lines);
+ }
}
+ return *lines;
}
VectorTileLayer::VectorTileLayer(std::shared_ptr<const std::string> data_,
diff --git a/src/mbgl/tile/vector_tile_data.hpp b/src/mbgl/tile/vector_tile_data.hpp
index 7c95121a37..f5086936f8 100644
--- a/src/mbgl/tile/vector_tile_data.hpp
+++ b/src/mbgl/tile/vector_tile_data.hpp
@@ -15,12 +15,14 @@ public:
FeatureType getType() const override;
optional<Value> getValue(const std::string& key) const override;
- std::unordered_map<std::string, Value> getProperties() const override;
+ const PropertyMap& getProperties() const override;
FeatureIdentifier getID() const override;
- GeometryCollection getGeometries() const override;
+ const GeometryCollection& getGeometries() const override;
private:
mapbox::vector_tile::feature feature;
+ mutable optional<GeometryCollection> lines;
+ mutable optional<PropertyMap> properties;
};
class VectorTileLayer : public GeometryTileLayer {
diff --git a/src/mbgl/util/grid_index.cpp b/src/mbgl/util/grid_index.cpp
index f6b59b1bac..f33e889ddb 100644
--- a/src/mbgl/util/grid_index.cpp
+++ b/src/mbgl/util/grid_index.cpp
@@ -9,14 +9,16 @@ namespace mbgl {
template <class T>
-GridIndex<T>::GridIndex(const float width_, const float height_, const int16_t cellSize_) :
+GridIndex<T>::GridIndex(const float width_, const float height_, const uint32_t cellSize_) :
width(width_),
height(height_),
- xCellCount(std::ceil(width_ / cellSize_)),
- yCellCount(std::ceil(height_ / cellSize_)),
- xScale(xCellCount / width_),
- yScale(yCellCount / height_)
+ xCellCount(std::ceil(width / cellSize_)),
+ yCellCount(std::ceil(height / cellSize_)),
+ xScale(xCellCount / width),
+ yScale(yCellCount / height)
{
+ assert(width > 0.0f);
+ assert(height > 0.0f);
boxCells.resize(xCellCount * yCellCount);
circleCells.resize(xCellCount * yCellCount);
}
@@ -30,7 +32,7 @@ void GridIndex<T>::insert(T&& t, const BBox& bbox) {
auto cx2 = convertToXCellCoord(bbox.max.x);
auto cy2 = convertToYCellCoord(bbox.max.y);
- int16_t x, y, cellIndex;
+ std::size_t x, y, cellIndex;
for (x = cx1; x <= cx2; ++x) {
for (y = cy1; y <= cy2; ++y) {
cellIndex = xCellCount * y + x;
@@ -50,7 +52,7 @@ void GridIndex<T>::insert(T&& t, const BCircle& bcircle) {
auto cx2 = convertToXCellCoord(bcircle.center.x + bcircle.radius);
auto cy2 = convertToYCellCoord(bcircle.center.y + bcircle.radius);
- int16_t x, y, cellIndex;
+ std::size_t x, y, cellIndex;
for (x = cx1; x <= cx2; ++x) {
for (y = cy1; y <= cy2; ++y) {
cellIndex = xCellCount * y + x;
@@ -151,7 +153,7 @@ void GridIndex<T>::query(const BBox& queryBBox, std::function<bool (const T&, co
auto cx2 = convertToXCellCoord(queryBBox.max.x);
auto cy2 = convertToYCellCoord(queryBBox.max.y);
- int16_t x, y, cellIndex;
+ std::size_t x, y, cellIndex;
for (x = cx1; x <= cx2; ++x) {
for (y = cy1; y <= cy2; ++y) {
cellIndex = xCellCount * y + x;
@@ -214,7 +216,7 @@ void GridIndex<T>::query(const BCircle& queryBCircle, std::function<bool (const
auto cx2 = convertToXCellCoord(queryBCircle.center.x + queryBCircle.radius);
auto cy2 = convertToYCellCoord(queryBCircle.center.y + queryBCircle.radius);
- int16_t x, y, cellIndex;
+ std::size_t x, y, cellIndex;
for (x = cx1; x <= cx2; ++x) {
for (y = cy1; y <= cy2; ++y) {
cellIndex = xCellCount * y + x;
@@ -252,12 +254,12 @@ void GridIndex<T>::query(const BCircle& queryBCircle, std::function<bool (const
}
template <class T>
-int16_t GridIndex<T>::convertToXCellCoord(const float x) const {
+std::size_t GridIndex<T>::convertToXCellCoord(const float x) const {
return util::max(0.0, util::min(xCellCount - 1.0, std::floor(x * xScale)));
}
template <class T>
-int16_t GridIndex<T>::convertToYCellCoord(const float y) const {
+std::size_t GridIndex<T>::convertToYCellCoord(const float y) const {
return util::max(0.0, util::min(yCellCount - 1.0, std::floor(y * yScale)));
}
diff --git a/src/mbgl/util/grid_index.hpp b/src/mbgl/util/grid_index.hpp
index 4c2d7dccc8..cb38023e59 100644
--- a/src/mbgl/util/grid_index.hpp
+++ b/src/mbgl/util/grid_index.hpp
@@ -57,7 +57,7 @@ template <class T>
class GridIndex {
public:
- GridIndex(const float width_, const float height_, const int16_t cellSize_);
+ GridIndex(const float width_, const float height_, const uint32_t cellSize_);
using BBox = mapbox::geometry::box<float>;
using BCircle = geometry::circle<float>;
@@ -81,8 +81,8 @@ private:
void query(const BBox&, std::function<bool (const T&, const BBox&)>) const;
void query(const BCircle&, std::function<bool (const T&, const BBox&)>) const;
- int16_t convertToXCellCoord(const float x) const;
- int16_t convertToYCellCoord(const float y) const;
+ std::size_t convertToXCellCoord(const float x) const;
+ std::size_t convertToYCellCoord(const float y) const;
bool boxesCollide(const BBox&, const BBox&) const;
bool circlesCollide(const BCircle&, const BCircle&) const;
@@ -91,8 +91,8 @@ private:
const float width;
const float height;
- const int16_t xCellCount;
- const int16_t yCellCount;
+ const std::size_t xCellCount;
+ const std::size_t yCellCount;
const double xScale;
const double yScale;