diff --git a/src/mbgl/map/geometry_tile.cpp b/src/mbgl/map/geometry_tile.cpp index b337cd7c9..0d7931b77 100644 --- a/src/mbgl/map/geometry_tile.cpp +++ b/src/mbgl/map/geometry_tile.cpp @@ -15,14 +15,6 @@ std::ostream& mbgl::operator<<(std::ostream& os, const GeometryFeatureType& type } } -GeometryTileFeature::GeometryTileFeature() {} - -Geometry GeometryTileFeature::nextGeometry() { - Geometry result; - result.set(); - return result; -} - std::ostream& mbgl::operator<<(std::ostream& os, const GeometryTileFeature& feature) { os << "Feature(" << feature.id << "): " << feature.type << std::endl; for (const auto& prop : feature.properties) { @@ -31,20 +23,10 @@ std::ostream& mbgl::operator<<(std::ostream& os, const GeometryTileFeature& feat return os; } -GeometryFilteredTileLayer::GeometryFilteredTileLayer(const GeometryTileLayer& layer_, const FilterExpression& filterExpression_) +GeometryFilteredTileLayer::GeometryFilteredTileLayer(const util::ptr layer_, const FilterExpression& filterExpression_) : layer(layer_), filterExpression(filterExpression_) {} -GeometryTileFeature GeometryFilteredTileLayer::nextMatchingFeature() { - GeometryTileFeature result; - result.type = GeometryFeatureType::Unknown; - return result; -} - -GeometryTileFeature GeometryTileLayer::nextFeature() { - return GeometryTileFeature(); -} - GeometryTile& GeometryTile::operator=(GeometryTile&& other) { if (this != &other) { layers.swap(other.layers); diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index 7d8698d13..4a7e05b90 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -18,7 +19,7 @@ namespace mbgl { -enum class GeometryFeatureType { +enum class GeometryFeatureType : uint8_t { Unknown = 0, Point = 1, LineString = 2, @@ -37,9 +38,7 @@ class GeometryTileLayer; class GeometryTileFeature { public: - GeometryTileFeature(); - - virtual Geometry nextGeometry(); + virtual Geometry nextGeometry() = 0; public: uint64_t id = 0; @@ -49,31 +48,33 @@ public: std::ostream& operator<<(std::ostream&, const GeometryTileFeature& feature); -template +template class GeometryTileTagExtractor { public: - GeometryTileTagExtractor(const GeometryTileLayer&); + GeometryTileTagExtractor(const util::ptr); - inline void setTags(const T& tags_) { tags = tags_; } - mapbox::util::optional getValue(const std::string &key) const; + inline void setTags(const Tags& tags_) { tags = tags_; } + virtual mapbox::util::optional getValue(const std::string &key) const; inline void setType(GeometryFeatureType type_) { type = type_; } inline GeometryFeatureType getType() const { return type; } -protected: - const GeometryTileLayer& layer; - T tags; +public: GeometryFeatureType type = GeometryFeatureType::Unknown; + Tags tags; + +protected: + const util::ptr layer; }; class GeometryFilteredTileLayer { public: - GeometryFilteredTileLayer(const GeometryTileLayer&, const FilterExpression&); + GeometryFilteredTileLayer(const util::ptr, const FilterExpression&); - virtual GeometryTileFeature nextMatchingFeature(); + virtual util::ptr nextMatchingFeature() = 0; protected: - const GeometryTileLayer& layer; + const util::ptr layer; const FilterExpression& filterExpression; }; @@ -81,7 +82,8 @@ std::ostream& operator<<(std::ostream&, const PositionedGlyph&); class GeometryTileLayer { public: - virtual GeometryTileFeature nextFeature(); + virtual util::ptr createFilter(const FilterExpression&) = 0; + virtual util::ptr nextFeature() = 0; public: std::string name; @@ -96,8 +98,10 @@ class GeometryTile { public: GeometryTile& operator=(GeometryTile&& other); + virtual void logDebug() const = 0; + public: - std::map layers; + std::map> layers; }; } diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp index de9c5a82e..de89143ae 100644 --- a/src/mbgl/map/tile_parser.cpp +++ b/src/mbgl/map/tile_parser.cpp @@ -189,7 +189,7 @@ std::unique_ptr TileParser::createBucket(const StyleBucket &bucketDesc) auto layer_it = vectorTile.layers.find(bucketDesc.source_layer); if (layer_it != vectorTile.layers.end()) { - const GeometryTileLayer &layer = layer_it->second; + const util::ptr layer = layer_it->second; if (bucketDesc.type == StyleLayerType::Fill) { return createFillBucket(layer, bucketDesc); } else if (bucketDesc.type == StyleLayerType::Line) { @@ -213,24 +213,24 @@ std::unique_ptr TileParser::createBucket(const StyleBucket &bucketDesc) } template -void TileParser::addBucketGeometries(Bucket& bucket, const GeometryTileLayer& layer, const FilterExpression &filter) { - GeometryFilteredTileLayer filtered_layer(layer, filter); - GeometryTileFeature feature = filtered_layer.nextMatchingFeature(); - while (feature.type != GeometryFeatureType::Unknown) { + void TileParser::addBucketGeometries(Bucket& bucket, const util::ptr layer, const FilterExpression &filter) { + util::ptr filtered_layer = layer->createFilter(filter); + util::ptr feature = filtered_layer->nextMatchingFeature(); + while (feature->type != GeometryFeatureType::Unknown) { if (obsolete()) return; - Geometry geometry = feature.nextGeometry(); + Geometry geometry = feature->nextGeometry(); while (!geometry.is()) { bucket->addGeometry(geometry); - geometry = feature.nextGeometry(); + geometry = feature->nextGeometry(); } - feature = filtered_layer.nextMatchingFeature(); + feature = filtered_layer->nextMatchingFeature(); } } -std::unique_ptr TileParser::createFillBucket(const GeometryTileLayer &layer, +std::unique_ptr TileParser::createFillBucket(const util::ptr layer, const StyleBucket &bucket_desc) { auto fill = parseStyleLayoutFill(bucket_desc, tile.id.z); auto bucket = util::make_unique(std::move(fill), @@ -241,7 +241,7 @@ std::unique_ptr TileParser::createFillBucket(const GeometryTileLayer &la return obsolete() ? nullptr : std::move(bucket); } -std::unique_ptr TileParser::createLineBucket(const GeometryTileLayer &layer, +std::unique_ptr TileParser::createLineBucket(const util::ptr layer, const StyleBucket &bucket_desc) { auto line = parseStyleLayoutLine(bucket_desc, tile.id.z); auto bucket = util::make_unique(std::move(line), @@ -252,7 +252,7 @@ std::unique_ptr TileParser::createLineBucket(const GeometryTileLayer &la return obsolete() ? nullptr : std::move(bucket); } -std::unique_ptr TileParser::createSymbolBucket(const GeometryTileLayer &layer, +std::unique_ptr TileParser::createSymbolBucket(const util::ptr layer, const StyleBucket &bucket_desc) { auto symbol = parseStyleLayoutSymbol(bucket_desc, tile.id.z); auto bucket = util::make_unique(std::move(symbol), *collision); diff --git a/src/mbgl/map/tile_parser.hpp b/src/mbgl/map/tile_parser.hpp index 841ae1749..ee134911f 100644 --- a/src/mbgl/map/tile_parser.hpp +++ b/src/mbgl/map/tile_parser.hpp @@ -53,11 +53,11 @@ private: void parseStyleLayers(util::ptr group); std::unique_ptr createBucket(const StyleBucket& bucketDesc); - std::unique_ptr createFillBucket(const GeometryTileLayer& layer, const StyleBucket& bucketDesc); - std::unique_ptr createLineBucket(const GeometryTileLayer& layer, const StyleBucket& bucketDesc); - std::unique_ptr createSymbolBucket(const GeometryTileLayer& layer, const StyleBucket& bucketDesc); + std::unique_ptr createFillBucket(const util::ptr layer, const StyleBucket& bucketDesc); + std::unique_ptr createLineBucket(const util::ptr layer, const StyleBucket& bucketDesc); + std::unique_ptr createSymbolBucket(const util::ptr layer, const StyleBucket& bucketDesc); - template void addBucketGeometries(Bucket& bucket, const GeometryTileLayer& layer, const FilterExpression& filter); + template void addBucketGeometries(Bucket& bucket, const util::ptr layer, const FilterExpression& filter); private: const VectorTile vectorTile; diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index a1ab4ec80..338f2acae 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 util::ptr layer) { while (feature_pbf.next()) { if (feature_pbf.tag == 1) { // id id = feature_pbf.varint(); @@ -18,17 +18,17 @@ VectorTileFeature::VectorTileFeature(pbf feature_pbf, const GeometryTileLayer& l while (tags) { uint32_t tag_key = tags.varint(); - if (layer.keys.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.values.size() <= tag_val) { + if (layer->values.size() <= tag_val) { throw std::runtime_error("feature referenced out of range value"); } - properties.emplace(layer.keys[tag_key], layer.values[tag_val]); + properties.emplace(layer->keys[tag_key], layer->values[tag_val]); } else { throw std::runtime_error("uneven number of feature tag ids"); } @@ -93,18 +93,23 @@ Geometry VectorTileFeature::nextGeometry() { return std::move(result); } -VectorTile::VectorTile(pbf tile) { - while (tile.next()) { - if (tile.tag == 3) { // layer - VectorTileLayer layer(tile.message()); - layers.emplace(layer.name, std::forward(layer)); +VectorTile::VectorTile(pbf tile_pbf) { + while (tile_pbf.next()) { + if (tile_pbf.tag == 3) { // layer + util::ptr layer = std::make_shared(tile_pbf.message()); + layers.emplace(layer->name, std::forward>(layer)); } else { - tile.skip(); + tile_pbf.skip(); } } } -VectorTileLayer::VectorTileLayer(pbf layer) : feature_pbf(layer) { +void VectorTile::logDebug() const { + printf("got here for VectorTile\n"); +} + +VectorTileLayer::VectorTileLayer(pbf layer_pbf) + : feature_pbf(layer_pbf) { while (feature_pbf.next()) { if (feature_pbf.tag == 1) { // name name = feature_pbf.string(); @@ -121,13 +126,13 @@ VectorTileLayer::VectorTileLayer(pbf layer) : feature_pbf(layer) { } } -FilteredVectorTileLayer::FilteredVectorTileLayer(const VectorTileLayer& layer_, const FilterExpression& filterExpression_) +FilteredVectorTileLayer::FilteredVectorTileLayer(const util::ptr layer_, const FilterExpression& filterExpression_) : GeometryFilteredTileLayer(layer_, filterExpression_) { - feature_pbf = layer_.feature_pbf; + feature_pbf = layer_->feature_pbf; } template <> -GeometryTileTagExtractor::GeometryTileTagExtractor(const GeometryTileLayer& layer_) +GeometryTileTagExtractor::GeometryTileTagExtractor(const util::ptr layer_) : layer(layer_) {} template <> @@ -138,8 +143,8 @@ mapbox::util::optional GeometryTileTagExtractor::getValue(const std: mapbox::util::optional value; - auto field_it = layer.key_index.find(key); - if (field_it != layer.key_index.end()) { + auto field_it = layer->key_index.find(key); + if (field_it != layer->key_index.end()) { const uint32_t filter_key = field_it->second; // Now loop through all the key/value pair tags. @@ -157,8 +162,8 @@ mapbox::util::optional GeometryTileTagExtractor::getValue(const std: tag_val = tags_pbf_.varint(); if (tag_key == filter_key) { - if (layer.values.size() > tag_val) { - value = layer.values[tag_val]; + if (layer->values.size() > tag_val) { + value = layer->values[tag_val]; } else { fprintf(stderr, "[WARNING] feature references out of range value\n"); break; @@ -172,10 +177,8 @@ mapbox::util::optional GeometryTileTagExtractor::getValue(const std: template bool mbgl::evaluate(const FilterExpression&, const GeometryTileTagExtractor&); -GeometryTileFeature FilteredVectorTileLayer::nextMatchingFeature() { - GeometryTileFeature result; - - if (feature_pbf.next(2)) { +util::ptr FilteredVectorTileLayer::nextMatchingFeature() { + while (feature_pbf.next(2)) { pbf current_feature_pbf = feature_pbf.message(); GeometryTileTagExtractor extractor(layer); @@ -191,19 +194,21 @@ GeometryTileFeature FilteredVectorTileLayer::nextMatchingFeature() { } if (evaluate(filterExpression, extractor)) { - result = VectorTileFeature(current_feature_pbf.message(), layer); + return std::move(std::make_shared(current_feature_pbf.message(), layer)); } } - return std::move(result); + return std::move(std::make_shared(pbf(), layer)); } -GeometryTileFeature VectorTileLayer::nextFeature() { - GeometryTileFeature result; +util::ptr VectorTileLayer::createFilter(const FilterExpression& filterExpression) { + return std::make_shared(shared_from_this(), filterExpression); +} - if (feature_pbf.next(2)) { - result = VectorTileFeature(feature_pbf.message(), *this); +util::ptr VectorTileLayer::nextFeature() { + while (feature_pbf.next(2)) { + return std::move(std::make_shared(feature_pbf.message(), shared_from_this())); } - return std::move(result); + return std::move(std::make_shared(pbf(), shared_from_this())); } diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index f83eebb1e..f16e98c3b 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include namespace mbgl { @@ -12,7 +13,7 @@ class VectorTileLayer; class VectorTileFeature : public GeometryTileFeature { public: - VectorTileFeature(pbf, const GeometryTileLayer&); + VectorTileFeature(pbf, const util::ptr); Geometry nextGeometry(); @@ -23,21 +24,22 @@ private: class FilteredVectorTileLayer : public GeometryFilteredTileLayer { public: - FilteredVectorTileLayer(const VectorTileLayer&, const FilterExpression&); + FilteredVectorTileLayer(const util::ptr, const FilterExpression&); - GeometryTileFeature nextMatchingFeature(); + virtual util::ptr nextMatchingFeature(); private: pbf feature_pbf; }; -class VectorTileLayer : public GeometryTileLayer { +class VectorTileLayer : public GeometryTileLayer, public std::enable_shared_from_this { friend class FilteredVectorTileLayer; public: VectorTileLayer(pbf); - GeometryTileFeature nextFeature(); + virtual util::ptr createFilter(const FilterExpression&); + virtual util::ptr nextFeature(); private: pbf feature_pbf; @@ -46,6 +48,8 @@ private: class VectorTile : public GeometryTile { public: VectorTile(pbf); + + virtual void logDebug() const; }; } diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 245eb7329..60315c8fe 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -47,7 +47,7 @@ void SymbolBucket::addGlyphsToAtlas(uint64_t tileid, const std::string stackname glyphAtlas.addGlyphs(tileid, text, stackname, fontStack,face); } -std::vector SymbolBucket::processFeatures(const GeometryTileLayer &layer, +std::vector SymbolBucket::processFeatures(const util::ptr layer, const FilterExpression &filter, GlyphStore &glyphStore, const Sprite &sprite) { @@ -64,14 +64,14 @@ std::vector SymbolBucket::processFeatures(const GeometryTileLayer // Determine and load glyph ranges std::set ranges; - GeometryFilteredTileLayer filtered_layer(layer, filter); - GeometryTileFeature feature = filtered_layer.nextMatchingFeature(); - while (feature.type != GeometryFeatureType::Unknown) { + util::ptr filtered_layer = layer->createFilter(filter); + util::ptr feature = filtered_layer->nextMatchingFeature(); + while (feature->type != GeometryFeatureType::Unknown) { SymbolFeature ft; if (has_text) { - std::string u8string = util::replaceTokens(layout.text.field, feature.properties); + std::string u8string = util::replaceTokens(layout.text.field, feature->properties); if (layout.text.transform == TextTransformType::Uppercase) { u8string = platform::uppercase(u8string); @@ -90,14 +90,14 @@ std::vector SymbolBucket::processFeatures(const GeometryTileLayer } if (has_icon) { - ft.sprite = util::replaceTokens(layout.icon.image, feature.properties); + ft.sprite = util::replaceTokens(layout.icon.image, feature->properties); } if (ft.label.length() || ft.sprite.length()) { auto &multiline = ft.geometry; - Geometry geometry = feature.nextGeometry(); + Geometry geometry = feature->nextGeometry(); const GeometryLine& line = geometry.get(); bool first = true; for (auto point_it = line.begin(); point_it != line.end(); point_it++) { @@ -111,7 +111,7 @@ std::vector SymbolBucket::processFeatures(const GeometryTileLayer features.push_back(std::move(ft)); } - feature = filtered_layer.nextMatchingFeature(); + feature = filtered_layer->nextMatchingFeature(); } if (layout.placement == PlacementType::Line) { @@ -124,7 +124,7 @@ std::vector SymbolBucket::processFeatures(const GeometryTileLayer return features; } -void SymbolBucket::addFeatures(const GeometryTileLayer &layer, const FilterExpression &filter, +void SymbolBucket::addFeatures(const util::ptr 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 ce2629d3a..d9b461afa 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -64,7 +65,7 @@ public: bool hasTextData() const; bool hasIconData() const; - void addFeatures(const GeometryTileLayer &layer, const FilterExpression &filter, + void addFeatures(const util::ptr layer, const FilterExpression &filter, const Tile::ID &id, SpriteAtlas &spriteAtlas, Sprite &sprite, GlyphAtlas &glyphAtlas, GlyphStore &glyphStore); @@ -77,7 +78,7 @@ public: private: - std::vector processFeatures(const GeometryTileLayer &layer, const FilterExpression &filter, GlyphStore &glyphStore, const Sprite &sprite); + std::vector processFeatures(const util::ptr layer, const FilterExpression &filter, GlyphStore &glyphStore, const Sprite &sprite); void addFeature(const GeometryLine &line, const Shaping &shaping, const GlyphPositions &face, const Rect &image);