diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2015-03-09 13:22:52 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2015-03-09 18:32:08 -0700 |
commit | 50b5c1565366e223bf657d68ddac70b25ad13bcf (patch) | |
tree | e9b0c0d3e7eb42b595c44db5bd3fd612a1a1c558 /src | |
parent | 2d8bf823fca8daede324b6b345d2fecd224715ee (diff) | |
download | qtlocation-mapboxgl-50b5c1565366e223bf657d68ddac70b25ad13bcf.tar.gz |
Rework GeometryTile* interface
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/map/geometry_tile.cpp | 24 | ||||
-rw-r--r-- | src/mbgl/map/geometry_tile.hpp | 68 | ||||
-rw-r--r-- | src/mbgl/map/tile_parser.cpp | 40 | ||||
-rw-r--r-- | src/mbgl/map/tile_parser.hpp | 11 | ||||
-rw-r--r-- | src/mbgl/map/vector_tile.cpp | 154 | ||||
-rw-r--r-- | src/mbgl/map/vector_tile.hpp | 62 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.cpp | 26 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.hpp | 16 | ||||
-rw-r--r-- | src/mbgl/util/token.hpp | 8 |
9 files changed, 112 insertions, 297 deletions
diff --git a/src/mbgl/map/geometry_tile.cpp b/src/mbgl/map/geometry_tile.cpp index 2800712ef2..f87468914c 100644 --- a/src/mbgl/map/geometry_tile.cpp +++ b/src/mbgl/map/geometry_tile.cpp @@ -1,24 +1,16 @@ #include <mbgl/map/geometry_tile.hpp> #include <mbgl/style/filter_expression_private.hpp> -#include <iostream> +namespace mbgl { -using namespace mbgl; - -std::ostream& mbgl::operator<<(std::ostream& os, const GeometryFeatureType& type) { - switch (type) { - case GeometryFeatureType::Unknown: return os << "Unknown"; - case GeometryFeatureType::Point: return os << "Point"; - case GeometryFeatureType::LineString: return os << "LineString"; - case GeometryFeatureType::Polygon: return os << "Polygon"; - default: return os << "Invalid"; +mapbox::util::optional<Value> GeometryTileFeatureExtractor::getValue(const std::string& key) const { + if (key == "$type") { + return Value(uint64_t(feature.getType())); } + + return feature.getValue(key); } -std::ostream& mbgl::operator<<(std::ostream& os, const GeometryTileFeature& feature) { - os << "Feature(" << feature.getID() << "): " << feature.getType() << std::endl; - for (const auto& prop : feature.getProperties()) { - os << " - " << prop.first << ": " << &prop.second << std::endl; - } - return os; +template bool evaluate(const FilterExpression&, const GeometryTileFeatureExtractor&); + } diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index 045c298428..40a820274b 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -8,9 +8,9 @@ #include <mbgl/util/ptr.hpp> #include <mbgl/util/variant.hpp> #include <mbgl/util/vec.hpp> +#include <mbgl/util/noncopyable.hpp> #include <cstdint> -#include <iosfwd> #include <map> #include <string> #include <type_traits> @@ -34,69 +34,33 @@ using Geometry = mapbox::util::variant<std::false_type, GeometryPoint, GeometryL typedef std::vector<Geometry> GeometryCollection; -std::ostream& operator<<(std::ostream&, const GeometryFeatureType& type); - -class GeometryTileLayer; - -class GeometryTileFeature { +class GeometryTileFeature : public mbgl::util::noncopyable { public: - virtual uint64_t getID() const = 0; virtual GeometryFeatureType getType() const = 0; - virtual std::map<std::string, Value> getProperties() const = 0; - virtual GeometryCollection nextGeometry() = 0; + virtual mapbox::util::optional<Value> getValue(const std::string& key) const = 0; + virtual GeometryCollection getGeometries() const = 0; }; -std::ostream& operator<<(std::ostream&, const GeometryTileFeature& feature); - -template <typename Tags> -class GeometryTileTagExtractor { -public: - GeometryTileTagExtractor(const GeometryTileLayer&); - - inline void setTags(const Tags& tags_) { tags = tags_; } - virtual mapbox::util::optional<Value> getValue(const std::string &key) const; - - inline void setType(GeometryFeatureType type_) { type = type_; } - inline GeometryFeatureType getType() const { return type; } - +class GeometryTileLayer : public mbgl::util::noncopyable { public: - GeometryFeatureType type = GeometryFeatureType::Unknown; - Tags tags; - -protected: - const GeometryTileLayer& layer; + virtual std::size_t featureCount() const = 0; + virtual const util::ptr<const GeometryTileFeature> feature(std::size_t i) const = 0; }; -class GeometryFilteredTileLayer { +class GeometryTile : public mbgl::util::noncopyable { public: - class iterator { - public: - void operator++(); - bool operator!=(const iterator&) const; - GeometryTileFeature& operator*() const; - }; - -public: - virtual iterator begin() const = 0; - virtual iterator end() const = 0; + virtual const util::ptr<const GeometryTileLayer> getLayer(const std::string&) const = 0; }; -std::ostream& operator<<(std::ostream&, const PositionedGlyph&); - -class GeometryTileLayer { +class GeometryTileFeatureExtractor { public: - virtual const std::string& getName() const = 0; - virtual uint32_t getExtent() const = 0; - virtual const std::vector<std::string>& getKeys() const = 0; - virtual const std::unordered_map<std::string, uint32_t>& getKeyIndex() const = 0; - virtual const std::vector<Value>& getValues() const = 0; - virtual const std::map<std::string, std::map<Value, Shaping>>& getShaping() const = 0; - virtual util::ptr<GeometryFilteredTileLayer> createFilteredTileLayer(const FilterExpression&) const = 0; -}; + GeometryTileFeatureExtractor(const GeometryTileFeature& feature_) + : feature(feature_) {} -class GeometryTile { -public: - virtual const util::ptr<const GeometryTileLayer> getLayer(const std::string&) const = 0; + mapbox::util::optional<Value> getValue(const std::string& key) const; + +private: + const GeometryTileFeature& feature; }; } diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp index be5b901369..48f5b1405f 100644 --- a/src/mbgl/map/tile_parser.cpp +++ b/src/mbgl/map/tile_parser.cpp @@ -187,14 +187,14 @@ std::unique_ptr<Bucket> TileParser::createBucket(const StyleBucket &bucketDesc) if (tile.id.z >= std::ceil(bucketDesc.max_zoom)) return nullptr; if (bucketDesc.visibility == mbgl::VisibilityType::None) return nullptr; - const util::ptr<const GeometryTileLayer> layer = vectorTile.getLayer(bucketDesc.source_layer); - if (layer.get() != nullptr) { + auto layer = vectorTile.getLayer(bucketDesc.source_layer); + if (layer) { if (bucketDesc.type == StyleLayerType::Fill) { - return createFillBucket(layer, bucketDesc); + return createFillBucket(*layer, bucketDesc); } else if (bucketDesc.type == StyleLayerType::Line) { - return createLineBucket(layer, bucketDesc); + return createLineBucket(*layer, bucketDesc); } else if (bucketDesc.type == StyleLayerType::Symbol) { - return createSymbolBucket(layer, bucketDesc); + return createSymbolBucket(*layer, bucketDesc); } else if (bucketDesc.type == StyleLayerType::Raster) { return nullptr; } else { @@ -212,25 +212,23 @@ std::unique_ptr<Bucket> TileParser::createBucket(const StyleBucket &bucketDesc) } template <class Bucket> -void TileParser::addBucketGeometries(Bucket& bucket, const util::ptr<const GeometryTileLayer> layer, const FilterExpression &filter) { - - util::ptr<GeometryFilteredTileLayer> filtered_layer = layer->createFilteredTileLayer(filter); - - for (auto feature_it = filtered_layer->begin(); feature_it != filtered_layer->end(); ++feature_it) { +void TileParser::addBucketGeometries(Bucket& bucket, const GeometryTileLayer& layer, const FilterExpression &filter) { + for (std::size_t i = 0; i < layer.featureCount(); i++) { + auto feature = layer.feature(i); if (obsolete()) return; - GeometryCollection geometry = (*feature_it).nextGeometry(); - while (geometry.size()) { - bucket->addGeometry(geometry); - geometry = (*feature_it).nextGeometry(); - } + GeometryTileFeatureExtractor extractor(*feature); + if (!evaluate(filter, extractor)) + continue; + + bucket->addGeometry(feature->getGeometries()); } } -std::unique_ptr<Bucket> TileParser::createFillBucket(const util::ptr<const GeometryTileLayer> layer, - const StyleBucket &bucket_desc) { +std::unique_ptr<Bucket> TileParser::createFillBucket(const GeometryTileLayer& layer, + const StyleBucket& bucket_desc) { auto fill = parseStyleLayoutFill(bucket_desc, tile.id.z); auto bucket = util::make_unique<FillBucket>(std::move(fill), tile.fillVertexBuffer, @@ -240,8 +238,8 @@ std::unique_ptr<Bucket> TileParser::createFillBucket(const util::ptr<const Geome return obsolete() ? nullptr : std::move(bucket); } -std::unique_ptr<Bucket> TileParser::createLineBucket(const util::ptr<const GeometryTileLayer> layer, - const StyleBucket &bucket_desc) { +std::unique_ptr<Bucket> TileParser::createLineBucket(const GeometryTileLayer& layer, + const StyleBucket& bucket_desc) { auto line = parseStyleLayoutLine(bucket_desc, tile.id.z); auto bucket = util::make_unique<LineBucket>(std::move(line), tile.lineVertexBuffer, @@ -251,8 +249,8 @@ std::unique_ptr<Bucket> TileParser::createLineBucket(const util::ptr<const Geome return obsolete() ? nullptr : std::move(bucket); } -std::unique_ptr<Bucket> TileParser::createSymbolBucket(const util::ptr<const GeometryTileLayer> layer, - const StyleBucket &bucket_desc) { +std::unique_ptr<Bucket> TileParser::createSymbolBucket(const GeometryTileLayer& layer, + const StyleBucket& bucket_desc) { auto symbol = parseStyleLayoutSymbol(bucket_desc, tile.id.z); auto bucket = util::make_unique<SymbolBucket>(std::move(symbol), *collision); bucket->addFeatures( diff --git a/src/mbgl/map/tile_parser.hpp b/src/mbgl/map/tile_parser.hpp index 90a9037fd3..e7c05e1b1e 100644 --- a/src/mbgl/map/tile_parser.hpp +++ b/src/mbgl/map/tile_parser.hpp @@ -52,12 +52,13 @@ private: bool obsolete() const; void parseStyleLayers(util::ptr<const StyleLayerGroup> group); - std::unique_ptr<Bucket> createBucket(const StyleBucket& bucketDesc); - std::unique_ptr<Bucket> createFillBucket(const util::ptr<const GeometryTileLayer> layer, const StyleBucket& bucketDesc); - std::unique_ptr<Bucket> createLineBucket(const util::ptr<const GeometryTileLayer> layer, const StyleBucket& bucketDesc); - std::unique_ptr<Bucket> createSymbolBucket(const util::ptr<const GeometryTileLayer> layer, const StyleBucket& bucketDesc); + std::unique_ptr<Bucket> createBucket(const StyleBucket&); + std::unique_ptr<Bucket> createFillBucket(const GeometryTileLayer&, const StyleBucket&); + std::unique_ptr<Bucket> createLineBucket(const GeometryTileLayer&, const StyleBucket&); + std::unique_ptr<Bucket> createSymbolBucket(const GeometryTileLayer&, const StyleBucket&); - template <class Bucket> void addBucketGeometries(Bucket& bucket, const util::ptr<const GeometryTileLayer> layer, const FilterExpression& filter); + template <class Bucket> + void addBucketGeometries(Bucket&, const GeometryTileLayer&, const FilterExpression&); private: const VectorTile vectorTile; diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 6eb0704a64..7f472400ae 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -8,7 +8,7 @@ using namespace mbgl; -VectorTileFeature::VectorTileFeature(pbf feature_pbf, const GeometryTileLayer& layer) { +VectorTileFeature::VectorTileFeature(pbf feature_pbf, const VectorTileLayer& layer) { while (feature_pbf.next()) { if (feature_pbf.tag == 1) { // id id = feature_pbf.varint<uint64_t>(); @@ -18,17 +18,17 @@ VectorTileFeature::VectorTileFeature(pbf feature_pbf, const GeometryTileLayer& l while (tags) { uint32_t tag_key = tags.varint(); - if (layer.getKeys().size() <= tag_key) { + if (layer.keys.size() <= tag_key) { throw std::runtime_error("feature referenced out of range key"); } if (tags) { uint32_t tag_val = tags.varint(); - if (layer.getValues().size() <= tag_val) { + if (layer.values.size() <= tag_val) { throw std::runtime_error("feature referenced out of range value"); } - properties.emplace(layer.getKeys()[tag_key], layer.getValues()[tag_val]); + properties.emplace(layer.keys[tag_key], layer.values[tag_val]); } else { throw std::runtime_error("uneven number of feature tag ids"); } @@ -43,12 +43,20 @@ VectorTileFeature::VectorTileFeature(pbf feature_pbf, const GeometryTileLayer& l } } -GeometryCollection VectorTileFeature::nextGeometry() { +mapbox::util::optional<Value> VectorTileFeature::getValue(const std::string& key) const { + auto it = properties.find(key); + if (it != properties.end()) { + return it->second; + } + return mapbox::util::optional<Value>(); +} +GeometryCollection VectorTileFeature::getGeometries() const { GeometryCollection result; + pbf geom_pbf = geometry_pbf; - while (geometry_pbf.next(4)) { // geometry - pbf current_geometry_pbf = geometry_pbf.message(); + while (geom_pbf.next(4)) { // geometry + pbf current_geometry_pbf = geom_pbf.message(); PBFGeometry current_geometry(current_geometry_pbf); PBFGeometry::command cmd; int32_t x, y; @@ -96,44 +104,33 @@ GeometryCollection VectorTileFeature::nextGeometry() { return std::move(result); } -bool VectorTileFeature::operator==(const VectorTileFeature& other) const { - return (geometry_pbf == other.geometry_pbf); -} - VectorTile::VectorTile(pbf tile_pbf) { while (tile_pbf.next()) { if (tile_pbf.tag == 3) { // layer - VectorTileLayer layer(tile_pbf.message()); - layers.emplace(layer.getName(), std::forward<VectorTileLayer>(layer)); + util::ptr<VectorTileLayer> layer = std::make_shared<VectorTileLayer>(tile_pbf.message()); + layers.emplace(layer->name, layer); } else { tile_pbf.skip(); } } } -VectorTile& VectorTile::operator=(VectorTile&& other) { - if (this != &other) { - layers.swap(other.layers); - } - return *this; -} - const util::ptr<const GeometryTileLayer> VectorTile::getLayer(const std::string& name) const { auto layer_it = layers.find(name); if (layer_it != layers.end()) { - return std::make_shared<const VectorTileLayer>(layer_it->second); + return layer_it->second; } return nullptr; } -VectorTileLayer::VectorTileLayer(pbf layer_pbf) - : feature_pbf(layer_pbf) { +VectorTileLayer::VectorTileLayer(pbf layer_pbf) { while (layer_pbf.next()) { if (layer_pbf.tag == 1) { // name name = layer_pbf.string(); + } else if (layer_pbf.tag == 2) { // feature + features.push_back(layer_pbf.message()); } else if (layer_pbf.tag == 3) { // keys keys.emplace_back(layer_pbf.string()); - key_index.emplace(keys.back(), keys.size() - 1); } else if (layer_pbf.tag == 4) { // values values.emplace_back(std::move(parseValue(layer_pbf.message()))); } else if (layer_pbf.tag == 5) { // extent @@ -144,111 +141,6 @@ VectorTileLayer::VectorTileLayer(pbf layer_pbf) } } -util::ptr<GeometryFilteredTileLayer> VectorTileLayer::createFilteredTileLayer(const FilterExpression& filterExpression) const { - return std::make_shared<FilteredVectorTileLayer>(*this, filterExpression); -} - -FilteredVectorTileLayer::FilteredVectorTileLayer(const VectorTileLayer& layer_, const FilterExpression& filterExpression_) - : layer(layer_), - filterExpression(filterExpression_) {} - -GeometryFilteredTileLayer::iterator FilteredVectorTileLayer::begin() const { - return iterator(*this, layer.feature_pbf); -} - -GeometryFilteredTileLayer::iterator FilteredVectorTileLayer::end() const { - return iterator(*this, pbf(layer.feature_pbf.end, 0)); -} - -FilteredVectorTileLayer::iterator::iterator(const FilteredVectorTileLayer& parent_, const pbf& feature_pbf_) - : parent(parent_), - feature(VectorTileFeature(pbf(), parent_.layer)), - feature_pbf(feature_pbf_) { - operator++(); -} - -template <> -GeometryTileTagExtractor<pbf>::GeometryTileTagExtractor(const GeometryTileLayer& layer_) - : layer(layer_) {} - -template <> -mapbox::util::optional<Value> GeometryTileTagExtractor<pbf>::getValue(const std::string& key) const { - if (key == "$type") { - return Value(uint64_t(type)); - } - - mapbox::util::optional<Value> value; - - auto field_it = layer.getKeyIndex().find(key); - if (field_it != layer.getKeyIndex().end()) { - const uint32_t filter_key = field_it->second; - - // Now loop through all the key/value pair tags. - // tags are packed varints. They should have an even length. - pbf tags_pbf_ = tags; - uint32_t tag_key, tag_val; - while (tags_pbf_) { - tag_key = tags_pbf_.varint(); - if (!tags_pbf_) { - // This should not happen; otherwise the vector tile is invalid. - fprintf(stderr, "[WARNING] uneven number of feature tag ids\n"); - return value; - } - // Note: We need to run this command in all cases, even if the keys don't match. - tag_val = tags_pbf_.varint(); - - if (tag_key == filter_key) { - if (layer.getValues().size() > tag_val) { - value = layer.getValues()[tag_val]; - } else { - fprintf(stderr, "[WARNING] feature references out of range value\n"); - break; - } - } - } - } - - return value; -} - -template bool mbgl::evaluate(const FilterExpression&, const GeometryTileTagExtractor<pbf>&); - -void FilteredVectorTileLayer::iterator::operator++() { - valid = false; - - const FilterExpression &expression = parent.filterExpression; - - while (feature_pbf.next(2)) { // feature - feature = VectorTileFeature(feature_pbf.message(), parent.layer); - pbf feature_pbf_ = feature_pbf.message(); - - GeometryTileTagExtractor<pbf> extractor(parent.layer); - - // Retrieve the basic information - while (feature_pbf_.next()) { - if (feature_pbf_.tag == 2) { // tags - extractor.setTags(feature_pbf_.message()); - } else if (feature_pbf_.tag == 3) { // geometry type - extractor.setType(GeometryFeatureType(feature_pbf_.varint())); - } else { - feature_pbf_.skip(); - } - } - - if (evaluate(expression, extractor)) { - valid = true; - return; // data loop - } else { - valid = false; - } - } -} - -bool FilteredVectorTileLayer::iterator::operator!=(const iterator& other) const { - return !(feature == other.feature); -} - -VectorTileFeature& FilteredVectorTileLayer::iterator::operator*() const { - VectorTileFeature* f = const_cast<VectorTileFeature *>(&feature); - return *f; +const util::ptr<const GeometryTileFeature> VectorTileLayer::feature(std::size_t i) const { + return std::make_shared<VectorTileFeature>(features.at(i), *this); } diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index c99a4a3fb7..b929835692 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -2,23 +2,19 @@ #define MBGL_MAP_VECTOR_TILE #include <mbgl/map/geometry_tile.hpp> -#include <mbgl/style/filter_expression.hpp> -#include <mbgl/util/ptr.hpp> +#include <mbgl/util/pbf.hpp> namespace mbgl { class VectorTileLayer; -struct pbf; class VectorTileFeature : public GeometryTileFeature { public: - VectorTileFeature(pbf, const GeometryTileLayer&); + VectorTileFeature(pbf, const VectorTileLayer&); - virtual inline uint64_t getID() const { return id; }; - virtual inline GeometryFeatureType getType() const { return type; } - virtual inline std::map<std::string, Value> getProperties() const { return properties; } - virtual GeometryCollection nextGeometry(); - bool operator==(const VectorTileFeature&) const; + virtual GeometryFeatureType getType() const { return type; } + virtual mapbox::util::optional<Value> getValue(const std::string&) const; + virtual GeometryCollection getGeometries() const; private: uint64_t id = 0; @@ -27,66 +23,32 @@ private: pbf geometry_pbf; }; -class FilteredVectorTileLayer : public GeometryFilteredTileLayer { -public: - class iterator : public GeometryFilteredTileLayer::iterator { - public: - iterator(const FilteredVectorTileLayer&, const pbf&); - void operator++(); - bool operator!=(const iterator&) const; - VectorTileFeature& operator*() const; - - private: - const FilteredVectorTileLayer& parent; - bool valid = false; - VectorTileFeature feature; - pbf feature_pbf; - }; - -public: - FilteredVectorTileLayer(const VectorTileLayer&, const FilterExpression&); - - virtual GeometryFilteredTileLayer::iterator begin() const; - virtual GeometryFilteredTileLayer::iterator end() const; - -private: - const VectorTileLayer& layer; - const FilterExpression& filterExpression; -}; - class VectorTileLayer : public GeometryTileLayer { - friend class FilteredVectorTileLayer; public: VectorTileLayer(pbf); - virtual inline const std::string& getName() const { return name; } - virtual inline uint32_t getExtent() const { return extent; } - virtual inline const std::vector<std::string>& getKeys() const { return keys; } - virtual inline const std::unordered_map<std::string, uint32_t>& getKeyIndex() const { return key_index; } - virtual inline const std::vector<Value>& getValues() const { return values; } - virtual inline const std::map<std::string, std::map<Value, Shaping>>& getShaping() const { return shaping; } - - virtual util::ptr<GeometryFilteredTileLayer> createFilteredTileLayer(const FilterExpression&) const; + virtual std::size_t featureCount() const { return features.size(); } + virtual const util::ptr<const GeometryTileFeature> feature(std::size_t) const; private: + friend class VectorTile; + friend class VectorTileFeature; + std::string name; uint32_t extent = 4096; std::vector<std::string> keys; - std::unordered_map<std::string, uint32_t> key_index; std::vector<Value> values; - std::map<std::string, std::map<Value, Shaping>> shaping; - const pbf feature_pbf; + std::vector<pbf> features; }; class VectorTile : public GeometryTile { public: VectorTile(pbf); - VectorTile& operator=(VectorTile&&); virtual const util::ptr<const GeometryTileLayer> getLayer(const std::string&) const; private: - std::map<std::string, const VectorTileLayer> layers; + std::map<std::string, util::ptr<const GeometryTileLayer>> layers; }; } diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 631fcaf5d5..1d94714f76 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -1,6 +1,5 @@ #include <mbgl/renderer/symbol_bucket.hpp> #include <mbgl/map/geometry_tile.hpp> -#include <mbgl/map/vector_tile.hpp> #include <mbgl/style/style_layout.hpp> #include <mbgl/geometry/text_buffer.hpp> #include <mbgl/geometry/icon_buffer.hpp> @@ -49,8 +48,8 @@ void SymbolBucket::addGlyphsToAtlas(uint64_t tileid, const std::string stackname glyphAtlas.addGlyphs(tileid, text, stackname, fontStack,face); } -std::vector<SymbolFeature> SymbolBucket::processFeatures(const util::ptr<const GeometryTileLayer> layer, - const FilterExpression &filter, +std::vector<SymbolFeature> SymbolBucket::processFeatures(const GeometryTileLayer& layer, + const FilterExpression& filter, GlyphStore &glyphStore, const Sprite &sprite) { auto &layout = *styleLayout; @@ -66,14 +65,22 @@ std::vector<SymbolFeature> SymbolBucket::processFeatures(const util::ptr<const G // Determine and load glyph ranges std::set<GlyphRange> ranges; - util::ptr<GeometryFilteredTileLayer> filtered_layer = layer->createFilteredTileLayer(filter); + for (std::size_t i = 0; i < layer.featureCount(); i++) { + auto feature = layer.feature(i); - for (auto feature_it = filtered_layer->begin(); feature_it != filtered_layer->end(); ++feature_it) { + GeometryTileFeatureExtractor extractor(*feature); + if (!evaluate(filter, extractor)) + continue; SymbolFeature ft; + auto getValue = [&feature](const std::string& key) -> std::string { + auto value = feature->getValue(key); + return value ? toString(*value) : std::string(); + }; + if (has_text) { - std::string u8string = util::replaceTokens(layout.text.field, (*feature_it).getProperties()); + std::string u8string = util::replaceTokens(layout.text.field, getValue); if (layout.text.transform == TextTransformType::Uppercase) { u8string = platform::uppercase(u8string); @@ -92,14 +99,14 @@ std::vector<SymbolFeature> SymbolBucket::processFeatures(const util::ptr<const G } if (has_icon) { - ft.sprite = util::replaceTokens(layout.icon.image, (*feature_it).getProperties()); + ft.sprite = util::replaceTokens(layout.icon.image, getValue); } if (ft.label.length() || ft.sprite.length()) { auto &multiline = ft.geometry; - GeometryCollection geometryCollection = (*feature_it).nextGeometry(); + GeometryCollection geometryCollection = feature->getGeometries(); multiline.emplace_back(); for (auto& geometry : geometryCollection) { const GeometryLine& line = geometry.get<GeometryLine>(); @@ -123,7 +130,8 @@ std::vector<SymbolFeature> SymbolBucket::processFeatures(const util::ptr<const G return features; } -void SymbolBucket::addFeatures(const util::ptr<const GeometryTileLayer> layer, const FilterExpression &filter, +void SymbolBucket::addFeatures(const GeometryTileLayer& layer, + const FilterExpression& filter, const Tile::ID &id, SpriteAtlas &spriteAtlas, Sprite &sprite, GlyphAtlas & glyphAtlas, GlyphStore &glyphStore) { auto &layout = *styleLayout; diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp index 9d2d002a63..75f66bff3c 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -65,9 +65,13 @@ public: bool hasTextData() const; bool hasIconData() const; - void addFeatures(const util::ptr<const GeometryTileLayer> layer, const FilterExpression &filter, - const Tile::ID &id, SpriteAtlas &spriteAtlas, Sprite &sprite, - GlyphAtlas &glyphAtlas, GlyphStore &glyphStore); + void addFeatures(const GeometryTileLayer&, + const FilterExpression&, + const Tile::ID&, + SpriteAtlas&, + Sprite&, + GlyphAtlas&, + GlyphStore&); void addGlyphs(const PlacedGlyphs &glyphs, float placementZoom, PlacementRange placementRange, float zoom); @@ -77,8 +81,10 @@ public: void drawIcons(IconShader& shader); private: - - std::vector<SymbolFeature> processFeatures(const util::ptr<const GeometryTileLayer> layer, const FilterExpression &filter, GlyphStore &glyphStore, const Sprite &sprite); + std::vector<SymbolFeature> processFeatures(const GeometryTileLayer&, + const FilterExpression&, + GlyphStore&, + const Sprite&); void addFeature(const std::vector<Coordinate> &line, const Shaping &shaping, const GlyphPositions &face, const Rect<uint16_t> &image); diff --git a/src/mbgl/util/token.hpp b/src/mbgl/util/token.hpp index 455190aabf..a2cc267bfe 100644 --- a/src/mbgl/util/token.hpp +++ b/src/mbgl/util/token.hpp @@ -38,14 +38,6 @@ std::string replaceTokens(const std::string &source, const Lookup &lookup) { return result; } -template <typename T> -inline std::string replaceTokens(const std::string &source, const std::map<std::string, T> &properties) { - return replaceTokens(source, [&properties](const std::string &token) -> std::string { - const auto it_prop = properties.find(token); - return it_prop != properties.end() ? toString(it_prop->second) : ""; - }); -} - } // end namespace util } // end namespace mbgl |