diff --git a/src/mbgl/geometry/geometry.hpp b/src/mbgl/geometry/geometry.hpp deleted file mode 100644 index 484d17b36da..00000000000 --- a/src/mbgl/geometry/geometry.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef MBGL_GEOMETRY_GEOMETRY -#define MBGL_GEOMETRY_GEOMETRY - -#include -#include - -#include - -namespace mbgl { - -class Geometry : private util::noncopyable { - -public: - inline explicit Geometry(pbf& data); - - enum command : uint8_t { - end = 0, - move_to = 1, - line_to = 2, - close = 7 - }; - - inline command next(int32_t &rx, int32_t &ry); - -private: - pbf& data; - uint8_t cmd; - uint32_t length; - int32_t x, y; - int32_t ox, oy; -}; - -Geometry::Geometry(pbf& data_) - : data(data_), - cmd(1), - length(0), - x(0), y(0), - ox(0), oy(0) {} - -Geometry::command Geometry::next(int32_t &rx, int32_t &ry) { - if (data.data < data.end) { - if (length == 0) { - uint32_t cmd_length = static_cast(data.varint()); - cmd = cmd_length & 0x7; - length = cmd_length >> 3; - } - - --length; - - if (cmd == move_to || cmd == line_to) { - rx = (x += data.svarint()); - ry = (y += data.svarint()); - - if (cmd == move_to) { - ox = x; - oy = y; - return move_to; - } else { - return line_to; - } - } else if (cmd == close) { - rx = ox; - ry = oy; - return close; - } else { - fprintf(stderr, "unknown command: %d\n", cmd); - // TODO: gracefully handle geometry parse failures - return end; - } - } else { - return end; - } -} - -} - -#endif diff --git a/src/mbgl/geometry/glyph_atlas.cpp b/src/mbgl/geometry/glyph_atlas.cpp index fd429d41a32..4aaa77f38dd 100644 --- a/src/mbgl/geometry/glyph_atlas.cpp +++ b/src/mbgl/geometry/glyph_atlas.cpp @@ -1,5 +1,4 @@ #include -#include #include #include diff --git a/src/mbgl/map/geometry_tile.cpp b/src/mbgl/map/geometry_tile.cpp new file mode 100644 index 00000000000..f87468914c0 --- /dev/null +++ b/src/mbgl/map/geometry_tile.cpp @@ -0,0 +1,16 @@ +#include +#include + +namespace mbgl { + +mapbox::util::optional GeometryTileFeatureExtractor::getValue(const std::string& key) const { + if (key == "$type") { + return Value(uint64_t(feature.getType())); + } + + return feature.getValue(key); +} + +template bool evaluate(const FilterExpression&, const GeometryTileFeatureExtractor&); + +} diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp new file mode 100644 index 00000000000..f303a32bde6 --- /dev/null +++ b/src/mbgl/map/geometry_tile.hpp @@ -0,0 +1,62 @@ +#ifndef MBGL_MAP_GEOMETRY_TILE +#define MBGL_MAP_GEOMETRY_TILE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace mbgl { + +enum class FeatureType : uint8_t { + Unknown = 0, + Point = 1, + LineString = 2, + Polygon = 3 +}; + +typedef std::vector> GeometryCollection; + +class GeometryTileFeature : public mbgl::util::noncopyable { +public: + virtual FeatureType getType() const = 0; + virtual mapbox::util::optional getValue(const std::string& key) const = 0; + virtual GeometryCollection getGeometries() const = 0; +}; + +class GeometryTileLayer : public mbgl::util::noncopyable { +public: + virtual std::size_t featureCount() const = 0; + virtual util::ptr feature(std::size_t i) const = 0; +}; + +class GeometryTile : public mbgl::util::noncopyable { +public: + virtual util::ptr getLayer(const std::string&) const = 0; +}; + +class GeometryTileFeatureExtractor { +public: + GeometryTileFeatureExtractor(const GeometryTileFeature& feature_) + : feature(feature_) {} + + mapbox::util::optional getValue(const std::string& key) const; + +private: + const GeometryTileFeature& feature; +}; + +} + +#endif diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp index 43e754978bb..48f5b1405f0 100644 --- a/src/mbgl/map/tile_parser.cpp +++ b/src/mbgl/map/tile_parser.cpp @@ -187,15 +187,14 @@ std::unique_ptr TileParser::createBucket(const StyleBucket &bucketDesc) if (tile.id.z >= std::ceil(bucketDesc.max_zoom)) return nullptr; if (bucketDesc.visibility == mbgl::VisibilityType::None) return nullptr; - auto layer_it = vectorTile.layers.find(bucketDesc.source_layer); - if (layer_it != vectorTile.layers.end()) { - const VectorTileLayer &layer = layer_it->second; + 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 { @@ -213,25 +212,23 @@ std::unique_ptr TileParser::createBucket(const StyleBucket &bucketDesc) } template -void TileParser::addBucketGeometries(Bucket& bucket, const VectorTileLayer& layer, const FilterExpression &filter) { - FilteredVectorTileLayer filtered_layer(layer, filter); - for (pbf feature : filtered_layer) { +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; - while (feature.next(4)) { // geometry - pbf geometry_pbf = feature.message(); - if (geometry_pbf) { - bucket->addGeometry(geometry_pbf); - } else if (debug::tileParseWarnings) { - fprintf(stderr, "[WARNING] geometry is empty\n"); - } - } + GeometryTileFeatureExtractor extractor(*feature); + if (!evaluate(filter, extractor)) + continue; + + bucket->addGeometry(feature->getGeometries()); } } -std::unique_ptr TileParser::createFillBucket(const VectorTileLayer &layer, - const StyleBucket &bucket_desc) { +std::unique_ptr TileParser::createFillBucket(const GeometryTileLayer& layer, + const StyleBucket& bucket_desc) { auto fill = parseStyleLayoutFill(bucket_desc, tile.id.z); auto bucket = util::make_unique(std::move(fill), tile.fillVertexBuffer, @@ -241,8 +238,8 @@ std::unique_ptr TileParser::createFillBucket(const VectorTileLayer &laye return obsolete() ? nullptr : std::move(bucket); } -std::unique_ptr TileParser::createLineBucket(const VectorTileLayer &layer, - const StyleBucket &bucket_desc) { +std::unique_ptr TileParser::createLineBucket(const GeometryTileLayer& layer, + const StyleBucket& bucket_desc) { auto line = parseStyleLayoutLine(bucket_desc, tile.id.z); auto bucket = util::make_unique(std::move(line), tile.lineVertexBuffer, @@ -252,8 +249,8 @@ std::unique_ptr TileParser::createLineBucket(const VectorTileLayer &laye return obsolete() ? nullptr : std::move(bucket); } -std::unique_ptr TileParser::createSymbolBucket(const VectorTileLayer &layer, - const StyleBucket &bucket_desc) { +std::unique_ptr TileParser::createSymbolBucket(const GeometryTileLayer& layer, + const StyleBucket& bucket_desc) { auto symbol = parseStyleLayoutSymbol(bucket_desc, tile.id.z); auto bucket = util::make_unique(std::move(symbol), *collision); bucket->addFeatures( diff --git a/src/mbgl/map/tile_parser.hpp b/src/mbgl/map/tile_parser.hpp index 228557846c6..e7c05e1b1e9 100644 --- a/src/mbgl/map/tile_parser.hpp +++ b/src/mbgl/map/tile_parser.hpp @@ -1,6 +1,7 @@ #ifndef MBGL_MAP_TILE_PARSER #define MBGL_MAP_TILE_PARSER +#include #include #include #include @@ -51,12 +52,13 @@ class TileParser : private util::noncopyable bool obsolete() const; void parseStyleLayers(util::ptr group); - std::unique_ptr createBucket(const StyleBucket& bucketDesc); - std::unique_ptr createFillBucket(const VectorTileLayer& layer, const StyleBucket& bucketDesc); - std::unique_ptr createLineBucket(const VectorTileLayer& layer, const StyleBucket& bucketDesc); - std::unique_ptr createSymbolBucket(const VectorTileLayer& layer, const StyleBucket& bucketDesc); + std::unique_ptr createBucket(const StyleBucket&); + std::unique_ptr createFillBucket(const GeometryTileLayer&, const StyleBucket&); + std::unique_ptr createLineBucket(const GeometryTileLayer&, const StyleBucket&); + std::unique_ptr createSymbolBucket(const GeometryTileLayer&, const StyleBucket&); - template void addBucketGeometries(Bucket& bucket, const VectorTileLayer& layer, const FilterExpression& filter); + template + 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 2828b088429..e9ae52e9ad1 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -1,30 +1,14 @@ #include -#include -#include - -#include -#include using namespace mbgl; - -std::ostream& mbgl::operator<<(std::ostream& os, const FeatureType& type) { - switch (type) { - case FeatureType::Unknown: return os << "Unknown"; - case FeatureType::Point: return os << "Point"; - case FeatureType::LineString: return os << "LineString"; - case FeatureType::Polygon: return os << "Polygon"; - default: return os << "Invalid"; - } -} - -VectorTileFeature::VectorTileFeature(pbf feature, const VectorTileLayer& layer) { - while (feature.next()) { - if (feature.tag == 1) { // id - id = feature.varint(); - } else if (feature.tag == 2) { // tags +VectorTileFeature::VectorTileFeature(pbf feature_pbf, const VectorTileLayer& layer) { + while (feature_pbf.next()) { + if (feature_pbf.tag == 1) { // id + id = feature_pbf.varint(); + } else if (feature_pbf.tag == 2) { // tags // tags are packed varints. They should have an even length. - pbf tags = feature.message(); + pbf tags = feature_pbf.message(); while (tags) { uint32_t tag_key = tags.varint(); @@ -43,173 +27,106 @@ VectorTileFeature::VectorTileFeature(pbf feature, const VectorTileLayer& layer) throw std::runtime_error("uneven number of feature tag ids"); } } - } else if (feature.tag == 3) { // type - type = (FeatureType)feature.varint(); - } else if (feature.tag == 4) { // geometry - geometry = feature.message(); + } else if (feature_pbf.tag == 3) { // type + type = (FeatureType)feature_pbf.varint(); + } else if (feature_pbf.tag == 4) { // geometry + geometry_pbf = feature_pbf.message(); } else { - feature.skip(); + feature_pbf.skip(); } } } - -std::ostream& mbgl::operator<<(std::ostream& os, const VectorTileFeature& feature) { - os << "Feature(" << feature.id << "): " << feature.type << std::endl; - for (const auto& prop : feature.properties) { - os << " - " << prop.first << ": " << prop.second << std::endl; +mapbox::util::optional VectorTileFeature::getValue(const std::string& key) const { + auto it = properties.find(key); + if (it != properties.end()) { + return it->second; } - return os; + return mapbox::util::optional(); } +GeometryCollection VectorTileFeature::getGeometries() const { + pbf data(geometry_pbf); + uint8_t cmd = 1; + uint32_t length = 0; + int32_t x = 0; + int32_t y = 0; -VectorTile::VectorTile() {} + GeometryCollection lines; + lines.emplace_back(); + std::vector* line = &lines.back(); -VectorTile::VectorTile(pbf tile) { - while (tile.next()) { - if (tile.tag == 3) { // layer - VectorTileLayer layer(tile.message()); - layers.emplace(layer.name, std::forward(layer)); - } else { - tile.skip(); + while (data.data < data.end) { + if (length == 0) { + uint32_t cmd_length = data.varint(); + cmd = cmd_length & 0x7; + length = cmd_length >> 3; } - } -} - -VectorTile& VectorTile::operator=(VectorTile && other) { - if (this != &other) { - layers.swap(other.layers); - } - return *this; -} - -VectorTileLayer::VectorTileLayer(pbf layer) : data(layer) { - std::vector stacks; - - while (layer.next()) { - if (layer.tag == 1) { // name - name = layer.string(); - } else if (layer.tag == 3) { // keys - keys.emplace_back(layer.string()); - key_index.emplace(keys.back(), keys.size() - 1); - } else if (layer.tag == 4) { // values - values.emplace_back(std::move(parseValue(layer.message()))); - } else if (layer.tag == 5) { // extent - extent = layer.varint(); - } else { - layer.skip(); - } - } -} - -FilteredVectorTileLayer::FilteredVectorTileLayer(const VectorTileLayer& layer_, const FilterExpression &filterExpression_) - : layer(layer_), - filterExpression(filterExpression_) { -} - -FilteredVectorTileLayer::iterator FilteredVectorTileLayer::begin() const { - return iterator(*this, layer.data); -} - -FilteredVectorTileLayer::iterator FilteredVectorTileLayer::end() const { - return iterator(*this, pbf(layer.data.end, 0)); -} -FilteredVectorTileLayer::iterator::iterator(const FilteredVectorTileLayer& parent_, const pbf& data_) - : parent(parent_), - feature(pbf()), - data(data_) { - operator++(); -} - -VectorTileTagExtractor::VectorTileTagExtractor(const VectorTileLayer &layer) : layer_(layer) {} + --length; + if (cmd == 1 || cmd == 2) { + x += data.svarint(); + y += data.svarint(); -void VectorTileTagExtractor::setTags(const pbf &pbf) { - tags_ = pbf; -} + if (cmd == 1 && !line->empty()) { // moveTo + lines.emplace_back(); + line = &lines.back(); + } -mapbox::util::optional VectorTileTagExtractor::getValue(const std::string &key) const { - if (key == "$type") { - return Value(uint64_t(type_)); - } + line->emplace_back(x, y); - mapbox::util::optional value; - - 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. - // 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; + } else if (cmd == 7) { // closePolygon + if (!line->empty()) { + line->push_back((*line)[0]); } - // 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_.values.size() > tag_val) { - value = layer_.values[tag_val]; - } else { - fprintf(stderr, "[WARNING] feature references out of range value\n"); - break; - } - } + } else { + throw std::runtime_error("unknown command"); } } - return value; + return lines; } -void VectorTileTagExtractor::setType(FeatureType type) { - type_ = type; -} - -template bool mbgl::evaluate(const FilterExpression&, const VectorTileTagExtractor&); - -void FilteredVectorTileLayer::iterator::operator++() { - valid = false; - - const FilterExpression &expression = parent.filterExpression; - - while (data.next(2)) { // feature - feature = data.message(); - pbf feature_pbf = feature; - - VectorTileTagExtractor 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(FeatureType(feature_pbf.varint())); - } else { - feature_pbf.skip(); - } - } - - if (evaluate(expression, extractor)) { - valid = true; - return; // data loop +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, layer); } else { - valid = false; + tile_pbf.skip(); } } } -bool FilteredVectorTileLayer::iterator::operator!=(const iterator& other) const { - return !(data.data == other.data.data && data.end == other.data.end && valid == other.valid); +util::ptr VectorTile::getLayer(const std::string& name) const { + auto layer_it = layers.find(name); + if (layer_it != layers.end()) { + return layer_it->second; + } + return nullptr; +} + +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()); + } else if (layer_pbf.tag == 4) { // values + values.emplace_back(std::move(parseValue(layer_pbf.message()))); + } else if (layer_pbf.tag == 5) { // extent + extent = layer_pbf.varint(); + } else { + layer_pbf.skip(); + } + } } -const pbf& FilteredVectorTileLayer::iterator:: operator*() const { - return feature; +util::ptr VectorTileLayer::feature(std::size_t i) const { + return std::make_shared(features.at(i), *this); } diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index 2d02ba3a0b2..fc8c5966a03 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -1,117 +1,55 @@ #ifndef MBGL_MAP_VECTOR_TILE #define MBGL_MAP_VECTOR_TILE -#include -#include -#include +#include #include -#include - -#include -#include -#include -#include -#include -#include namespace mbgl { class VectorTileLayer; -enum class FeatureType { - Unknown = 0, - Point = 1, - LineString = 2, - Polygon = 3 -}; - -std::ostream& operator<<(std::ostream&, const FeatureType& type); - -class VectorTileFeature { +class VectorTileFeature : public GeometryTileFeature { public: - VectorTileFeature(pbf feature, const VectorTileLayer& layer); + VectorTileFeature(pbf, const VectorTileLayer&); + FeatureType getType() const override { return type; } + mapbox::util::optional getValue(const std::string&) const override; + GeometryCollection getGeometries() const override; + +private: uint64_t id = 0; FeatureType type = FeatureType::Unknown; std::map properties; - pbf geometry; + pbf geometry_pbf; }; -std::ostream& operator<<(std::ostream&, const VectorTileFeature& feature); - - -class VectorTileTagExtractor { +class VectorTileLayer : public GeometryTileLayer { public: - VectorTileTagExtractor(const VectorTileLayer &layer); + VectorTileLayer(pbf); - void setTags(const pbf &pbf); - mapbox::util::optional getValue(const std::string &key) const; - void setType(FeatureType type); - FeatureType getType() const; + std::size_t featureCount() const override { return features.size(); } + util::ptr feature(std::size_t) const override; private: - const VectorTileLayer &layer_; - pbf tags_; - FeatureType type_ = FeatureType::Unknown; -}; - -/* - * Allows iterating over the features of a VectorTileLayer using a - * BucketDescription as filter. Only features matching the descriptions will - * be returned (as pbf). - */ -class FilteredVectorTileLayer { -public: - class iterator { - public: - iterator(const FilteredVectorTileLayer& filter, const pbf& data); - void operator++(); - bool operator!=(const iterator& other) const; - const pbf& operator*() const; - - private: - const FilteredVectorTileLayer& parent; - bool valid = false; - pbf feature; - pbf data; - }; + friend class VectorTile; + friend class VectorTileFeature; -public: - FilteredVectorTileLayer(const VectorTileLayer& layer, const FilterExpression &filterExpression); - - iterator begin() const; - iterator end() const; - -private: - const VectorTileLayer& layer; - const FilterExpression& filterExpression; -}; - -std::ostream& operator<<(std::ostream&, const PositionedGlyph& placement); - -class VectorTileLayer { -public: - VectorTileLayer(pbf data); - - const pbf data; std::string name; uint32_t extent = 4096; std::vector keys; - std::unordered_map key_index; std::vector values; - std::map> shaping; + std::vector features; }; -class VectorTile { +class VectorTile : public GeometryTile { public: - VectorTile(); - VectorTile(pbf data); - VectorTile& operator=(VectorTile&& other); - - std::map layers; -}; + VectorTile(pbf); + util::ptr getLayer(const std::string&) const override; +private: + std::map> layers; +}; } diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index c632244d775..19ee302125c 100644 --- a/src/mbgl/renderer/fill_bucket.cpp +++ b/src/mbgl/renderer/fill_bucket.cpp @@ -1,17 +1,12 @@ #include #include #include -#include - #include #include #include -#include #include - #include - #include struct geometry_too_long_exception : std::exception {}; @@ -69,27 +64,16 @@ FillBucket::~FillBucket() { } } -void FillBucket::addGeometry(pbf& geom) { - Geometry::command cmd; - - Coordinate coord; - Geometry geometry(geom); - int32_t x, y; - while ((cmd = geometry.next(x, y)) != Geometry::end) { - if (cmd == Geometry::move_to) { - if (line.size()) { - clipper.AddPath(line, ClipperLib::ptSubject, true); - line.clear(); - hasVertices = true; - } +void FillBucket::addGeometry(const GeometryCollection& geometryCollection) { + for (auto& line_ : geometryCollection) { + for (auto& v : line_) { + line.emplace_back(v.x, v.y); + } + if (line.size()) { + clipper.AddPath(line, ClipperLib::ptSubject, true); + line.clear(); + hasVertices = true; } - line.emplace_back(x, y); - } - - if (line.size()) { - clipper.AddPath(line, ClipperLib::ptSubject, true); - line.clear(); - hasVertices = true; } tessellate(); diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index b674f104e4e..46b8f538574 100644 --- a/src/mbgl/renderer/fill_bucket.hpp +++ b/src/mbgl/renderer/fill_bucket.hpp @@ -2,6 +2,7 @@ #define MBGL_RENDERER_FILLBUCKET #include +#include #include #include #include @@ -27,7 +28,6 @@ class BucketDescription; class OutlineShader; class PlainShader; class PatternShader; -struct pbf; class FillBucket : public Bucket { @@ -49,7 +49,7 @@ class FillBucket : public Bucket { const mat4 &matrix) override; bool hasData() const override; - void addGeometry(pbf& data); + void addGeometry(const GeometryCollection&); void tessellate(); void drawElements(PlainShader& shader); diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index fc9482d1d68..6eea0d8d0f0 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -1,12 +1,9 @@ #include -#include -#include +#include #include #include #include -#include - #include #include #include @@ -37,28 +34,6 @@ LineBucket::~LineBucket() { // Do not remove. header file only contains forward definitions to unique pointers. } - -void LineBucket::addGeometry(pbf& geom) { - std::vector line; - Geometry::command cmd; - - Coordinate coord; - Geometry geometry(geom); - int32_t x, y; - while ((cmd = geometry.next(x, y)) != Geometry::end) { - if (cmd == Geometry::move_to) { - if (!line.empty()) { - addGeometry(line); - line.clear(); - } - } - line.emplace_back(x, y); - } - if (line.size()) { - addGeometry(line); - } -} - struct TriangleElement { TriangleElement(uint16_t a_, uint16_t b_, uint16_t c_) : a(a_), b(b_), c(c_) {} uint16_t a, b, c; @@ -66,6 +41,12 @@ struct TriangleElement { typedef uint16_t PointElement; +void LineBucket::addGeometry(const GeometryCollection& geometryCollection) { + for (auto& line : geometryCollection) { + addGeometry(line); + } +} + void LineBucket::addGeometry(const std::vector& vertices) { auto &layout = *styleLayout; // TODO: use roundLimit diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index 1059cee71d4..25b21901766 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -2,6 +2,7 @@ #define MBGL_RENDERER_LINEBUCKET #include +#include #include #include #include @@ -20,7 +21,6 @@ class LineShader; class LinejoinShader; class LineSDFShader; class LinepatternShader; -struct pbf; class LineBucket : public Bucket { typedef ElementGroup<3> triangle_group_type; @@ -37,7 +37,7 @@ class LineBucket : public Bucket { const mat4 &matrix) override; bool hasData() const override; - void addGeometry(pbf& data); + void addGeometry(const GeometryCollection&); void addGeometry(const std::vector& line); bool hasPoints() const; diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 63630e1c06c..c755573df9c 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -1,10 +1,10 @@ -#include #include +#include +#include #include #include #include #include -#include #include #include #include @@ -18,6 +18,7 @@ #include #include #include +#include namespace mbgl { @@ -47,8 +48,8 @@ void SymbolBucket::addGlyphsToAtlas(uint64_t tileid, const std::string stackname glyphAtlas.addGlyphs(tileid, text, stackname, fontStack,face); } -std::vector SymbolBucket::processFeatures(const VectorTileLayer &layer, - const FilterExpression &filter, +std::vector SymbolBucket::processFeatures(const GeometryTileLayer& layer, + const FilterExpression& filter, GlyphStore &glyphStore, const Sprite &sprite) { auto &layout = *styleLayout; @@ -64,14 +65,22 @@ std::vector SymbolBucket::processFeatures(const VectorTileLayer & // Determine and load glyph ranges std::set ranges; - FilteredVectorTileLayer filtered_layer(layer, filter); - for (const pbf &feature_pbf : filtered_layer) { - const VectorTileFeature feature{feature_pbf, layer}; + for (std::size_t i = 0; i < layer.featureCount(); i++) { + auto feature = layer.feature(i); + + 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.properties); + std::string u8string = util::replaceTokens(layout.text.field, getValue); if (layout.text.transform == TextTransformType::Uppercase) { u8string = platform::uppercase(u8string); @@ -90,25 +99,19 @@ std::vector SymbolBucket::processFeatures(const VectorTileLayer & } if (has_icon) { - ft.sprite = util::replaceTokens(layout.icon.image, feature.properties); + ft.sprite = util::replaceTokens(layout.icon.image, getValue); } if (ft.label.length() || ft.sprite.length()) { auto &multiline = ft.geometry; - // Decode line - Geometry::command cmd; - pbf geom(feature.geometry); - Geometry geometry(geom); - bool first = true; - int32_t x, y; - while ((cmd = geometry.next(x, y)) != Geometry::end) { - if (first || cmd == Geometry::move_to) { - multiline.emplace_back(); - first = false; + GeometryCollection geometryCollection = feature->getGeometries(); + for (auto& line : geometryCollection) { + multiline.emplace_back(); + for (auto& point : line) { + multiline.back().emplace_back(point.x, point.y); } - multiline.back().emplace_back(x, y); } features.push_back(std::move(ft)); @@ -125,7 +128,8 @@ std::vector SymbolBucket::processFeatures(const VectorTileLayer & return features; } -void SymbolBucket::addFeatures(const VectorTileLayer &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 0637c01cfe1..75f66bff3c9 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -2,14 +2,15 @@ #define MBGL_RENDERER_SYMBOLBUCKET #include +#include #include #include #include #include -#include #include #include #include +#include #include #include @@ -64,9 +65,13 @@ class SymbolBucket : public Bucket { bool hasTextData() const; bool hasIconData() const; - void addFeatures(const VectorTileLayer &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); @@ -76,13 +81,13 @@ class SymbolBucket : public Bucket { void drawIcons(IconShader& shader); private: - - std::vector processFeatures(const VectorTileLayer &layer, const FilterExpression &filter, GlyphStore &glyphStore, const Sprite &sprite); - + std::vector processFeatures(const GeometryTileLayer&, + const FilterExpression&, + GlyphStore&, + const Sprite&); void addFeature(const std::vector &line, const Shaping &shaping, const GlyphPositions &face, const Rect &image); - // Adds placed items to the buffer. template void addSymbols(Buffer &buffer, const PlacedGlyphs &symbols, float scale, PlacementRange placementRange); diff --git a/src/mbgl/style/filter_expression.cpp b/src/mbgl/style/filter_expression.cpp index 7d4f60b3ed3..ec44b57b550 100644 --- a/src/mbgl/style/filter_expression.cpp +++ b/src/mbgl/style/filter_expression.cpp @@ -1,4 +1,4 @@ -#include +#include #include namespace mbgl { diff --git a/src/mbgl/util/token.hpp b/src/mbgl/util/token.hpp index 455190aabf3..a2cc267bfec 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 -inline std::string replaceTokens(const std::string &source, const std::map &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