From 831264d5305b5352b7e8d419d29750119a5a2cf9 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Mon, 2 Mar 2015 16:30:22 -0800 Subject: [PATCH 01/27] refs #928: 90% of way to genericizing VectorTile --- src/mbgl/map/geometry_tile.cpp | 29 +++++++ src/mbgl/map/geometry_tile.hpp | 105 ++++++++++++++++++++++++ src/mbgl/map/vector_tile.cpp | 114 ++++++++++----------------- src/mbgl/map/vector_tile.hpp | 93 ++++++---------------- src/mbgl/style/filter_expression.cpp | 10 +-- 5 files changed, 203 insertions(+), 148 deletions(-) create mode 100644 src/mbgl/map/geometry_tile.cpp create mode 100644 src/mbgl/map/geometry_tile.hpp diff --git a/src/mbgl/map/geometry_tile.cpp b/src/mbgl/map/geometry_tile.cpp new file mode 100644 index 00000000000..53272b10c6b --- /dev/null +++ b/src/mbgl/map/geometry_tile.cpp @@ -0,0 +1,29 @@ +#include +#include + +#include + +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"; + } +} + +GeometryTile& GeometryTile::operator=(GeometryTile&& other) { + if (this != &other) { + layers.swap(other.layers); + } + return *this; +} + +template +GeometryFilteredTileLayer::iterator::iterator(const GeometryFilteredTileLayer& parent_) + : parent(parent_) { + operator++(); +} diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp new file mode 100644 index 00000000000..6ca2b0eb569 --- /dev/null +++ b/src/mbgl/map/geometry_tile.hpp @@ -0,0 +1,105 @@ +#ifndef MBGL_MAP_GEOMETRY_TILE +#define MBGL_MAP_GEOMETRY_TILE + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace mbgl { + +class GeometryTileLayer; + +enum class GeometryFeatureType { + Unknown = 0, + Point = 1, + LineString = 2, + Polygon = 3 +}; + +std::ostream& operator<<(std::ostream&, const GeometryFeatureType& type); + +template +class GeometryTileFeature { +public: + uint64_t id = 0; + GeometryFeatureType type = GeometryFeatureType::Unknown; + std::map properties; + T geometries; +}; + +template +std::ostream& operator<<(std::ostream&, const GeometryTileFeature& feature); + +template +class GeometryTileTagExtractor { +public: + GeometryTileTagExtractor(const GeometryTileLayer&); + + void setTags(const T&); + virtual mapbox::util::optional getValue(const std::string &key) const; + inline void setType(GeometryFeatureType type_) { type = type_; } + GeometryFeatureType getType() const { return type; } + +protected: + const GeometryTileLayer &layer; + GeometryFeatureType type = GeometryFeatureType::Unknown; +}; + + +template +class GeometryFilteredTileLayer { +public: + class iterator { + public: + iterator(const GeometryFilteredTileLayer&); + virtual void operator++(); + virtual bool operator!=(const iterator& other) const; + virtual const T& operator*() const; + + protected: + const GeometryFilteredTileLayer& parent; + bool valid = false; + }; + +public: + GeometryFilteredTileLayer(const GeometryTileLayer&, const FilterExpression&); + + iterator begin() const; + iterator end() const; + +public: + const GeometryTileLayer& layer; + const FilterExpression& filterExpression; +}; + +std::ostream& operator<<(std::ostream&, const PositionedGlyph&); + +class GeometryTileLayer { +public: + std::string name; + uint32_t extent = 4096; + std::vector keys; + std::unordered_map key_index; + std::vector values; + std::map> shaping; +}; + +class GeometryTile { +public: + GeometryTile& operator=(GeometryTile&& other); + +public: + std::map layers; +}; + +} + +#endif diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 2828b088429..1da9daef8fd 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -2,22 +2,10 @@ #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 @@ -44,17 +32,16 @@ VectorTileFeature::VectorTileFeature(pbf feature, const VectorTileLayer& layer) } } } else if (feature.tag == 3) { // type - type = (FeatureType)feature.varint(); + type = (GeometryFeatureType)feature.varint(); } else if (feature.tag == 4) { // geometry - geometry = feature.message(); + geometries = feature.message(); } else { feature.skip(); } } } - -std::ostream& mbgl::operator<<(std::ostream& os, const VectorTileFeature& feature) { +std::ostream& mbgl::operator<<(std::ostream& os, const GeometryTileFeature& feature) { os << "Feature(" << feature.id << "): " << feature.type << std::endl; for (const auto& prop : feature.properties) { os << " - " << prop.first << ": " << prop.second << std::endl; @@ -62,10 +49,6 @@ std::ostream& mbgl::operator<<(std::ostream& os, const VectorTileFeature& featur return os; } - -VectorTile::VectorTile() {} - - VectorTile::VectorTile(pbf tile) { while (tile.next()) { if (tile.tag == 3) { // layer @@ -77,16 +60,7 @@ VectorTile::VectorTile(pbf tile) { } } -VectorTile& VectorTile::operator=(VectorTile && other) { - if (this != &other) { - layers.swap(other.layers); - } - return *this; -} - -VectorTileLayer::VectorTileLayer(pbf layer) : data(layer) { - std::vector stacks; - +VectorTileLayer::VectorTileLayer(pbf layer) : layer_pbf(layer) { while (layer.next()) { if (layer.tag == 1) { // name name = layer.string(); @@ -103,61 +77,61 @@ VectorTileLayer::VectorTileLayer(pbf layer) : data(layer) { } } -FilteredVectorTileLayer::FilteredVectorTileLayer(const VectorTileLayer& layer_, const FilterExpression &filterExpression_) - : layer(layer_), - filterExpression(filterExpression_) { -} +FilteredVectorTileLayer::FilteredVectorTileLayer(const VectorTileLayer& layer_, const FilterExpression& filterExpression_) + : GeometryFilteredTileLayer(layer_, filterExpression_) {} FilteredVectorTileLayer::iterator FilteredVectorTileLayer::begin() const { - return iterator(*this, layer.data); + const VectorTileLayer *layer_ = static_cast(&layer); + + return FilteredVectorTileLayer::iterator(*this, layer_->layer_pbf); } FilteredVectorTileLayer::iterator FilteredVectorTileLayer::end() const { - return iterator(*this, pbf(layer.data.end, 0)); -} + const VectorTileLayer *layer_ = static_cast(&layer); -FilteredVectorTileLayer::iterator::iterator(const FilteredVectorTileLayer& parent_, const pbf& data_) - : parent(parent_), - feature(pbf()), - data(data_) { - operator++(); + return FilteredVectorTileLayer::iterator(*this, pbf(layer_->layer_pbf.end, 0)); } -VectorTileTagExtractor::VectorTileTagExtractor(const VectorTileLayer &layer) : layer_(layer) {} +FilteredVectorTileLayer::iterator::iterator(const FilteredVectorTileLayer& parent_, const pbf& data_pbf_) + : GeometryFilteredTileLayer::iterator(parent_), + feature_pbf(pbf()), + data_pbf(data_pbf_) {} +VectorTileTagExtractor::VectorTileTagExtractor(const VectorTileLayer& layer_) + : GeometryTileTagExtractor(layer_) {} -void VectorTileTagExtractor::setTags(const pbf &pbf) { - tags_ = pbf; +void VectorTileTagExtractor::setTags(const pbf& pbf) { + tags_pbf = pbf; } -mapbox::util::optional VectorTileTagExtractor::getValue(const std::string &key) const { +mapbox::util::optional VectorTileTagExtractor::getValue(const std::string& key) const { if (key == "$type") { - return Value(uint64_t(type_)); + return Value(uint64_t(type)); } 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. // tags are packed varints. They should have an even length. - pbf tags_pbf = tags_; + pbf tags_pbf_ = tags_pbf; uint32_t tag_key, tag_val; - while (tags_pbf) { - tag_key = tags_pbf.varint(); - if (!tags_pbf) { + 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(); + 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; @@ -169,10 +143,6 @@ mapbox::util::optional VectorTileTagExtractor::getValue(const std::string return value; } -void VectorTileTagExtractor::setType(FeatureType type) { - type_ = type; -} - template bool mbgl::evaluate(const FilterExpression&, const VectorTileTagExtractor&); void FilteredVectorTileLayer::iterator::operator++() { @@ -180,20 +150,20 @@ void FilteredVectorTileLayer::iterator::operator++() { const FilterExpression &expression = parent.filterExpression; - while (data.next(2)) { // feature - feature = data.message(); - pbf feature_pbf = feature; + while (data_pbf.next(2)) { // feature + feature_pbf = data_pbf.message(); + pbf feature_pbf_ = feature_pbf; - VectorTileTagExtractor extractor(parent.layer); + GeometryTileTagExtractor extractor(parent.layer); // Retrieve the basic information - while (feature_pbf.next()) { - if (feature_pbf.tag == 2) { // tags + 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 if (feature_pbf_.tag == 3) { // geometry type + extractor.setType(GeometryFeatureType(feature_pbf_.varint())); } else { - feature_pbf.skip(); + feature_pbf_.skip(); } } @@ -207,9 +177,9 @@ void FilteredVectorTileLayer::iterator::operator++() { } bool FilteredVectorTileLayer::iterator::operator!=(const iterator& other) const { - return !(data.data == other.data.data && data.end == other.data.end && valid == other.valid); + return !(data_pbf.data == other.data_pbf.data && data_pbf.end == other.data_pbf.end && valid == other.valid); } const pbf& FilteredVectorTileLayer::iterator:: operator*() const { - return feature; + return feature_pbf; } diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index 2d02ba3a0b2..bfa9e086abd 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -1,118 +1,69 @@ #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&); - uint64_t id = 0; - FeatureType type = FeatureType::Unknown; - std::map properties; - pbf geometry; +private: + const pbf feature_pbf; }; -std::ostream& operator<<(std::ostream&, const VectorTileFeature& feature); - +std::ostream& operator<<(std::ostream&, const GeometryTileFeature&); -class VectorTileTagExtractor { +class VectorTileTagExtractor : public GeometryTileTagExtractor { public: - VectorTileTagExtractor(const VectorTileLayer &layer); + VectorTileTagExtractor(const VectorTileLayer&); - void setTags(const pbf &pbf); + void setTags(const pbf&); mapbox::util::optional getValue(const std::string &key) const; - void setType(FeatureType type); - FeatureType getType() const; private: - const VectorTileLayer &layer_; - pbf tags_; - FeatureType type_ = FeatureType::Unknown; + pbf tags_pbf; }; -/* - * 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 { +class FilteredVectorTileLayer : public GeometryFilteredTileLayer { public: - class iterator { + class iterator : public GeometryFilteredTileLayer::iterator { public: - iterator(const FilteredVectorTileLayer& filter, const pbf& data); + iterator(const FilteredVectorTileLayer&, const pbf&); void operator++(); bool operator!=(const iterator& other) const; const pbf& operator*() const; private: - const FilteredVectorTileLayer& parent; - bool valid = false; - pbf feature; - pbf data; + pbf feature_pbf; + pbf data_pbf; }; public: - FilteredVectorTileLayer(const VectorTileLayer& layer, const FilterExpression &filterExpression); + FilteredVectorTileLayer(const VectorTileLayer&, const 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 GeometryTileLayer { +public: + VectorTileLayer(pbf); -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; + const pbf layer_pbf; }; -class VectorTile { +class VectorTile : public GeometryTile { public: - VectorTile(); - VectorTile(pbf data); - VectorTile& operator=(VectorTile&& other); - - std::map layers; + VectorTile(pbf); }; - - } #endif diff --git a/src/mbgl/style/filter_expression.cpp b/src/mbgl/style/filter_expression.cpp index 7d4f60b3ed3..e5a2e3abc3d 100644 --- a/src/mbgl/style/filter_expression.cpp +++ b/src/mbgl/style/filter_expression.cpp @@ -1,18 +1,18 @@ -#include +#include #include namespace mbgl { Value parseFeatureType(const Value& value) { if (value == std::string("Point")) { - return Value(uint64_t(FeatureType::Point)); + return Value(uint64_t(GeometryFeatureType::Point)); } else if (value == std::string("LineString")) { - return Value(uint64_t(FeatureType::LineString)); + return Value(uint64_t(GeometryFeatureType::LineString)); } else if (value == std::string("Polygon")) { - return Value(uint64_t(FeatureType::Polygon)); + return Value(uint64_t(GeometryFeatureType::Polygon)); } else { Log::Warning(Event::ParseStyle, "value for $type filter must be Point, LineString, or Polygon"); - return Value(uint64_t(FeatureType::Unknown)); + return Value(uint64_t(GeometryFeatureType::Unknown)); } } From 41c3b82d3e2a160cfa52d5d7c3e2e02eb81f32c0 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Wed, 4 Mar 2015 13:37:03 -0800 Subject: [PATCH 02/27] refs #928: bookmarking working build of refactor --- .../{geometry.hpp => pbf_geometry.hpp} | 12 +- src/mbgl/map/geometry_tile.cpp | 36 +++- src/mbgl/map/geometry_tile.hpp | 56 +++--- src/mbgl/map/tile_parser.cpp | 28 +-- src/mbgl/map/tile_parser.hpp | 9 +- src/mbgl/map/vector_tile.cpp | 180 ++++++++++-------- src/mbgl/map/vector_tile.hpp | 48 ++--- src/mbgl/renderer/fill_bucket.cpp | 28 +-- src/mbgl/renderer/fill_bucket.hpp | 4 +- src/mbgl/renderer/line_bucket.cpp | 31 +-- src/mbgl/renderer/line_bucket.hpp | 5 +- src/mbgl/renderer/symbol_bucket.cpp | 29 ++- src/mbgl/renderer/symbol_bucket.hpp | 10 +- 13 files changed, 233 insertions(+), 243 deletions(-) rename src/mbgl/geometry/{geometry.hpp => pbf_geometry.hpp} (83%) diff --git a/src/mbgl/geometry/geometry.hpp b/src/mbgl/geometry/pbf_geometry.hpp similarity index 83% rename from src/mbgl/geometry/geometry.hpp rename to src/mbgl/geometry/pbf_geometry.hpp index 484d17b36da..46380e6fecd 100644 --- a/src/mbgl/geometry/geometry.hpp +++ b/src/mbgl/geometry/pbf_geometry.hpp @@ -1,5 +1,5 @@ -#ifndef MBGL_GEOMETRY_GEOMETRY -#define MBGL_GEOMETRY_GEOMETRY +#ifndef MBGL_GEOMETRY_PBF_GEOMETRY +#define MBGL_GEOMETRY_PBF_GEOMETRY #include #include @@ -8,10 +8,10 @@ namespace mbgl { -class Geometry : private util::noncopyable { +class PBFGeometry : private util::noncopyable { public: - inline explicit Geometry(pbf& data); + inline explicit PBFGeometry(pbf& data); enum command : uint8_t { end = 0, @@ -30,14 +30,14 @@ class Geometry : private util::noncopyable { int32_t ox, oy; }; -Geometry::Geometry(pbf& data_) +PBFGeometry::PBFGeometry(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) { +PBFGeometry::command PBFGeometry::next(int32_t &rx, int32_t &ry) { if (data.data < data.end) { if (length == 0) { uint32_t cmd_length = static_cast(data.varint()); diff --git a/src/mbgl/map/geometry_tile.cpp b/src/mbgl/map/geometry_tile.cpp index 53272b10c6b..b337cd7c954 100644 --- a/src/mbgl/map/geometry_tile.cpp +++ b/src/mbgl/map/geometry_tile.cpp @@ -15,15 +15,39 @@ 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) { + os << " - " << prop.first << ": " << prop.second << std::endl; + } + return os; +} + +GeometryFilteredTileLayer::GeometryFilteredTileLayer(const GeometryTileLayer& 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); } return *this; } - -template -GeometryFilteredTileLayer::iterator::iterator(const GeometryFilteredTileLayer& parent_) - : parent(parent_) { - operator++(); -} diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index 6ca2b0eb569..7d8698d13e8 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -5,18 +5,19 @@ #include #include #include +#include +#include #include #include #include #include +#include #include #include namespace mbgl { -class GeometryTileLayer; - enum class GeometryFeatureType { Unknown = 0, Point = 1, @@ -24,58 +25,54 @@ enum class GeometryFeatureType { Polygon = 3 }; +typedef Coordinate GeometryPoint; +typedef std::vector GeometryLine; +typedef std::vector GeometryPolygon; + +using Geometry = mapbox::util::variant; + std::ostream& operator<<(std::ostream&, const GeometryFeatureType& type); -template +class GeometryTileLayer; + class GeometryTileFeature { +public: + GeometryTileFeature(); + + virtual Geometry nextGeometry(); + public: uint64_t id = 0; GeometryFeatureType type = GeometryFeatureType::Unknown; std::map properties; - T geometries; }; -template -std::ostream& operator<<(std::ostream&, const GeometryTileFeature& feature); +std::ostream& operator<<(std::ostream&, const GeometryTileFeature& feature); template class GeometryTileTagExtractor { public: GeometryTileTagExtractor(const GeometryTileLayer&); - void setTags(const T&); - virtual mapbox::util::optional getValue(const std::string &key) const; + inline void setTags(const T& tags_) { tags = tags_; } + mapbox::util::optional getValue(const std::string &key) const; + inline void setType(GeometryFeatureType type_) { type = type_; } - GeometryFeatureType getType() const { return type; } + inline GeometryFeatureType getType() const { return type; } protected: - const GeometryTileLayer &layer; + const GeometryTileLayer& layer; + T tags; GeometryFeatureType type = GeometryFeatureType::Unknown; }; - -template class GeometryFilteredTileLayer { -public: - class iterator { - public: - iterator(const GeometryFilteredTileLayer&); - virtual void operator++(); - virtual bool operator!=(const iterator& other) const; - virtual const T& operator*() const; - - protected: - const GeometryFilteredTileLayer& parent; - bool valid = false; - }; - public: GeometryFilteredTileLayer(const GeometryTileLayer&, const FilterExpression&); - iterator begin() const; - iterator end() const; + virtual GeometryTileFeature nextMatchingFeature(); -public: +protected: const GeometryTileLayer& layer; const FilterExpression& filterExpression; }; @@ -83,6 +80,9 @@ class GeometryFilteredTileLayer { std::ostream& operator<<(std::ostream&, const PositionedGlyph&); class GeometryTileLayer { +public: + virtual GeometryTileFeature nextFeature(); + public: std::string name; uint32_t extent = 4096; diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp index 43e754978bb..de9c5a82e0b 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 VectorTileLayer &layer = layer_it->second; + const GeometryTileLayer &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 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) { + GeometryFilteredTileLayer filtered_layer(layer, filter); + GeometryTileFeature feature = filtered_layer.nextMatchingFeature(); + while (feature.type != GeometryFeatureType::Unknown) { 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"); - } + Geometry geometry = feature.nextGeometry(); + while (!geometry.is()) { + bucket->addGeometry(geometry); + geometry = feature.nextGeometry(); } + + feature = filtered_layer.nextMatchingFeature(); } } -std::unique_ptr TileParser::createFillBucket(const VectorTileLayer &layer, +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), @@ -241,7 +241,7 @@ std::unique_ptr TileParser::createFillBucket(const VectorTileLayer &laye return obsolete() ? nullptr : std::move(bucket); } -std::unique_ptr TileParser::createLineBucket(const VectorTileLayer &layer, +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), @@ -252,7 +252,7 @@ std::unique_ptr TileParser::createLineBucket(const VectorTileLayer &laye return obsolete() ? nullptr : std::move(bucket); } -std::unique_ptr TileParser::createSymbolBucket(const VectorTileLayer &layer, +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); diff --git a/src/mbgl/map/tile_parser.hpp b/src/mbgl/map/tile_parser.hpp index 228557846c6..841ae1749c1 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 @@ -52,11 +53,11 @@ class TileParser : private util::noncopyable 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 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); - template void addBucketGeometries(Bucket& bucket, const VectorTileLayer& layer, const FilterExpression& filter); + template void addBucketGeometries(Bucket& bucket, const GeometryTileLayer& 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 1da9daef8fd..a1ab4ec809c 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -1,18 +1,20 @@ #include +#include #include #include +#include #include using namespace mbgl; -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 GeometryTileLayer& 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(); @@ -31,22 +33,64 @@ VectorTileFeature::VectorTileFeature(pbf feature, const VectorTileLayer& layer) throw std::runtime_error("uneven number of feature tag ids"); } } - } else if (feature.tag == 3) { // type - type = (GeometryFeatureType)feature.varint(); - } else if (feature.tag == 4) { // geometry - geometries = feature.message(); + } else if (feature_pbf.tag == 3) { // type + type = (GeometryFeatureType)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 GeometryTileFeature& feature) { - os << "Feature(" << feature.id << "): " << feature.type << std::endl; - for (const auto& prop : feature.properties) { - os << " - " << prop.first << ": " << prop.second << std::endl; +Geometry VectorTileFeature::nextGeometry() { + pbf current_geometry_pbf = geometry_pbf.message(); + PBFGeometry current_geometry(current_geometry_pbf); + int32_t x, y; + Geometry result; + result.set(); + + if (multigeometry || geometry_pbf.next(4)) { + if (type == GeometryFeatureType::Point) { + current_geometry.next(x, y); + GeometryPoint point(x, y); + result.set(point); + } else if (type == GeometryFeatureType::LineString) { + GeometryLine line; + PBFGeometry::command cmd; + while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { + if (cmd == PBFGeometry::move_to) { + multigeometry = true; + result.set(line); + break; + } else { + line.emplace_back(x, y); + } + } + if (!multigeometry) { + result.set(line); + } + } else if (type == GeometryFeatureType::Polygon) { + GeometryPolygon polygon; + PBFGeometry::command cmd; + while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { + if (cmd == PBFGeometry::move_to) { + multigeometry = true; + result.set(polygon); + break; + } else { +// polygon.emplace_back(x, y); + } + } + if (!multigeometry) { + result.set(polygon); + } + } else { + throw std::runtime_error("unrecognized geometry type"); + } } - return os; + + return std::move(result); } VectorTile::VectorTile(pbf tile) { @@ -60,51 +104,34 @@ VectorTile::VectorTile(pbf tile) { } } -VectorTileLayer::VectorTileLayer(pbf layer) : layer_pbf(layer) { - while (layer.next()) { - if (layer.tag == 1) { // name - name = layer.string(); - } else if (layer.tag == 3) { // keys - keys.emplace_back(layer.string()); +VectorTileLayer::VectorTileLayer(pbf layer) : feature_pbf(layer) { + while (feature_pbf.next()) { + if (feature_pbf.tag == 1) { // name + name = feature_pbf.string(); + } else if (feature_pbf.tag == 3) { // keys + keys.emplace_back(feature_pbf.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 if (feature_pbf.tag == 4) { // values + values.emplace_back(std::move(parseValue(feature_pbf.message()))); + } else if (feature_pbf.tag == 5) { // extent + extent = feature_pbf.varint(); } else { - layer.skip(); + feature_pbf.skip(); } } } FilteredVectorTileLayer::FilteredVectorTileLayer(const VectorTileLayer& layer_, const FilterExpression& filterExpression_) - : GeometryFilteredTileLayer(layer_, filterExpression_) {} - -FilteredVectorTileLayer::iterator FilteredVectorTileLayer::begin() const { - const VectorTileLayer *layer_ = static_cast(&layer); - - return FilteredVectorTileLayer::iterator(*this, layer_->layer_pbf); -} - -FilteredVectorTileLayer::iterator FilteredVectorTileLayer::end() const { - const VectorTileLayer *layer_ = static_cast(&layer); - - return FilteredVectorTileLayer::iterator(*this, pbf(layer_->layer_pbf.end, 0)); + : GeometryFilteredTileLayer(layer_, filterExpression_) { + feature_pbf = layer_.feature_pbf; } -FilteredVectorTileLayer::iterator::iterator(const FilteredVectorTileLayer& parent_, const pbf& data_pbf_) - : GeometryFilteredTileLayer::iterator(parent_), - feature_pbf(pbf()), - data_pbf(data_pbf_) {} - -VectorTileTagExtractor::VectorTileTagExtractor(const VectorTileLayer& layer_) - : GeometryTileTagExtractor(layer_) {} - -void VectorTileTagExtractor::setTags(const pbf& pbf) { - tags_pbf = pbf; -} +template <> +GeometryTileTagExtractor::GeometryTileTagExtractor(const GeometryTileLayer& layer_) + : layer(layer_) {} -mapbox::util::optional VectorTileTagExtractor::getValue(const std::string& key) const { +template <> +mapbox::util::optional GeometryTileTagExtractor::getValue(const std::string& key) const { if (key == "$type") { return Value(uint64_t(type)); } @@ -117,7 +144,7 @@ mapbox::util::optional VectorTileTagExtractor::getValue(const std::string // Now loop through all the key/value pair tags. // tags are packed varints. They should have an even length. - pbf tags_pbf_ = tags_pbf; + pbf tags_pbf_ = tags; uint32_t tag_key, tag_val; while (tags_pbf_) { tag_key = tags_pbf_.varint(); @@ -143,43 +170,40 @@ mapbox::util::optional VectorTileTagExtractor::getValue(const std::string return value; } -template bool mbgl::evaluate(const FilterExpression&, const VectorTileTagExtractor&); +template bool mbgl::evaluate(const FilterExpression&, const GeometryTileTagExtractor&); -void FilteredVectorTileLayer::iterator::operator++() { - valid = false; +GeometryTileFeature FilteredVectorTileLayer::nextMatchingFeature() { + GeometryTileFeature result; - const FilterExpression &expression = parent.filterExpression; + if (feature_pbf.next(2)) { + pbf current_feature_pbf = feature_pbf.message(); - while (data_pbf.next(2)) { // feature - feature_pbf = data_pbf.message(); - pbf feature_pbf_ = feature_pbf; + GeometryTileTagExtractor extractor(layer); - GeometryTileTagExtractor 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())); + while (current_feature_pbf.next()) { + if (current_feature_pbf.tag == 2) { // tags + extractor.setTags(current_feature_pbf); + } else if (current_feature_pbf.tag == 3) { // geometry type + extractor.setType(GeometryFeatureType(current_feature_pbf.varint())); } else { - feature_pbf_.skip(); + current_feature_pbf.skip(); } } - if (evaluate(expression, extractor)) { - valid = true; - return; // data loop - } else { - valid = false; + if (evaluate(filterExpression, extractor)) { + result = VectorTileFeature(current_feature_pbf.message(), layer); } } -} -bool FilteredVectorTileLayer::iterator::operator!=(const iterator& other) const { - return !(data_pbf.data == other.data_pbf.data && data_pbf.end == other.data_pbf.end && valid == other.valid); + return std::move(result); } -const pbf& FilteredVectorTileLayer::iterator:: operator*() const { - return feature_pbf; +GeometryTileFeature VectorTileLayer::nextFeature() { + GeometryTileFeature result; + + if (feature_pbf.next(2)) { + result = VectorTileFeature(feature_pbf.message(), *this); + } + + return std::move(result); } diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index bfa9e086abd..f83eebb1edd 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -2,6 +2,7 @@ #define MBGL_MAP_VECTOR_TILE #include +#include #include #include @@ -9,54 +10,37 @@ namespace mbgl { class VectorTileLayer; -class VectorTileFeature : public GeometryTileFeature { +class VectorTileFeature : public GeometryTileFeature { public: - VectorTileFeature(pbf, const VectorTileLayer&); + VectorTileFeature(pbf, const GeometryTileLayer&); + + Geometry nextGeometry(); private: - const pbf feature_pbf; + pbf geometry_pbf; + bool multigeometry = false; }; -std::ostream& operator<<(std::ostream&, const GeometryTileFeature&); - -class VectorTileTagExtractor : public GeometryTileTagExtractor { +class FilteredVectorTileLayer : public GeometryFilteredTileLayer { public: - VectorTileTagExtractor(const VectorTileLayer&); + FilteredVectorTileLayer(const VectorTileLayer&, const FilterExpression&); - void setTags(const pbf&); - mapbox::util::optional getValue(const std::string &key) const; + GeometryTileFeature nextMatchingFeature(); private: - pbf tags_pbf; -}; - -class FilteredVectorTileLayer : public GeometryFilteredTileLayer { -public: - class iterator : public GeometryFilteredTileLayer::iterator { - public: - iterator(const FilteredVectorTileLayer&, const pbf&); - void operator++(); - bool operator!=(const iterator& other) const; - const pbf& operator*() const; - - private: - pbf feature_pbf; - pbf data_pbf; - }; + pbf feature_pbf; -public: - FilteredVectorTileLayer(const VectorTileLayer&, const FilterExpression&); - - iterator begin() const; - iterator end() const; }; class VectorTileLayer : public GeometryTileLayer { + friend class FilteredVectorTileLayer; public: VectorTileLayer(pbf); -public: - const pbf layer_pbf; + GeometryTileFeature nextFeature(); + +private: + pbf feature_pbf; }; class VectorTile : public GeometryTile { diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index c632244d775..86b9daeada4 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,24 +64,13 @@ 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; - } - } - line.emplace_back(x, y); - } +void FillBucket::addGeometry(const Geometry& fill) { + const GeometryPolygon& polygon = fill.get(); - if (line.size()) { + for (auto line_it = polygon.begin(); line_it != polygon.end(); line_it++) { + for (auto point_it = line_it->begin(); point_it != line_it->end(); point_it++) { + line.emplace_back(point_it->x, point_it->y); + } clipper.AddPath(line, ClipperLib::ptSubject, true); line.clear(); hasVertices = true; diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index b674f104e4e..bec48260579 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 Geometry& fill); void tessellate(); void drawElements(PlainShader& shader); diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index fc9482d1d68..40b69a0ab57 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,7 +41,9 @@ struct TriangleElement { typedef uint16_t PointElement; -void LineBucket::addGeometry(const std::vector& vertices) { +void LineBucket::addGeometry(const Geometry &line) { + const GeometryLine& vertices = line.get(); + auto &layout = *styleLayout; // TODO: use roundLimit // const float roundLimit = geometry.round_limit; diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index 1059cee71d4..9239634332d 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,8 +37,7 @@ class LineBucket : public Bucket { const mat4 &matrix) override; bool hasData() const override; - void addGeometry(pbf& data); - void addGeometry(const std::vector& line); + void addGeometry(const Geometry& line); bool hasPoints() const; diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 63630e1c06c..245eb7329c5 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 @@ -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 VectorTileLayer &layer, +std::vector SymbolBucket::processFeatures(const GeometryTileLayer &layer, const FilterExpression &filter, GlyphStore &glyphStore, const Sprite &sprite) { @@ -64,9 +64,9 @@ 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}; + GeometryFilteredTileLayer filtered_layer(layer, filter); + GeometryTileFeature feature = filtered_layer.nextMatchingFeature(); + while (feature.type != GeometryFeatureType::Unknown) { SymbolFeature ft; @@ -97,22 +97,21 @@ std::vector SymbolBucket::processFeatures(const VectorTileLayer & auto &multiline = ft.geometry; - // Decode line - Geometry::command cmd; - pbf geom(feature.geometry); - Geometry geometry(geom); + Geometry geometry = feature.nextGeometry(); + const GeometryLine& line = geometry.get(); bool first = true; - int32_t x, y; - while ((cmd = geometry.next(x, y)) != Geometry::end) { - if (first || cmd == Geometry::move_to) { + for (auto point_it = line.begin(); point_it != line.end(); point_it++) { + if (first) { multiline.emplace_back(); first = false; } - multiline.back().emplace_back(x, y); + multiline.back().emplace_back(point_it->x, point_it->y); } features.push_back(std::move(ft)); } + + feature = filtered_layer.nextMatchingFeature(); } if (layout.placement == PlacementType::Line) { @@ -125,7 +124,7 @@ 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..ce2629d3ae7 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -2,11 +2,11 @@ #define MBGL_RENDERER_SYMBOLBUCKET #include +#include #include #include #include #include -#include #include #include #include @@ -64,7 +64,7 @@ class SymbolBucket : public Bucket { bool hasTextData() const; bool hasIconData() const; - void addFeatures(const VectorTileLayer &layer, const FilterExpression &filter, + void addFeatures(const GeometryTileLayer &layer, const FilterExpression &filter, const Tile::ID &id, SpriteAtlas &spriteAtlas, Sprite &sprite, GlyphAtlas &glyphAtlas, GlyphStore &glyphStore); @@ -77,11 +77,9 @@ class SymbolBucket : public Bucket { private: - std::vector processFeatures(const VectorTileLayer &layer, const FilterExpression &filter, GlyphStore &glyphStore, const Sprite &sprite); - - - void addFeature(const std::vector &line, const Shaping &shaping, const GlyphPositions &face, const Rect &image); + std::vector processFeatures(const GeometryTileLayer &layer, const FilterExpression &filter, GlyphStore &glyphStore, const Sprite &sprite); + void addFeature(const GeometryLine &line, const Shaping &shaping, const GlyphPositions &face, const Rect &image); // Adds placed items to the buffer. template From 0a8a0aee908484f50519cf6cfee3c46fcf34db83 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 6 Mar 2015 12:08:42 -0800 Subject: [PATCH 03/27] move to abstract base classes & shared pointers --- src/mbgl/map/geometry_tile.cpp | 20 +-------- src/mbgl/map/geometry_tile.hpp | 36 +++++++++-------- src/mbgl/map/tile_parser.cpp | 22 +++++----- src/mbgl/map/tile_parser.hpp | 8 ++-- src/mbgl/map/vector_tile.cpp | 63 ++++++++++++++++------------- src/mbgl/map/vector_tile.hpp | 14 ++++--- src/mbgl/renderer/symbol_bucket.cpp | 18 ++++----- src/mbgl/renderer/symbol_bucket.hpp | 5 ++- 8 files changed, 91 insertions(+), 95 deletions(-) diff --git a/src/mbgl/map/geometry_tile.cpp b/src/mbgl/map/geometry_tile.cpp index b337cd7c954..0d7931b777e 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 7d8698d13e8..4a7e05b902e 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 @@ class GeometryTileFeature { 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 de9c5a82e0b..de89143ae37 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 841ae1749c1..ee134911fc2 100644 --- a/src/mbgl/map/tile_parser.hpp +++ b/src/mbgl/map/tile_parser.hpp @@ -53,11 +53,11 @@ class TileParser : private util::noncopyable 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 a1ab4ec809c..338f2acaeb6 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 f83eebb1edd..f16e98c3bd5 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 @@ class VectorTileFeature : public GeometryTileFeature { 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 @@ class VectorTileLayer : public GeometryTileLayer { 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 245eb7329c5..60315c8fe0c 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 ce2629d3ae7..d9b461afaa4 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 @@ class SymbolBucket : public Bucket { 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 @@ class SymbolBucket : public Bucket { 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); From 787cedb593663bbfe42bad6a938e5b3eb614e30c Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 6 Mar 2015 12:16:10 -0800 Subject: [PATCH 04/27] fix reference --- src/mbgl/map/geometry_tile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mbgl/map/geometry_tile.cpp b/src/mbgl/map/geometry_tile.cpp index 0d7931b777e..defff0ebfb4 100644 --- a/src/mbgl/map/geometry_tile.cpp +++ b/src/mbgl/map/geometry_tile.cpp @@ -18,7 +18,7 @@ std::ostream& mbgl::operator<<(std::ostream& os, const GeometryFeatureType& type std::ostream& mbgl::operator<<(std::ostream& os, const GeometryTileFeature& feature) { os << "Feature(" << feature.id << "): " << feature.type << std::endl; for (const auto& prop : feature.properties) { - os << " - " << prop.first << ": " << prop.second << std::endl; + os << " - " << prop.first << ": " << &prop.second << std::endl; } return os; } From 4d9c1a0f33019e688a58d673623a9e3e340993bd Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 6 Mar 2015 12:48:27 -0800 Subject: [PATCH 05/27] iterate through fresh copy of layer data --- src/mbgl/map/vector_tile.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 338f2acaeb6..5af24d66085 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -110,18 +110,18 @@ void VectorTile::logDebug() const { VectorTileLayer::VectorTileLayer(pbf layer_pbf) : feature_pbf(layer_pbf) { - while (feature_pbf.next()) { - if (feature_pbf.tag == 1) { // name - name = feature_pbf.string(); - } else if (feature_pbf.tag == 3) { // keys - keys.emplace_back(feature_pbf.string()); + while (layer_pbf.next()) { + if (layer_pbf.tag == 1) { // name + name = layer_pbf.string(); + } else if (layer_pbf.tag == 3) { // keys + keys.emplace_back(layer_pbf.string()); key_index.emplace(keys.back(), keys.size() - 1); - } else if (feature_pbf.tag == 4) { // values - values.emplace_back(std::move(parseValue(feature_pbf.message()))); - } else if (feature_pbf.tag == 5) { // extent - extent = feature_pbf.varint(); + } 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 { - feature_pbf.skip(); + layer_pbf.skip(); } } } From e379756f6239afee6fff49ca44e3bb9631a0baf7 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 6 Mar 2015 12:48:40 -0800 Subject: [PATCH 06/27] proper move --- src/mbgl/map/vector_tile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 5af24d66085..5914338b38a 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -202,7 +202,7 @@ util::ptr FilteredVectorTileLayer::nextMatchingFeature() { } util::ptr VectorTileLayer::createFilter(const FilterExpression& filterExpression) { - return std::make_shared(shared_from_this(), filterExpression); + return std::move(std::make_shared(shared_from_this(), filterExpression)); } util::ptr VectorTileLayer::nextFeature() { From 91dc0ba06f501d3a75bb253fbf7083a22c5111d3 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 6 Mar 2015 12:48:49 -0800 Subject: [PATCH 07/27] no need for while loop --- src/mbgl/map/vector_tile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 5914338b38a..72142f0a0a6 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -206,7 +206,7 @@ util::ptr VectorTileLayer::createFilter(const FilterE } util::ptr VectorTileLayer::nextFeature() { - while (feature_pbf.next(2)) { + if (feature_pbf.next(2)) { return std::move(std::make_shared(feature_pbf.message(), shared_from_this())); } From 685aa01043e765eb9b0a176fea6524a5b0ac0f6e Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 6 Mar 2015 16:53:11 -0800 Subject: [PATCH 08/27] pass actual feature pbf when filtering layer features --- src/mbgl/map/vector_tile.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 72142f0a0a6..235a4151d74 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -179,13 +179,14 @@ template bool mbgl::evaluate(const FilterExpression&, const GeometryTileTagExtra util::ptr FilteredVectorTileLayer::nextMatchingFeature() { while (feature_pbf.next(2)) { - pbf current_feature_pbf = feature_pbf.message(); + pbf matching_feature_pbf = feature_pbf.message(); + pbf current_feature_pbf = matching_feature_pbf; GeometryTileTagExtractor extractor(layer); while (current_feature_pbf.next()) { if (current_feature_pbf.tag == 2) { // tags - extractor.setTags(current_feature_pbf); + extractor.setTags(current_feature_pbf.message()); } else if (current_feature_pbf.tag == 3) { // geometry type extractor.setType(GeometryFeatureType(current_feature_pbf.varint())); } else { @@ -194,7 +195,7 @@ util::ptr FilteredVectorTileLayer::nextMatchingFeature() { } if (evaluate(filterExpression, extractor)) { - return std::move(std::make_shared(current_feature_pbf.message(), layer)); + return std::move(std::make_shared(matching_feature_pbf, layer)); } } From 405137700becde67e4eca33b2d31ce34e32c4dd8 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 6 Mar 2015 17:47:14 -0800 Subject: [PATCH 09/27] parse geometry collections from the pbfs; iterate geometries in buckets --- src/mbgl/map/geometry_tile.hpp | 4 +- src/mbgl/map/tile_parser.cpp | 6 +- src/mbgl/map/vector_tile.cpp | 43 +-- src/mbgl/map/vector_tile.hpp | 3 +- src/mbgl/renderer/fill_bucket.cpp | 11 +- src/mbgl/renderer/fill_bucket.hpp | 2 +- src/mbgl/renderer/line_bucket.cpp | 448 ++++++++++++++-------------- src/mbgl/renderer/line_bucket.hpp | 2 +- src/mbgl/renderer/symbol_bucket.cpp | 15 +- 9 files changed, 270 insertions(+), 264 deletions(-) diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index 4a7e05b902e..81960c981e8 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -32,13 +32,15 @@ typedef std::vector GeometryPolygon; using Geometry = mapbox::util::variant; +typedef std::vector GeometryCollection; + std::ostream& operator<<(std::ostream&, const GeometryFeatureType& type); class GeometryTileLayer; class GeometryTileFeature { public: - virtual Geometry nextGeometry() = 0; + virtual GeometryCollection nextGeometry() = 0; public: uint64_t id = 0; diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp index de89143ae37..861141b1fa0 100644 --- a/src/mbgl/map/tile_parser.cpp +++ b/src/mbgl/map/tile_parser.cpp @@ -220,10 +220,12 @@ template if (obsolete()) return; - Geometry geometry = feature->nextGeometry(); - while (!geometry.is()) { + GeometryCollection geometry = feature->nextGeometry(); + if (geometry.size()) { bucket->addGeometry(geometry); geometry = feature->nextGeometry(); + } else if (debug::tileParseWarnings) { + fprintf(stderr, "[WARNING] geometry is empty\n"); } feature = filtered_layer->nextMatchingFeature(); diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 235a4151d74..332534f25a7 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -43,47 +43,50 @@ VectorTileFeature::VectorTileFeature(pbf feature_pbf, const util::ptr(); - if (multigeometry || geometry_pbf.next(4)) { + while (geometry_pbf.next(4)) { // geometry if (type == GeometryFeatureType::Point) { current_geometry.next(x, y); GeometryPoint point(x, y); - result.set(point); + result.emplace_back(GeometryPoint(x, y)); } else if (type == GeometryFeatureType::LineString) { GeometryLine line; PBFGeometry::command cmd; while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { if (cmd == PBFGeometry::move_to) { - multigeometry = true; - result.set(line); - break; - } else { - line.emplace_back(x, y); + if (!line.empty()) { + result.push_back(line); + line.clear(); + } } + line.emplace_back(x, y); } - if (!multigeometry) { - result.set(line); + if (line.size()) { + result.push_back(line); } } else if (type == GeometryFeatureType::Polygon) { - GeometryPolygon polygon; + GeometryLine line; PBFGeometry::command cmd; while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { if (cmd == PBFGeometry::move_to) { - multigeometry = true; - result.set(polygon); - break; - } else { -// polygon.emplace_back(x, y); + if (line.size()) { + result.push_back(line); + line.clear(); + } } + line.emplace_back(x, y); } - if (!multigeometry) { - result.set(polygon); + + if (line.size()) { + result.push_back(line); + line.clear(); } } else { throw std::runtime_error("unrecognized geometry type"); diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index f16e98c3bd5..85ec09bede2 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -15,11 +15,10 @@ class VectorTileFeature : public GeometryTileFeature { public: VectorTileFeature(pbf, const util::ptr); - Geometry nextGeometry(); + GeometryCollection nextGeometry(); private: pbf geometry_pbf; - bool multigeometry = false; }; class FilteredVectorTileLayer : public GeometryFilteredTileLayer { diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index 86b9daeada4..18e337f9115 100644 --- a/src/mbgl/renderer/fill_bucket.cpp +++ b/src/mbgl/renderer/fill_bucket.cpp @@ -64,12 +64,11 @@ FillBucket::~FillBucket() { } } -void FillBucket::addGeometry(const Geometry& fill) { - const GeometryPolygon& polygon = fill.get(); - - for (auto line_it = polygon.begin(); line_it != polygon.end(); line_it++) { - for (auto point_it = line_it->begin(); point_it != line_it->end(); point_it++) { - line.emplace_back(point_it->x, point_it->y); +void FillBucket::addGeometry(const GeometryCollection& geometryCollection) { + for (auto& line_ : geometryCollection) { + const GeometryLine& vertices = line_.get(); + for (auto& v : vertices) { + line.emplace_back(ClipperLib::IntPoint(v.x, v.y)); } clipper.AddPath(line, ClipperLib::ptSubject, true); line.clear(); diff --git a/src/mbgl/renderer/fill_bucket.hpp b/src/mbgl/renderer/fill_bucket.hpp index bec48260579..46b8f538574 100644 --- a/src/mbgl/renderer/fill_bucket.hpp +++ b/src/mbgl/renderer/fill_bucket.hpp @@ -49,7 +49,7 @@ class FillBucket : public Bucket { const mat4 &matrix) override; bool hasData() const override; - void addGeometry(const Geometry& fill); + 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 40b69a0ab57..1f2e26c1661 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -41,290 +41,292 @@ struct TriangleElement { typedef uint16_t PointElement; -void LineBucket::addGeometry(const Geometry &line) { - const GeometryLine& vertices = line.get(); +void LineBucket::addGeometry(const GeometryCollection& geometryCollection) { + for (auto& line : geometryCollection) { + const GeometryLine& vertices = line.get(); - auto &layout = *styleLayout; - // TODO: use roundLimit - // const float roundLimit = geometry.round_limit; + auto &layout = *styleLayout; + // TODO: use roundLimit + // const float roundLimit = geometry.round_limit; - if (vertices.size() < 2) { - // fprintf(stderr, "a line must have at least two vertices\n"); - return; - } - - Coordinate firstVertex = vertices.front(); - Coordinate lastVertex = vertices.back(); - bool closed = firstVertex.x == lastVertex.x && firstVertex.y == lastVertex.y; - - if (vertices.size() == 2 && closed) { - // fprintf(stderr, "a line may not have coincident points\n"); - return; - } + if (vertices.size() < 2) { + // fprintf(stderr, "a line must have at least two vertices\n"); + return; + } - CapType beginCap = layout.cap; - CapType endCap = closed ? CapType::Butt : layout.cap; + Coordinate firstVertex = vertices.front(); + Coordinate lastVertex = vertices.back(); + bool closed = firstVertex.x == lastVertex.x && firstVertex.y == lastVertex.y; - JoinType currentJoin = JoinType::Miter; + if (vertices.size() == 2 && closed) { + // fprintf(stderr, "a line may not have coincident points\n"); + return; + } - Coordinate currentVertex = Coordinate::null(), - prevVertex = Coordinate::null(), - nextVertex = Coordinate::null(); - vec2 prevNormal = vec2::null(), - nextNormal = vec2::null(); + CapType beginCap = layout.cap; + CapType endCap = closed ? CapType::Butt : layout.cap; - int32_t e1 = -1, e2 = -1, e3 = -1; + JoinType currentJoin = JoinType::Miter; - int8_t flip = 1; - double distance = 0; + Coordinate currentVertex = Coordinate::null(), + prevVertex = Coordinate::null(), + nextVertex = Coordinate::null(); + vec2 prevNormal = vec2::null(), + nextNormal = vec2::null(); - if (closed) { - currentVertex = vertices[vertices.size() - 2]; - nextNormal = util::normal(currentVertex, lastVertex); - } + int32_t e1 = -1, e2 = -1, e3 = -1; - int32_t start_vertex = (int32_t)vertexBuffer.index(); + int8_t flip = 1; + double distance = 0; - std::vector triangle_store; - std::vector point_store; + if (closed) { + currentVertex = vertices[vertices.size() - 2]; + nextNormal = util::normal(currentVertex, lastVertex); + } - for (size_t i = 0; i < vertices.size(); ++i) { - if (nextNormal) prevNormal = { -nextNormal.x, -nextNormal.y }; - if (currentVertex) prevVertex = currentVertex; + int32_t start_vertex = (int32_t)vertexBuffer.index(); - currentVertex = vertices[i]; - currentJoin = layout.join; + std::vector triangle_store; + std::vector point_store; - if (prevVertex) distance += util::dist(currentVertex, prevVertex); + for (size_t i = 0; i < vertices.size(); ++i) { + if (nextNormal) prevNormal = { -nextNormal.x, -nextNormal.y }; + if (currentVertex) prevVertex = currentVertex; - // Find the next vertex. - if (i + 1 < vertices.size()) { - nextVertex = vertices[i + 1]; - } else { - nextVertex = Coordinate::null(); - } + currentVertex = vertices[i]; + currentJoin = layout.join; - // If the line is closed, we treat the last vertex like the first vertex. - if (!nextVertex && closed) { - nextVertex = vertices[1]; - } + if (prevVertex) distance += util::dist(currentVertex, prevVertex); - if (nextVertex) { - // if two consecutive vertices exist, skip one - if (currentVertex.x == nextVertex.x && currentVertex.y == nextVertex.y) continue; - } + // Find the next vertex. + if (i + 1 < vertices.size()) { + nextVertex = vertices[i + 1]; + } else { + nextVertex = Coordinate::null(); + } - // Calculate the normal towards the next vertex in this line. In case - // there is no next vertex, pretend that the line is continuing straight, - // meaning that we are just reversing the previous normal - if (nextVertex) { - nextNormal = util::normal(currentVertex, nextVertex); - } else { - nextNormal = { -prevNormal.x, -prevNormal.y }; - } + // If the line is closed, we treat the last vertex like the first vertex. + if (!nextVertex && closed) { + nextVertex = vertices[1]; + } - // If we still don't have a previous normal, this is the beginning of a - // non-closed line, so we're doing a straight "join". - if (!prevNormal) { - prevNormal = { -nextNormal.x, -nextNormal.y }; - } + if (nextVertex) { + // if two consecutive vertices exist, skip one + if (currentVertex.x == nextVertex.x && currentVertex.y == nextVertex.y) continue; + } - // Determine the normal of the join extrusion. It is the angle bisector - // of the segments between the previous line and the next line. - vec2 joinNormal = { - prevNormal.x + nextNormal.x, - prevNormal.y + nextNormal.y - }; - - // Cross product yields 0..1 depending on whether they are parallel - // or perpendicular. - double joinAngularity = nextNormal.x * joinNormal.y - nextNormal.y * joinNormal.x; - joinNormal.x /= joinAngularity; - joinNormal.y /= joinAngularity; - double roundness = std::fmax(std::abs(joinNormal.x), std::abs(joinNormal.y)); - - - // Switch to miter joins if the angle is very low. - if (currentJoin != JoinType::Miter) { - if (std::fabs(joinAngularity) < 0.5 && roundness < layout.miter_limit) { - currentJoin = JoinType::Miter; + // Calculate the normal towards the next vertex in this line. In case + // there is no next vertex, pretend that the line is continuing straight, + // meaning that we are just reversing the previous normal + if (nextVertex) { + nextNormal = util::normal(currentVertex, nextVertex); + } else { + nextNormal = { -prevNormal.x, -prevNormal.y }; } - } - // Add offset square begin cap. - if (!prevVertex && beginCap == CapType::Square) { - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * (prevNormal.x + prevNormal.y), flip * (-prevNormal.x + prevNormal.y), // extrude normal - 0, 0, distance) - start_vertex; // texture normal + // If we still don't have a previous normal, this is the beginning of a + // non-closed line, so we're doing a straight "join". + if (!prevNormal) { + prevNormal = { -nextNormal.x, -nextNormal.y }; + } - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + // Determine the normal of the join extrusion. It is the angle bisector + // of the segments between the previous line and the next line. + vec2 joinNormal = { + prevNormal.x + nextNormal.x, + prevNormal.y + nextNormal.y + }; + + // Cross product yields 0..1 depending on whether they are parallel + // or perpendicular. + double joinAngularity = nextNormal.x * joinNormal.y - nextNormal.y * joinNormal.x; + joinNormal.x /= joinAngularity; + joinNormal.y /= joinAngularity; + double roundness = std::fmax(std::abs(joinNormal.x), std::abs(joinNormal.y)); + + + // Switch to miter joins if the angle is very low. + if (currentJoin != JoinType::Miter) { + if (std::fabs(joinAngularity) < 0.5 && roundness < layout.miter_limit) { + currentJoin = JoinType::Miter; + } + } - // Add second vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * (prevNormal.x - prevNormal.y), flip * (prevNormal.x + prevNormal.y), // extrude normal - 0, 1, distance) - start_vertex; // texture normal + // Add offset square begin cap. + if (!prevVertex && beginCap == CapType::Square) { + // Add first vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + flip * (prevNormal.x + prevNormal.y), flip * (-prevNormal.x + prevNormal.y), // extrude normal + 0, 0, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - } + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - // Add offset square end cap. - else if (!nextVertex && endCap == CapType::Square) { - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - nextNormal.x - flip * nextNormal.y, flip * nextNormal.x + nextNormal.y, // extrude normal - 0, 0, distance) - start_vertex; // texture normal + // Add second vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + flip * (prevNormal.x - prevNormal.y), flip * (prevNormal.x + prevNormal.y), // extrude normal + 0, 1, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; + } - // Add second vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - nextNormal.x + flip * nextNormal.y, -flip * nextNormal.x + nextNormal.y, // extrude normal - 0, 1, distance) - start_vertex; // texture normal + // Add offset square end cap. + else if (!nextVertex && endCap == CapType::Square) { + // Add first vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + nextNormal.x - flip * nextNormal.y, flip * nextNormal.x + nextNormal.y, // extrude normal + 0, 0, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - } + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - else if (currentJoin == JoinType::Miter) { - // MITER JOIN - if (std::fabs(joinAngularity) < 0.01) { - // The two normals are almost parallel. - joinNormal.x = -nextNormal.y; - joinNormal.y = nextNormal.x; - } else if (roundness > layout.miter_limit) { - // If the miter grows too large, flip the direction to make a - // bevel join. - joinNormal.x = (prevNormal.x - nextNormal.x) / joinAngularity; - joinNormal.y = (prevNormal.y - nextNormal.y) / joinAngularity; - } + // Add second vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + nextNormal.x + flip * nextNormal.y, -flip * nextNormal.x + nextNormal.y, // extrude normal + 0, 1, distance) - start_vertex; // texture normal - if (roundness > layout.miter_limit) { - flip = -flip; + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; } - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * joinNormal.x, flip * joinNormal.y, // extrude normal - 0, 0, distance) - start_vertex; // texture normal + else if (currentJoin == JoinType::Miter) { + // MITER JOIN + if (std::fabs(joinAngularity) < 0.01) { + // The two normals are almost parallel. + joinNormal.x = -nextNormal.y; + joinNormal.y = nextNormal.x; + } else if (roundness > layout.miter_limit) { + // If the miter grows too large, flip the direction to make a + // bevel join. + joinNormal.x = (prevNormal.x - nextNormal.x) / joinAngularity; + joinNormal.y = (prevNormal.y - nextNormal.y) / joinAngularity; + } - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + if (roundness > layout.miter_limit) { + flip = -flip; + } - // Add second vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - -flip * joinNormal.x, -flip * joinNormal.y, // extrude normal - 0, 1, distance) - start_vertex; // texture normal + // Add first vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + flip * joinNormal.x, flip * joinNormal.y, // extrude normal + 0, 0, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - if ((!prevVertex && beginCap == CapType::Round) || - (!nextVertex && endCap == CapType::Round)) { - point_store.emplace_back(e1); - } - } + // Add second vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + -flip * joinNormal.x, -flip * joinNormal.y, // extrude normal + 0, 1, distance) - start_vertex; // texture normal - else { - // Close up the previous line - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * prevNormal.y, -flip * prevNormal.x, // extrude normal - 0, 0, distance) - start_vertex; // texture normal + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + if ((!prevVertex && beginCap == CapType::Round) || + (!nextVertex && endCap == CapType::Round)) { + point_store.emplace_back(e1); + } + } - // Add second vertex. - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - -flip * prevNormal.y, flip * prevNormal.x, // extrude normal - 0, 1, distance) - start_vertex; // texture normal + else { + // Close up the previous line + // Add first vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + flip * prevNormal.y, -flip * prevNormal.x, // extrude normal + 0, 0, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - prevNormal = { -nextNormal.x, -nextNormal.y }; - flip = 1; + // Add second vertex. + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + -flip * prevNormal.y, flip * prevNormal.x, // extrude normal + 0, 1, distance) - start_vertex; // texture normal + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - // begin/end caps - if ((!prevVertex && beginCap == CapType::Round) || - (!nextVertex && endCap == CapType::Round)) { - point_store.emplace_back(e1); - } + prevNormal = { -nextNormal.x, -nextNormal.y }; + flip = 1; - if (currentJoin == JoinType::Round) { - if (prevVertex && nextVertex && (!closed || i > 0)) { + // begin/end caps + if ((!prevVertex && beginCap == CapType::Round) || + (!nextVertex && endCap == CapType::Round)) { point_store.emplace_back(e1); } - // Reset the previous vertices so that we don't accidentally create - // any triangles. - e1 = -1; e2 = -1; e3 = -1; - } - // Start the new quad. - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - -flip * nextNormal.y, flip * nextNormal.x, // extrude normal - 0, 0, distance) - start_vertex; // texture normal + if (currentJoin == JoinType::Round) { + if (prevVertex && nextVertex && (!closed || i > 0)) { + point_store.emplace_back(e1); + } - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + // Reset the previous vertices so that we don't accidentally create + // any triangles. + e1 = -1; e2 = -1; e3 = -1; + } - // Add second vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * nextNormal.y, -flip * nextNormal.x, // extrude normal - 0, 1, distance) - start_vertex; // texture normal + // Start the new quad. + // Add first vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + -flip * nextNormal.y, flip * nextNormal.x, // extrude normal + 0, 0, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - } - } + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - size_t end_vertex = vertexBuffer.index(); - size_t vertex_count = end_vertex - start_vertex; + // Add second vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + flip * nextNormal.y, -flip * nextNormal.x, // extrude normal + 0, 1, distance) - start_vertex; // texture normal - // Store the triangle/line groups. - { - if (!triangleGroups.size() || (triangleGroups.back()->vertex_length + vertex_count > 65535)) { - // Move to a new group because the old one can't hold the geometry. - triangleGroups.emplace_back(util::make_unique()); + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; + } } - assert(triangleGroups.back()); - triangle_group_type& group = *triangleGroups.back(); - for (const TriangleElement& triangle : triangle_store) { - triangleElementsBuffer.add( - group.vertex_length + triangle.a, - group.vertex_length + triangle.b, - group.vertex_length + triangle.c - ); - } + size_t end_vertex = vertexBuffer.index(); + size_t vertex_count = end_vertex - start_vertex; - group.vertex_length += vertex_count; - group.elements_length += triangle_store.size(); - } + // Store the triangle/line groups. + { + if (!triangleGroups.size() || (triangleGroups.back()->vertex_length + vertex_count > 65535)) { + // Move to a new group because the old one can't hold the geometry. + triangleGroups.emplace_back(util::make_unique()); + } - // Store the line join/cap groups. - { - if (!pointGroups.size() || (pointGroups.back()->vertex_length + vertex_count > 65535)) { - // Move to a new group because the old one can't hold the geometry. - pointGroups.emplace_back(util::make_unique()); - } + assert(triangleGroups.back()); + triangle_group_type& group = *triangleGroups.back(); + for (const TriangleElement& triangle : triangle_store) { + triangleElementsBuffer.add( + group.vertex_length + triangle.a, + group.vertex_length + triangle.b, + group.vertex_length + triangle.c + ); + } - assert(pointGroups.back()); - point_group_type& group = *pointGroups.back(); - for (PointElement point : point_store) { - pointElementsBuffer.add(group.vertex_length + point); + group.vertex_length += vertex_count; + group.elements_length += triangle_store.size(); } - group.vertex_length += vertex_count; - group.elements_length += point_store.size(); + // Store the line join/cap groups. + { + if (!pointGroups.size() || (pointGroups.back()->vertex_length + vertex_count > 65535)) { + // Move to a new group because the old one can't hold the geometry. + pointGroups.emplace_back(util::make_unique()); + } + + assert(pointGroups.back()); + point_group_type& group = *pointGroups.back(); + for (PointElement point : point_store) { + pointElementsBuffer.add(group.vertex_length + point); + } + + group.vertex_length += vertex_count; + group.elements_length += point_store.size(); + } } } diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index 9239634332d..4190b79f574 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -37,7 +37,7 @@ class LineBucket : public Bucket { const mat4 &matrix) override; bool hasData() const override; - void addGeometry(const Geometry& line); + void addGeometry(const GeometryCollection&); bool hasPoints() const; diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 60315c8fe0c..462ac72ab7c 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -97,15 +97,14 @@ std::vector SymbolBucket::processFeatures(const util::ptrnextGeometry(); - const GeometryLine& line = geometry.get(); - bool first = true; - for (auto point_it = line.begin(); point_it != line.end(); point_it++) { - if (first) { - multiline.emplace_back(); - first = false; + GeometryCollection geometryCollection = feature->nextGeometry(); + multiline.emplace_back(); + for (auto& geometry : geometryCollection) { + const GeometryLine& line = geometry.get(); + multiline.emplace_back(); + for (auto& point : line) { + multiline.back().emplace_back(point.x, point.y); } - multiline.back().emplace_back(point_it->x, point_it->y); } features.push_back(std::move(ft)); From c170f8887d167c9bdc2f4cc218b87552a364221e Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 6 Mar 2015 19:23:17 -0800 Subject: [PATCH 10/27] get rid of unused member --- src/mbgl/map/geometry_tile.hpp | 1 - src/mbgl/map/vector_tile.cpp | 8 -------- src/mbgl/map/vector_tile.hpp | 1 - 3 files changed, 10 deletions(-) diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index 81960c981e8..ccb200248f8 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -85,7 +85,6 @@ std::ostream& operator<<(std::ostream&, const PositionedGlyph&); class GeometryTileLayer { public: virtual util::ptr createFilter(const FilterExpression&) = 0; - virtual util::ptr nextFeature() = 0; public: std::string name; diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 332534f25a7..d0e254b6628 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -208,11 +208,3 @@ util::ptr FilteredVectorTileLayer::nextMatchingFeature() { util::ptr VectorTileLayer::createFilter(const FilterExpression& filterExpression) { return std::move(std::make_shared(shared_from_this(), filterExpression)); } - -util::ptr VectorTileLayer::nextFeature() { - if (feature_pbf.next(2)) { - return std::move(std::make_shared(feature_pbf.message(), shared_from_this())); - } - - 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 85ec09bede2..0fee14ac508 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -38,7 +38,6 @@ class VectorTileLayer : public GeometryTileLayer, public std::enable_shared_from VectorTileLayer(pbf); virtual util::ptr createFilter(const FilterExpression&); - virtual util::ptr nextFeature(); private: pbf feature_pbf; From b523d0256b9bcd9578f3435efc8faadb62631c48 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 6 Mar 2015 19:27:03 -0800 Subject: [PATCH 11/27] increment feature filter on creation --- src/mbgl/map/vector_tile.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index d0e254b6628..4cb06e917cd 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -132,6 +132,7 @@ VectorTileLayer::VectorTileLayer(pbf layer_pbf) FilteredVectorTileLayer::FilteredVectorTileLayer(const util::ptr layer_, const FilterExpression& filterExpression_) : GeometryFilteredTileLayer(layer_, filterExpression_) { feature_pbf = layer_->feature_pbf; + nextMatchingFeature(); } template <> From e57703d711eee356878f358d7a3c1ad323d137c2 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 6 Mar 2015 19:41:57 -0800 Subject: [PATCH 12/27] properly iterate geometries --- src/mbgl/map/tile_parser.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp index 861141b1fa0..c920ca473a3 100644 --- a/src/mbgl/map/tile_parser.cpp +++ b/src/mbgl/map/tile_parser.cpp @@ -221,11 +221,9 @@ template return; GeometryCollection geometry = feature->nextGeometry(); - if (geometry.size()) { + while (geometry.size()) { bucket->addGeometry(geometry); geometry = feature->nextGeometry(); - } else if (debug::tileParseWarnings) { - fprintf(stderr, "[WARNING] geometry is empty\n"); } feature = filtered_layer->nextMatchingFeature(); From 56bc3052ac7b4cf236f04120592f1adf1861750b Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 6 Mar 2015 19:42:15 -0800 Subject: [PATCH 13/27] refactor vars --- src/mbgl/map/vector_tile.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 4cb06e917cd..5244d61a2f5 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -47,18 +47,18 @@ GeometryCollection VectorTileFeature::nextGeometry() { GeometryCollection result; - pbf current_geometry_pbf = geometry_pbf.message(); - PBFGeometry current_geometry(current_geometry_pbf); - int32_t x, y; - while (geometry_pbf.next(4)) { // geometry + pbf current_geometry_pbf = geometry_pbf.message(); + PBFGeometry current_geometry(current_geometry_pbf); + PBFGeometry::command cmd; + int32_t x, y; + if (type == GeometryFeatureType::Point) { current_geometry.next(x, y); GeometryPoint point(x, y); result.emplace_back(GeometryPoint(x, y)); } else if (type == GeometryFeatureType::LineString) { GeometryLine line; - PBFGeometry::command cmd; while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { if (cmd == PBFGeometry::move_to) { if (!line.empty()) { @@ -73,7 +73,6 @@ GeometryCollection VectorTileFeature::nextGeometry() { } } else if (type == GeometryFeatureType::Polygon) { GeometryLine line; - PBFGeometry::command cmd; while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { if (cmd == PBFGeometry::move_to) { if (line.size()) { From cf623e96c5b2fa5250777a4d156f5a597f0673a7 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Fri, 6 Mar 2015 19:42:23 -0800 Subject: [PATCH 14/27] safely check points --- src/mbgl/map/vector_tile.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 5244d61a2f5..a42c16cd823 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -54,9 +54,10 @@ GeometryCollection VectorTileFeature::nextGeometry() { int32_t x, y; if (type == GeometryFeatureType::Point) { - current_geometry.next(x, y); - GeometryPoint point(x, y); - result.emplace_back(GeometryPoint(x, y)); + if ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { + GeometryPoint point(x, y); + result.emplace_back(GeometryPoint(x, y)); + } } else if (type == GeometryFeatureType::LineString) { GeometryLine line; while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { From e01fe2fb566237713eb13223e970c95e75bd9f5e Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Sat, 7 Mar 2015 16:19:14 -0800 Subject: [PATCH 15/27] doesn't make sense to move shared pointers --- src/mbgl/map/vector_tile.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index a42c16cd823..30357848f0e 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -199,13 +199,13 @@ util::ptr FilteredVectorTileLayer::nextMatchingFeature() { } if (evaluate(filterExpression, extractor)) { - return std::move(std::make_shared(matching_feature_pbf, layer)); + return std::make_shared(matching_feature_pbf, layer); } } - return std::move(std::make_shared(pbf(), layer)); + return std::make_shared(pbf(), layer); } util::ptr VectorTileLayer::createFilter(const FilterExpression& filterExpression) { - return std::move(std::make_shared(shared_from_this(), filterExpression)); + return std::make_shared(shared_from_this(), filterExpression); } From a6b6a8d67ea6a2ab324e639a32473137da739870 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Sun, 8 Mar 2015 11:36:01 -0700 Subject: [PATCH 16/27] move to abstract interfaces to more be in line with original API --- src/mbgl/geometry/glyph_atlas.cpp | 1 - src/mbgl/map/geometry_tile.cpp | 15 +---- src/mbgl/map/geometry_tile.hpp | 54 +++++++++------- src/mbgl/map/tile_parser.cpp | 27 ++++---- src/mbgl/map/tile_parser.hpp | 8 +-- src/mbgl/map/vector_tile.cpp | 99 +++++++++++++++++++---------- src/mbgl/map/vector_tile.hpp | 63 ++++++++++++++---- src/mbgl/renderer/symbol_bucket.cpp | 20 +++--- src/mbgl/renderer/symbol_bucket.hpp | 6 +- 9 files changed, 178 insertions(+), 115 deletions(-) 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 index defff0ebfb4..2800712ef25 100644 --- a/src/mbgl/map/geometry_tile.cpp +++ b/src/mbgl/map/geometry_tile.cpp @@ -16,20 +16,9 @@ std::ostream& mbgl::operator<<(std::ostream& os, const GeometryFeatureType& type } std::ostream& mbgl::operator<<(std::ostream& os, const GeometryTileFeature& feature) { - os << "Feature(" << feature.id << "): " << feature.type << std::endl; - for (const auto& prop : feature.properties) { + os << "Feature(" << feature.getID() << "): " << feature.getType() << std::endl; + for (const auto& prop : feature.getProperties()) { os << " - " << prop.first << ": " << &prop.second << std::endl; } return os; } - -GeometryFilteredTileLayer::GeometryFilteredTileLayer(const util::ptr layer_, const FilterExpression& filterExpression_) - : layer(layer_), - filterExpression(filterExpression_) {} - -GeometryTile& GeometryTile::operator=(GeometryTile&& other) { - if (this != &other) { - layers.swap(other.layers); - } - return *this; -} diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index ccb200248f8..5eb031667fd 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -40,12 +39,15 @@ class GeometryTileLayer; class GeometryTileFeature { public: + virtual ~GeometryTileFeature(); + + virtual uint64_t getID() const = 0; + virtual GeometryFeatureType getType() const = 0; + virtual std::map getProperties() const = 0; virtual GeometryCollection nextGeometry() = 0; -public: - uint64_t id = 0; - GeometryFeatureType type = GeometryFeatureType::Unknown; - std::map properties; +protected: + GeometryTileFeature(); }; std::ostream& operator<<(std::ostream&, const GeometryTileFeature& feature); @@ -53,7 +55,7 @@ std::ostream& operator<<(std::ostream&, const GeometryTileFeature& feature); template class GeometryTileTagExtractor { public: - GeometryTileTagExtractor(const util::ptr); + GeometryTileTagExtractor(const GeometryTileLayer&); inline void setTags(const Tags& tags_) { tags = tags_; } virtual mapbox::util::optional getValue(const std::string &key) const; @@ -66,43 +68,49 @@ class GeometryTileTagExtractor { Tags tags; protected: - const util::ptr layer; + const GeometryTileLayer& layer; }; class GeometryFilteredTileLayer { public: - GeometryFilteredTileLayer(const util::ptr, const FilterExpression&); + class iterator {}; + +public: + virtual ~GeometryFilteredTileLayer(); - virtual util::ptr nextMatchingFeature() = 0; + virtual iterator begin() const = 0; + virtual iterator end() const = 0; protected: - const util::ptr layer; - const FilterExpression& filterExpression; + GeometryFilteredTileLayer(); }; std::ostream& operator<<(std::ostream&, const PositionedGlyph&); class GeometryTileLayer { public: - virtual util::ptr createFilter(const FilterExpression&) = 0; + virtual ~GeometryTileLayer(); -public: - std::string name; - uint32_t extent = 4096; - std::vector keys; - std::unordered_map key_index; - std::vector values; - std::map> shaping; + virtual const std::string getName() const = 0; + virtual uint32_t getExtent() const = 0; + virtual const std::vector getKeys() const = 0; + virtual const std::unordered_map getKeyIndex() const = 0; + virtual const std::vector getValues() const = 0; + virtual const std::map> getShaping() const = 0; + virtual std::unique_ptr createFilteredTileLayer(const FilterExpression&) const = 0; + +protected: + GeometryTileLayer(); }; class GeometryTile { public: - GeometryTile& operator=(GeometryTile&& other); + virtual ~GeometryTile(); - virtual void logDebug() const = 0; + virtual std::map getLayers() const = 0; -public: - std::map> layers; +protected: + GeometryTile(); }; } diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp index c920ca473a3..dd97b62b317 100644 --- a/src/mbgl/map/tile_parser.cpp +++ b/src/mbgl/map/tile_parser.cpp @@ -187,9 +187,9 @@ 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 util::ptr layer = layer_it->second; + auto layer_it = vectorTile.getLayers().find(bucketDesc.source_layer); + if (layer_it != vectorTile.getLayers().end()) { + const GeometryTileLayer& layer = layer_it->second; if (bucketDesc.type == StyleLayerType::Fill) { return createFillBucket(layer, bucketDesc); } else if (bucketDesc.type == StyleLayerType::Line) { @@ -213,24 +213,23 @@ std::unique_ptr TileParser::createBucket(const StyleBucket &bucketDesc) } template - 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) { +void TileParser::addBucketGeometries(Bucket& bucket, const GeometryTileLayer& layer, const FilterExpression &filter) { + + std::unique_ptr filtered_layer = layer.createFilteredTileLayer(filter); + + for (auto feature : *filtered_layer) { if (obsolete()) return; - GeometryCollection geometry = feature->nextGeometry(); + GeometryCollection geometry = feature.nextGeometry(); while (geometry.size()) { bucket->addGeometry(geometry); - geometry = feature->nextGeometry(); + geometry = feature.nextGeometry(); } - - feature = filtered_layer->nextMatchingFeature(); } } -std::unique_ptr TileParser::createFillBucket(const util::ptr layer, +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), @@ -241,7 +240,7 @@ std::unique_ptr TileParser::createFillBucket(const util::ptr TileParser::createLineBucket(const util::ptr layer, +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), @@ -252,7 +251,7 @@ std::unique_ptr TileParser::createLineBucket(const util::ptr TileParser::createSymbolBucket(const util::ptr layer, +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); diff --git a/src/mbgl/map/tile_parser.hpp b/src/mbgl/map/tile_parser.hpp index ee134911fc2..841ae1749c1 100644 --- a/src/mbgl/map/tile_parser.hpp +++ b/src/mbgl/map/tile_parser.hpp @@ -53,11 +53,11 @@ class TileParser : private util::noncopyable void parseStyleLayers(util::ptr group); std::unique_ptr createBucket(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); + 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); - template void addBucketGeometries(Bucket& bucket, const util::ptr layer, const FilterExpression& filter); + template void addBucketGeometries(Bucket& bucket, const GeometryTileLayer& 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 30357848f0e..f31dd27aa2a 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -1,14 +1,15 @@ #include #include #include -#include +#include +#include #include #include using namespace mbgl; -VectorTileFeature::VectorTileFeature(pbf feature_pbf, const util::ptr layer) { +VectorTileFeature::VectorTileFeature(pbf feature_pbf, const GeometryTileLayer& layer) { while (feature_pbf.next()) { if (feature_pbf.tag == 1) { // id id = feature_pbf.varint(); @@ -18,17 +19,17 @@ VectorTileFeature::VectorTileFeature(pbf feature_pbf, const util::ptrkeys.size() <= tag_key) { + if (layer.getKeys().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.getValues().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.getKeys()[tag_key], layer.getValues()[tag_val]); } else { throw std::runtime_error("uneven number of feature tag ids"); } @@ -99,16 +100,19 @@ GeometryCollection VectorTileFeature::nextGeometry() { 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)); + VectorTileLayer layer(tile_pbf.message()); + layers.emplace(layer.getName(), std::forward(layer)); } else { tile_pbf.skip(); } } } -void VectorTile::logDebug() const { - printf("got here for VectorTile\n"); +VectorTile& VectorTile::operator=(VectorTile&& other) { + if (this != &other) { + layers.swap(other.layers); + } + return *this; } VectorTileLayer::VectorTileLayer(pbf layer_pbf) @@ -129,14 +133,31 @@ VectorTileLayer::VectorTileLayer(pbf layer_pbf) } } -FilteredVectorTileLayer::FilteredVectorTileLayer(const util::ptr layer_, const FilterExpression& filterExpression_) - : GeometryFilteredTileLayer(layer_, filterExpression_) { - feature_pbf = layer_->feature_pbf; - nextMatchingFeature(); +std::unique_ptr VectorTileLayer::createFilteredTileLayer(const FilterExpression& filterExpression) const { + return util::make_unique(*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::GeometryTileTagExtractor(const util::ptr layer_) +GeometryTileTagExtractor::GeometryTileTagExtractor(const GeometryTileLayer& layer_) : layer(layer_) {} template <> @@ -147,8 +168,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.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. @@ -166,8 +187,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.getValues().size() > tag_val) { + value = layer.getValues()[tag_val]; } else { fprintf(stderr, "[WARNING] feature references out of range value\n"); break; @@ -181,31 +202,41 @@ mapbox::util::optional GeometryTileTagExtractor::getValue(const std: template bool mbgl::evaluate(const FilterExpression&, const GeometryTileTagExtractor&); -util::ptr FilteredVectorTileLayer::nextMatchingFeature() { - while (feature_pbf.next(2)) { - pbf matching_feature_pbf = feature_pbf.message(); - pbf current_feature_pbf = matching_feature_pbf; +void FilteredVectorTileLayer::iterator::operator++() { + valid = false; + + const FilterExpression &expression = parent.filterExpression; - GeometryTileTagExtractor extractor(layer); + while (feature_pbf.next(2)) { // feature + feature = VectorTileFeature(feature_pbf.message(), parent.layer); + pbf feature_pbf_ = feature_pbf.message(); - while (current_feature_pbf.next()) { - if (current_feature_pbf.tag == 2) { // tags - extractor.setTags(current_feature_pbf.message()); - } else if (current_feature_pbf.tag == 3) { // geometry type - extractor.setType(GeometryFeatureType(current_feature_pbf.varint())); + GeometryTileTagExtractor 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 { - current_feature_pbf.skip(); + feature_pbf_.skip(); } } - if (evaluate(filterExpression, extractor)) { - return std::make_shared(matching_feature_pbf, layer); + if (evaluate(expression, extractor)) { + valid = true; + return; // data loop + } else { + valid = false; } } +} - return std::make_shared(pbf(), layer); +bool FilteredVectorTileLayer::iterator::operator!=(const iterator& other) const { + return !(feature_pbf.data == other.feature_pbf.data && feature_pbf.end == other.feature_pbf.end && valid == other.valid); } -util::ptr VectorTileLayer::createFilter(const FilterExpression& filterExpression) { - return std::make_shared(shared_from_this(), filterExpression); +const VectorTileFeature& FilteredVectorTileLayer::iterator::operator*() const { + return feature; } diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index 0fee14ac508..a306f524dc7 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -2,52 +2,89 @@ #define MBGL_MAP_VECTOR_TILE #include -#include #include -#include -#include namespace mbgl { class VectorTileLayer; +struct pbf; class VectorTileFeature : public GeometryTileFeature { public: - VectorTileFeature(pbf, const util::ptr); + VectorTileFeature(pbf, const GeometryTileLayer&); - GeometryCollection nextGeometry(); + virtual inline uint64_t getID() const { return id; }; + virtual inline GeometryFeatureType getType() const { return type; } + virtual inline std::map getProperties() const { return properties; } + virtual GeometryCollection nextGeometry(); private: + uint64_t id = 0; + GeometryFeatureType type = GeometryFeatureType::Unknown; + std::map properties; pbf geometry_pbf; }; class FilteredVectorTileLayer : public GeometryFilteredTileLayer { public: - FilteredVectorTileLayer(const util::ptr, const FilterExpression&); + class iterator : public GeometryFilteredTileLayer::iterator { + public: + iterator(const FilteredVectorTileLayer&, const pbf&); + void operator++(); + bool operator!=(const iterator&) const; + const VectorTileFeature& operator*() const; + + private: + const FilteredVectorTileLayer& parent; + bool valid = false; + VectorTileFeature feature; + pbf feature_pbf; + }; - virtual util::ptr nextMatchingFeature(); +public: + FilteredVectorTileLayer(const VectorTileLayer&, const FilterExpression&); -private: - pbf feature_pbf; + virtual GeometryFilteredTileLayer::iterator begin() const; + virtual GeometryFilteredTileLayer::iterator end() const; +private: + const VectorTileLayer& layer; + const FilterExpression& filterExpression; }; -class VectorTileLayer : public GeometryTileLayer, public std::enable_shared_from_this { +class VectorTileLayer : public GeometryTileLayer { friend class FilteredVectorTileLayer; public: VectorTileLayer(pbf); - virtual util::ptr createFilter(const FilterExpression&); + virtual inline const std::string getName() const { return name; } + virtual inline uint32_t getExtent() const { return extent; } + virtual inline const std::vector getKeys() const { return keys; } + virtual inline const std::unordered_map getKeyIndex() const { return key_index; } + virtual inline const std::vector getValues() const { return values; } + virtual inline const std::map> getShaping() const { return shaping; } + + virtual std::unique_ptr createFilteredTileLayer(const FilterExpression&) const; private: - pbf feature_pbf; + std::string name; + uint32_t extent = 4096; + std::vector keys; + std::unordered_map key_index; + std::vector values; + std::map> shaping; + const pbf feature_pbf; }; class VectorTile : public GeometryTile { public: VectorTile(pbf); - virtual void logDebug() const; + VectorTile& operator=(VectorTile&&); + virtual std::map getLayers() const; + +private: + std::map layers; }; } diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 462ac72ab7c..511add4de22 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include namespace mbgl { @@ -47,7 +49,7 @@ void SymbolBucket::addGlyphsToAtlas(uint64_t tileid, const std::string stackname glyphAtlas.addGlyphs(tileid, text, stackname, fontStack,face); } -std::vector SymbolBucket::processFeatures(const util::ptr layer, +std::vector SymbolBucket::processFeatures(const GeometryTileLayer& layer, const FilterExpression &filter, GlyphStore &glyphStore, const Sprite &sprite) { @@ -64,14 +66,14 @@ std::vector SymbolBucket::processFeatures(const util::ptr ranges; - util::ptr filtered_layer = layer->createFilter(filter); - util::ptr feature = filtered_layer->nextMatchingFeature(); - while (feature->type != GeometryFeatureType::Unknown) { + std::unique_ptr filtered_layer = layer.createFilteredTileLayer(filter); + + for (auto feature : *filtered_layer) { SymbolFeature ft; if (has_text) { - std::string u8string = util::replaceTokens(layout.text.field, feature->properties); + std::string u8string = util::replaceTokens(layout.text.field, feature.getProperties()); if (layout.text.transform == TextTransformType::Uppercase) { u8string = platform::uppercase(u8string); @@ -90,14 +92,14 @@ std::vector SymbolBucket::processFeatures(const util::ptrproperties); + ft.sprite = util::replaceTokens(layout.icon.image, feature.getProperties()); } if (ft.label.length() || ft.sprite.length()) { auto &multiline = ft.geometry; - GeometryCollection geometryCollection = feature->nextGeometry(); + GeometryCollection geometryCollection = feature.nextGeometry(); multiline.emplace_back(); for (auto& geometry : geometryCollection) { const GeometryLine& line = geometry.get(); @@ -109,8 +111,6 @@ std::vector SymbolBucket::processFeatures(const util::ptrnextMatchingFeature(); } if (layout.placement == PlacementType::Line) { @@ -123,7 +123,7 @@ std::vector SymbolBucket::processFeatures(const util::ptr 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 d9b461afaa4..0f9e8faa318 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -65,7 +65,7 @@ class SymbolBucket : public Bucket { bool hasTextData() const; bool hasIconData() const; - void addFeatures(const util::ptr layer, const FilterExpression &filter, + void addFeatures(const GeometryTileLayer& layer, const FilterExpression &filter, const Tile::ID &id, SpriteAtlas &spriteAtlas, Sprite &sprite, GlyphAtlas &glyphAtlas, GlyphStore &glyphStore); @@ -78,9 +78,9 @@ class SymbolBucket : public Bucket { private: - std::vector processFeatures(const util::ptr layer, const FilterExpression &filter, GlyphStore &glyphStore, const Sprite &sprite); + std::vector processFeatures(const GeometryTileLayer& layer, const FilterExpression &filter, GlyphStore &glyphStore, const Sprite &sprite); - void addFeature(const GeometryLine &line, const Shaping &shaping, const GlyphPositions &face, const Rect &image); + void addFeature(const std::vector &line, const Shaping &shaping, const GlyphPositions &face, const Rect &image); // Adds placed items to the buffer. template From fbb2d17f4317c0742dd89988882c3c3995f23580 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Sun, 8 Mar 2015 14:13:46 -0700 Subject: [PATCH 17/27] fix iterator comparator --- src/mbgl/map/vector_tile.cpp | 6 +++++- src/mbgl/map/vector_tile.hpp | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index f31dd27aa2a..d74a5922e17 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -97,6 +97,10 @@ 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 @@ -234,7 +238,7 @@ void FilteredVectorTileLayer::iterator::operator++() { } bool FilteredVectorTileLayer::iterator::operator!=(const iterator& other) const { - return !(feature_pbf.data == other.feature_pbf.data && feature_pbf.end == other.feature_pbf.end && valid == other.valid); + return !(feature == other.feature); } const VectorTileFeature& FilteredVectorTileLayer::iterator::operator*() const { diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index a306f524dc7..fe154bc85c1 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -17,6 +17,7 @@ class VectorTileFeature : public GeometryTileFeature { virtual inline GeometryFeatureType getType() const { return type; } virtual inline std::map getProperties() const { return properties; } virtual GeometryCollection nextGeometry(); + bool operator==(const VectorTileFeature&) const; private: uint64_t id = 0; From a45ae199cf37976d34301a024be31ef427c34892 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Sun, 8 Mar 2015 14:18:46 -0700 Subject: [PATCH 18/27] move from range-based for loop to iterator for to be clearer --- src/mbgl/map/geometry_tile.hpp | 12 +++++++++++- src/mbgl/map/tile_parser.cpp | 7 ++++--- src/mbgl/map/vector_tile.cpp | 5 +++-- src/mbgl/map/vector_tile.hpp | 2 +- src/mbgl/renderer/symbol_bucket.cpp | 8 ++++---- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index 5eb031667fd..fdca905208a 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -73,7 +73,17 @@ class GeometryTileTagExtractor { class GeometryFilteredTileLayer { public: - class iterator {}; + class iterator { + public: + virtual ~iterator(); + + void operator++(); + bool operator!=(const iterator&) const; + GeometryTileFeature& operator*() const; + + protected: + iterator(); + }; public: virtual ~GeometryFilteredTileLayer(); diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp index dd97b62b317..c75a19b9de5 100644 --- a/src/mbgl/map/tile_parser.cpp +++ b/src/mbgl/map/tile_parser.cpp @@ -217,14 +217,15 @@ void TileParser::addBucketGeometries(Bucket& bucket, const GeometryTileLayer& la std::unique_ptr filtered_layer = layer.createFilteredTileLayer(filter); - for (auto feature : *filtered_layer) { + for (auto feature_it = filtered_layer->begin(); feature_it != filtered_layer->end(); ++feature_it) { + if (obsolete()) return; - GeometryCollection geometry = feature.nextGeometry(); + GeometryCollection geometry = (*feature_it).nextGeometry(); while (geometry.size()) { bucket->addGeometry(geometry); - geometry = feature.nextGeometry(); + geometry = (*feature_it).nextGeometry(); } } } diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index d74a5922e17..cdd93d4bbe3 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -241,6 +241,7 @@ bool FilteredVectorTileLayer::iterator::operator!=(const iterator& other) const return !(feature == other.feature); } -const VectorTileFeature& FilteredVectorTileLayer::iterator::operator*() const { - return feature; +VectorTileFeature& FilteredVectorTileLayer::iterator::operator*() const { + VectorTileFeature* f = const_cast(&feature); + return *f; } diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index fe154bc85c1..63efbab4887 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -33,7 +33,7 @@ class FilteredVectorTileLayer : public GeometryFilteredTileLayer { iterator(const FilteredVectorTileLayer&, const pbf&); void operator++(); bool operator!=(const iterator&) const; - const VectorTileFeature& operator*() const; + VectorTileFeature& operator*() const; private: const FilteredVectorTileLayer& parent; diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 511add4de22..50a0f3c5575 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -68,12 +68,12 @@ std::vector SymbolBucket::processFeatures(const GeometryTileLayer std::unique_ptr filtered_layer = layer.createFilteredTileLayer(filter); - for (auto feature : *filtered_layer) { + for (auto feature_it = filtered_layer->begin(); feature_it != filtered_layer->end(); ++feature_it) { SymbolFeature ft; if (has_text) { - std::string u8string = util::replaceTokens(layout.text.field, feature.getProperties()); + std::string u8string = util::replaceTokens(layout.text.field, (*feature_it).getProperties()); if (layout.text.transform == TextTransformType::Uppercase) { u8string = platform::uppercase(u8string); @@ -92,14 +92,14 @@ std::vector SymbolBucket::processFeatures(const GeometryTileLayer } if (has_icon) { - ft.sprite = util::replaceTokens(layout.icon.image, feature.getProperties()); + ft.sprite = util::replaceTokens(layout.icon.image, (*feature_it).getProperties()); } if (ft.label.length() || ft.sprite.length()) { auto &multiline = ft.geometry; - GeometryCollection geometryCollection = feature.nextGeometry(); + GeometryCollection geometryCollection = (*feature_it).nextGeometry(); multiline.emplace_back(); for (auto& geometry : geometryCollection) { const GeometryLine& line = geometry.get(); From 7361f8566bc22f27a55de399bef23a03b4026094 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Sun, 8 Mar 2015 16:12:44 -0700 Subject: [PATCH 19/27] move to shared pointers for queried layers passed to buckets --- src/mbgl/map/geometry_tile.hpp | 28 ++-------------------------- src/mbgl/map/tile_parser.cpp | 15 +++++++-------- src/mbgl/map/tile_parser.hpp | 8 ++++---- src/mbgl/map/vector_tile.cpp | 8 ++++++++ src/mbgl/map/vector_tile.hpp | 3 ++- src/mbgl/renderer/symbol_bucket.cpp | 6 +++--- src/mbgl/renderer/symbol_bucket.hpp | 4 ++-- 7 files changed, 28 insertions(+), 44 deletions(-) diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index fdca905208a..a8105a5002b 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 @@ -39,15 +40,10 @@ class GeometryTileLayer; class GeometryTileFeature { public: - virtual ~GeometryTileFeature(); - virtual uint64_t getID() const = 0; virtual GeometryFeatureType getType() const = 0; virtual std::map getProperties() const = 0; virtual GeometryCollection nextGeometry() = 0; - -protected: - GeometryTileFeature(); }; std::ostream& operator<<(std::ostream&, const GeometryTileFeature& feature); @@ -75,32 +71,20 @@ class GeometryFilteredTileLayer { public: class iterator { public: - virtual ~iterator(); - void operator++(); bool operator!=(const iterator&) const; GeometryTileFeature& operator*() const; - - protected: - iterator(); }; public: - virtual ~GeometryFilteredTileLayer(); - virtual iterator begin() const = 0; virtual iterator end() const = 0; - -protected: - GeometryFilteredTileLayer(); }; std::ostream& operator<<(std::ostream&, const PositionedGlyph&); class GeometryTileLayer { public: - virtual ~GeometryTileLayer(); - virtual const std::string getName() const = 0; virtual uint32_t getExtent() const = 0; virtual const std::vector getKeys() const = 0; @@ -108,19 +92,11 @@ class GeometryTileLayer { virtual const std::vector getValues() const = 0; virtual const std::map> getShaping() const = 0; virtual std::unique_ptr createFilteredTileLayer(const FilterExpression&) const = 0; - -protected: - GeometryTileLayer(); }; class GeometryTile { public: - virtual ~GeometryTile(); - - virtual std::map getLayers() const = 0; - -protected: - GeometryTile(); + virtual const util::ptr getLayer(const std::string&) const = 0; }; } diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp index c75a19b9de5..73426a2d1e7 100644 --- a/src/mbgl/map/tile_parser.cpp +++ b/src/mbgl/map/tile_parser.cpp @@ -187,9 +187,8 @@ 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.getLayers().find(bucketDesc.source_layer); - if (layer_it != vectorTile.getLayers().end()) { - const GeometryTileLayer& layer = layer_it->second; + const util::ptr layer = vectorTile.getLayer(bucketDesc.source_layer); + if (layer.get() != nullptr) { if (bucketDesc.type == StyleLayerType::Fill) { return createFillBucket(layer, bucketDesc); } else if (bucketDesc.type == StyleLayerType::Line) { @@ -213,9 +212,9 @@ std::unique_ptr TileParser::createBucket(const StyleBucket &bucketDesc) } template -void TileParser::addBucketGeometries(Bucket& bucket, const GeometryTileLayer& layer, const FilterExpression &filter) { +void TileParser::addBucketGeometries(Bucket& bucket, const util::ptr layer, const FilterExpression &filter) { - std::unique_ptr filtered_layer = layer.createFilteredTileLayer(filter); + std::unique_ptr filtered_layer = layer->createFilteredTileLayer(filter); for (auto feature_it = filtered_layer->begin(); feature_it != filtered_layer->end(); ++feature_it) { @@ -230,7 +229,7 @@ void TileParser::addBucketGeometries(Bucket& bucket, const GeometryTileLayer& la } } -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 +240,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 +251,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 841ae1749c1..90a9037fd3f 100644 --- a/src/mbgl/map/tile_parser.hpp +++ b/src/mbgl/map/tile_parser.hpp @@ -53,11 +53,11 @@ class TileParser : private util::noncopyable 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 cdd93d4bbe3..0728608321d 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -119,6 +119,14 @@ VectorTile& VectorTile::operator=(VectorTile&& other) { return *this; } +const util::ptr VectorTile::getLayer(const std::string& name) const { + auto layer_it = layers.find(name); + if (layer_it != layers.end()) { + return std::make_shared(layer_it->second); + } + return nullptr; +} + VectorTileLayer::VectorTileLayer(pbf layer_pbf) : feature_pbf(layer_pbf) { while (layer_pbf.next()) { diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index 63efbab4887..5fc6764b694 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace mbgl { @@ -82,7 +83,7 @@ class VectorTile : public GeometryTile { VectorTile(pbf); VectorTile& operator=(VectorTile&&); - virtual std::map getLayers() const; + virtual const util::ptr getLayer(const std::string&) const; private: std::map layers; diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 50a0f3c5575..53833a75991 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -49,7 +49,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) { @@ -66,7 +66,7 @@ std::vector SymbolBucket::processFeatures(const GeometryTileLayer // Determine and load glyph ranges std::set ranges; - std::unique_ptr filtered_layer = layer.createFilteredTileLayer(filter); + std::unique_ptr filtered_layer = layer->createFilteredTileLayer(filter); for (auto feature_it = filtered_layer->begin(); feature_it != filtered_layer->end(); ++feature_it) { @@ -123,7 +123,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 0f9e8faa318..9d2d002a631 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -65,7 +65,7 @@ class SymbolBucket : public Bucket { 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); @@ -78,7 +78,7 @@ class SymbolBucket : public Bucket { 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 std::vector &line, const Shaping &shaping, const GlyphPositions &face, const Rect &image); From 0652174465d7231b514d9d5afd718af66dd62097 Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Sun, 8 Mar 2015 16:18:38 -0700 Subject: [PATCH 20/27] reference cleanups --- src/mbgl/map/geometry_tile.hpp | 10 +++++----- src/mbgl/map/vector_tile.hpp | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index a8105a5002b..3d5b677b879 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -85,12 +85,12 @@ std::ostream& operator<<(std::ostream&, const PositionedGlyph&); class GeometryTileLayer { public: - virtual const std::string getName() const = 0; + virtual const std::string& getName() const = 0; virtual uint32_t getExtent() const = 0; - virtual const std::vector getKeys() const = 0; - virtual const std::unordered_map getKeyIndex() const = 0; - virtual const std::vector getValues() const = 0; - virtual const std::map> getShaping() const = 0; + virtual const std::vector& getKeys() const = 0; + virtual const std::unordered_map& getKeyIndex() const = 0; + virtual const std::vector& getValues() const = 0; + virtual const std::map>& getShaping() const = 0; virtual std::unique_ptr createFilteredTileLayer(const FilterExpression&) const = 0; }; diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index 5fc6764b694..e2704a4114d 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -59,12 +59,12 @@ class VectorTileLayer : public GeometryTileLayer { public: VectorTileLayer(pbf); - virtual inline const std::string getName() const { return name; } + virtual inline const std::string& getName() const { return name; } virtual inline uint32_t getExtent() const { return extent; } - virtual inline const std::vector getKeys() const { return keys; } - virtual inline const std::unordered_map getKeyIndex() const { return key_index; } - virtual inline const std::vector getValues() const { return values; } - virtual inline const std::map> getShaping() const { return shaping; } + virtual inline const std::vector& getKeys() const { return keys; } + virtual inline const std::unordered_map& getKeyIndex() const { return key_index; } + virtual inline const std::vector& getValues() const { return values; } + virtual inline const std::map>& getShaping() const { return shaping; } virtual std::unique_ptr createFilteredTileLayer(const FilterExpression&) const; From 2d8bf823fca8daede324b6b345d2fecd224715ee Mon Sep 17 00:00:00 2001 From: "Justin R. Miller" Date: Sun, 8 Mar 2015 16:21:22 -0700 Subject: [PATCH 21/27] unique -> shared ptr --- src/mbgl/map/geometry_tile.hpp | 2 +- src/mbgl/map/tile_parser.cpp | 2 +- src/mbgl/map/vector_tile.cpp | 5 ++--- src/mbgl/map/vector_tile.hpp | 2 +- src/mbgl/renderer/symbol_bucket.cpp | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index 3d5b677b879..045c2984288 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -91,7 +91,7 @@ class GeometryTileLayer { virtual const std::unordered_map& getKeyIndex() const = 0; virtual const std::vector& getValues() const = 0; virtual const std::map>& getShaping() const = 0; - virtual std::unique_ptr createFilteredTileLayer(const FilterExpression&) const = 0; + virtual util::ptr createFilteredTileLayer(const FilterExpression&) const = 0; }; class GeometryTile { diff --git a/src/mbgl/map/tile_parser.cpp b/src/mbgl/map/tile_parser.cpp index 73426a2d1e7..be5b9013691 100644 --- a/src/mbgl/map/tile_parser.cpp +++ b/src/mbgl/map/tile_parser.cpp @@ -214,7 +214,7 @@ std::unique_ptr TileParser::createBucket(const StyleBucket &bucketDesc) template void TileParser::addBucketGeometries(Bucket& bucket, const util::ptr layer, const FilterExpression &filter) { - std::unique_ptr filtered_layer = layer->createFilteredTileLayer(filter); + util::ptr filtered_layer = layer->createFilteredTileLayer(filter); for (auto feature_it = filtered_layer->begin(); feature_it != filtered_layer->end(); ++feature_it) { diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 0728608321d..6eb0704a648 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include @@ -145,8 +144,8 @@ VectorTileLayer::VectorTileLayer(pbf layer_pbf) } } -std::unique_ptr VectorTileLayer::createFilteredTileLayer(const FilterExpression& filterExpression) const { - return util::make_unique(*this, filterExpression); +util::ptr VectorTileLayer::createFilteredTileLayer(const FilterExpression& filterExpression) const { + return std::make_shared(*this, filterExpression); } FilteredVectorTileLayer::FilteredVectorTileLayer(const VectorTileLayer& layer_, const FilterExpression& filterExpression_) diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index e2704a4114d..c99a4a3fb7d 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -66,7 +66,7 @@ class VectorTileLayer : public GeometryTileLayer { virtual inline const std::vector& getValues() const { return values; } virtual inline const std::map>& getShaping() const { return shaping; } - virtual std::unique_ptr createFilteredTileLayer(const FilterExpression&) const; + virtual util::ptr createFilteredTileLayer(const FilterExpression&) const; private: std::string name; diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 53833a75991..631fcaf5d59 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -66,7 +66,7 @@ std::vector SymbolBucket::processFeatures(const util::ptr ranges; - std::unique_ptr filtered_layer = layer->createFilteredTileLayer(filter); + util::ptr filtered_layer = layer->createFilteredTileLayer(filter); for (auto feature_it = filtered_layer->begin(); feature_it != filtered_layer->end(); ++feature_it) { From 50b5c1565366e223bf657d68ddac70b25ad13bcf Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 9 Mar 2015 13:22:52 -0700 Subject: [PATCH 22/27] Rework GeometryTile* interface --- src/mbgl/map/geometry_tile.cpp | 24 ++--- src/mbgl/map/geometry_tile.hpp | 68 +++--------- src/mbgl/map/tile_parser.cpp | 40 ++++---- src/mbgl/map/tile_parser.hpp | 11 +- src/mbgl/map/vector_tile.cpp | 154 +++++----------------------- src/mbgl/map/vector_tile.hpp | 62 +++-------- src/mbgl/renderer/symbol_bucket.cpp | 26 +++-- src/mbgl/renderer/symbol_bucket.hpp | 16 ++- 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 2800712ef25..f87468914c0 100644 --- a/src/mbgl/map/geometry_tile.cpp +++ b/src/mbgl/map/geometry_tile.cpp @@ -1,24 +1,16 @@ #include #include -#include +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 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 045c2984288..40a820274b1 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -8,9 +8,9 @@ #include #include #include +#include #include -#include #include #include #include @@ -34,69 +34,33 @@ using Geometry = mapbox::util::variant 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 getProperties() const = 0; - virtual GeometryCollection nextGeometry() = 0; + virtual mapbox::util::optional getValue(const std::string& key) const = 0; + virtual GeometryCollection getGeometries() const = 0; }; -std::ostream& operator<<(std::ostream&, const GeometryTileFeature& feature); - -template -class GeometryTileTagExtractor { -public: - GeometryTileTagExtractor(const GeometryTileLayer&); - - 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; } - +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 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 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& getKeys() const = 0; - virtual const std::unordered_map& getKeyIndex() const = 0; - virtual const std::vector& getValues() const = 0; - virtual const std::map>& getShaping() const = 0; - virtual util::ptr createFilteredTileLayer(const FilterExpression&) const = 0; -}; + GeometryTileFeatureExtractor(const GeometryTileFeature& feature_) + : feature(feature_) {} -class GeometryTile { -public: - virtual const util::ptr getLayer(const std::string&) const = 0; + mapbox::util::optional 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 be5b9013691..48f5b1405f0 100644 --- a/src/mbgl/map/tile_parser.cpp +++ b/src/mbgl/map/tile_parser.cpp @@ -187,14 +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; - const util::ptr 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 TileParser::createBucket(const StyleBucket &bucketDesc) } template -void TileParser::addBucketGeometries(Bucket& bucket, const util::ptr layer, const FilterExpression &filter) { - - util::ptr 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 TileParser::createFillBucket(const util::ptr 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, @@ -240,8 +238,8 @@ std::unique_ptr TileParser::createFillBucket(const util::ptr TileParser::createLineBucket(const util::ptr 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, @@ -251,8 +249,8 @@ std::unique_ptr TileParser::createLineBucket(const util::ptr TileParser::createSymbolBucket(const util::ptr 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 90a9037fd3f..e7c05e1b1e9 100644 --- a/src/mbgl/map/tile_parser.hpp +++ b/src/mbgl/map/tile_parser.hpp @@ -52,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 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); + 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 util::ptr 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 6eb0704a648..7f472400ae7 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(); @@ -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 VectorTileFeature::getValue(const std::string& key) const { + auto it = properties.find(key); + if (it != properties.end()) { + return it->second; + } + return mapbox::util::optional(); +} +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(layer)); + util::ptr layer = std::make_shared(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 VectorTile::getLayer(const std::string& name) const { auto layer_it = layers.find(name); if (layer_it != layers.end()) { - return std::make_shared(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 VectorTileLayer::createFilteredTileLayer(const FilterExpression& filterExpression) const { - return std::make_shared(*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::GeometryTileTagExtractor(const GeometryTileLayer& layer_) - : layer(layer_) {} - -template <> -mapbox::util::optional GeometryTileTagExtractor::getValue(const std::string& key) const { - if (key == "$type") { - return Value(uint64_t(type)); - } - - mapbox::util::optional 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&); - -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 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(&feature); - return *f; +const 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 c99a4a3fb7d..b9298356926 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 -#include -#include +#include 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 getProperties() const { return properties; } - virtual GeometryCollection nextGeometry(); - bool operator==(const VectorTileFeature&) const; + virtual GeometryFeatureType getType() const { return type; } + virtual mapbox::util::optional getValue(const std::string&) const; + virtual GeometryCollection getGeometries() const; private: uint64_t id = 0; @@ -27,66 +23,32 @@ class VectorTileFeature : public GeometryTileFeature { 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& getKeys() const { return keys; } - virtual inline const std::unordered_map& getKeyIndex() const { return key_index; } - virtual inline const std::vector& getValues() const { return values; } - virtual inline const std::map>& getShaping() const { return shaping; } - - virtual util::ptr createFilteredTileLayer(const FilterExpression&) const; + virtual std::size_t featureCount() const { return features.size(); } + virtual const util::ptr feature(std::size_t) const; private: + friend class VectorTile; + friend class VectorTileFeature; + std::string name; uint32_t extent = 4096; std::vector keys; - std::unordered_map key_index; std::vector values; - std::map> shaping; - const pbf feature_pbf; + std::vector features; }; class VectorTile : public GeometryTile { public: VectorTile(pbf); - VectorTile& operator=(VectorTile&&); virtual const util::ptr getLayer(const std::string&) const; private: - std::map layers; + std::map> layers; }; } diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index 631fcaf5d59..1d94714f76d 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -49,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 util::ptr layer, - const FilterExpression &filter, +std::vector SymbolBucket::processFeatures(const GeometryTileLayer& layer, + const FilterExpression& filter, GlyphStore &glyphStore, const Sprite &sprite) { auto &layout = *styleLayout; @@ -66,14 +65,22 @@ std::vector SymbolBucket::processFeatures(const util::ptr ranges; - util::ptr 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 SymbolBucket::processFeatures(const util::ptrgetGeometries(); multiline.emplace_back(); for (auto& geometry : geometryCollection) { const GeometryLine& line = geometry.get(); @@ -123,7 +130,8 @@ std::vector SymbolBucket::processFeatures(const util::ptr 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 9d2d002a631..75f66bff3c9 100644 --- a/src/mbgl/renderer/symbol_bucket.hpp +++ b/src/mbgl/renderer/symbol_bucket.hpp @@ -65,9 +65,13 @@ class SymbolBucket : public Bucket { bool hasTextData() const; bool hasIconData() const; - void addFeatures(const util::ptr 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 @@ class SymbolBucket : public Bucket { void drawIcons(IconShader& shader); private: - - std::vector processFeatures(const util::ptr 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); 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 From b7f04ee7c231d8165411161ff3f88138945da702 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 9 Mar 2015 17:39:37 -0700 Subject: [PATCH 23/27] Use single geometry format --- src/mbgl/geometry/pbf_geometry.hpp | 6 +- src/mbgl/map/geometry_tile.hpp | 8 +- src/mbgl/map/vector_tile.cpp | 55 +--- src/mbgl/renderer/fill_bucket.cpp | 13 +- src/mbgl/renderer/line_bucket.cpp | 448 ++++++++++++++-------------- src/mbgl/renderer/line_bucket.hpp | 1 + src/mbgl/renderer/symbol_bucket.cpp | 4 +- 7 files changed, 252 insertions(+), 283 deletions(-) diff --git a/src/mbgl/geometry/pbf_geometry.hpp b/src/mbgl/geometry/pbf_geometry.hpp index 46380e6fecd..84e15d10102 100644 --- a/src/mbgl/geometry/pbf_geometry.hpp +++ b/src/mbgl/geometry/pbf_geometry.hpp @@ -11,7 +11,7 @@ namespace mbgl { class PBFGeometry : private util::noncopyable { public: - inline explicit PBFGeometry(pbf& data); + inline explicit PBFGeometry(pbf data); enum command : uint8_t { end = 0, @@ -23,14 +23,14 @@ class PBFGeometry : private util::noncopyable { inline command next(int32_t &rx, int32_t &ry); private: - pbf& data; + pbf data; uint8_t cmd; uint32_t length; int32_t x, y; int32_t ox, oy; }; -PBFGeometry::PBFGeometry(pbf& data_) +PBFGeometry::PBFGeometry(pbf data_) : data(data_), cmd(1), length(0), diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index 40a820274b1..037b7a0db26 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -26,13 +26,7 @@ enum class GeometryFeatureType : uint8_t { Polygon = 3 }; -typedef Coordinate GeometryPoint; -typedef std::vector GeometryLine; -typedef std::vector GeometryPolygon; - -using Geometry = mapbox::util::variant; - -typedef std::vector GeometryCollection; +typedef std::vector> GeometryCollection; class GeometryTileFeature : public mbgl::util::noncopyable { public: diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 7f472400ae7..b90237e72b1 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -53,52 +53,25 @@ mapbox::util::optional VectorTileFeature::getValue(const std::string& key GeometryCollection VectorTileFeature::getGeometries() const { GeometryCollection result; - pbf geom_pbf = geometry_pbf; - - 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; - - if (type == GeometryFeatureType::Point) { - if ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { - GeometryPoint point(x, y); - result.emplace_back(GeometryPoint(x, y)); - } - } else if (type == GeometryFeatureType::LineString) { - GeometryLine line; - while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { - if (cmd == PBFGeometry::move_to) { - if (!line.empty()) { - result.push_back(line); - line.clear(); - } - } - line.emplace_back(x, y); - } - if (line.size()) { - result.push_back(line); - } - } else if (type == GeometryFeatureType::Polygon) { - GeometryLine line; - while ((cmd = current_geometry.next(x, y)) != PBFGeometry::end) { - if (cmd == PBFGeometry::move_to) { - if (line.size()) { - result.push_back(line); - line.clear(); - } - } - line.emplace_back(x, y); - } - if (line.size()) { + PBFGeometry geometry(geometry_pbf); + PBFGeometry::command cmd; + int32_t x, y; + + std::vector line; + + while ((cmd = geometry.next(x, y)) != PBFGeometry::end) { + if (cmd == PBFGeometry::move_to) { + if (!line.empty()) { result.push_back(line); line.clear(); } - } else { - throw std::runtime_error("unrecognized geometry type"); } + line.emplace_back(x, y); + } + + if (!line.empty()) { + result.push_back(line); } return std::move(result); diff --git a/src/mbgl/renderer/fill_bucket.cpp b/src/mbgl/renderer/fill_bucket.cpp index 18e337f9115..19ee302125c 100644 --- a/src/mbgl/renderer/fill_bucket.cpp +++ b/src/mbgl/renderer/fill_bucket.cpp @@ -66,13 +66,14 @@ FillBucket::~FillBucket() { void FillBucket::addGeometry(const GeometryCollection& geometryCollection) { for (auto& line_ : geometryCollection) { - const GeometryLine& vertices = line_.get(); - for (auto& v : vertices) { - line.emplace_back(ClipperLib::IntPoint(v.x, v.y)); + for (auto& v : line_) { + line.emplace_back(v.x, v.y); + } + if (line.size()) { + clipper.AddPath(line, ClipperLib::ptSubject, true); + line.clear(); + hasVertices = true; } - clipper.AddPath(line, ClipperLib::ptSubject, true); - line.clear(); - hasVertices = true; } tessellate(); diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index 1f2e26c1661..6eea0d8d0f0 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -43,290 +43,292 @@ typedef uint16_t PointElement; void LineBucket::addGeometry(const GeometryCollection& geometryCollection) { for (auto& line : geometryCollection) { - const GeometryLine& vertices = line.get(); + addGeometry(line); + } +} - auto &layout = *styleLayout; - // TODO: use roundLimit - // const float roundLimit = geometry.round_limit; +void LineBucket::addGeometry(const std::vector& vertices) { + auto &layout = *styleLayout; + // TODO: use roundLimit + // const float roundLimit = geometry.round_limit; - if (vertices.size() < 2) { - // fprintf(stderr, "a line must have at least two vertices\n"); - return; - } + if (vertices.size() < 2) { + // fprintf(stderr, "a line must have at least two vertices\n"); + return; + } - Coordinate firstVertex = vertices.front(); - Coordinate lastVertex = vertices.back(); - bool closed = firstVertex.x == lastVertex.x && firstVertex.y == lastVertex.y; + Coordinate firstVertex = vertices.front(); + Coordinate lastVertex = vertices.back(); + bool closed = firstVertex.x == lastVertex.x && firstVertex.y == lastVertex.y; - if (vertices.size() == 2 && closed) { - // fprintf(stderr, "a line may not have coincident points\n"); - return; - } + if (vertices.size() == 2 && closed) { + // fprintf(stderr, "a line may not have coincident points\n"); + return; + } - CapType beginCap = layout.cap; - CapType endCap = closed ? CapType::Butt : layout.cap; + CapType beginCap = layout.cap; + CapType endCap = closed ? CapType::Butt : layout.cap; - JoinType currentJoin = JoinType::Miter; + JoinType currentJoin = JoinType::Miter; - Coordinate currentVertex = Coordinate::null(), - prevVertex = Coordinate::null(), - nextVertex = Coordinate::null(); - vec2 prevNormal = vec2::null(), - nextNormal = vec2::null(); + Coordinate currentVertex = Coordinate::null(), + prevVertex = Coordinate::null(), + nextVertex = Coordinate::null(); + vec2 prevNormal = vec2::null(), + nextNormal = vec2::null(); - int32_t e1 = -1, e2 = -1, e3 = -1; + int32_t e1 = -1, e2 = -1, e3 = -1; - int8_t flip = 1; - double distance = 0; + int8_t flip = 1; + double distance = 0; - if (closed) { - currentVertex = vertices[vertices.size() - 2]; - nextNormal = util::normal(currentVertex, lastVertex); - } + if (closed) { + currentVertex = vertices[vertices.size() - 2]; + nextNormal = util::normal(currentVertex, lastVertex); + } - int32_t start_vertex = (int32_t)vertexBuffer.index(); + int32_t start_vertex = (int32_t)vertexBuffer.index(); - std::vector triangle_store; - std::vector point_store; + std::vector triangle_store; + std::vector point_store; - for (size_t i = 0; i < vertices.size(); ++i) { - if (nextNormal) prevNormal = { -nextNormal.x, -nextNormal.y }; - if (currentVertex) prevVertex = currentVertex; + for (size_t i = 0; i < vertices.size(); ++i) { + if (nextNormal) prevNormal = { -nextNormal.x, -nextNormal.y }; + if (currentVertex) prevVertex = currentVertex; - currentVertex = vertices[i]; - currentJoin = layout.join; + currentVertex = vertices[i]; + currentJoin = layout.join; - if (prevVertex) distance += util::dist(currentVertex, prevVertex); + if (prevVertex) distance += util::dist(currentVertex, prevVertex); - // Find the next vertex. - if (i + 1 < vertices.size()) { - nextVertex = vertices[i + 1]; - } else { - nextVertex = Coordinate::null(); - } + // Find the next vertex. + if (i + 1 < vertices.size()) { + nextVertex = vertices[i + 1]; + } else { + nextVertex = Coordinate::null(); + } - // If the line is closed, we treat the last vertex like the first vertex. - if (!nextVertex && closed) { - nextVertex = vertices[1]; - } + // If the line is closed, we treat the last vertex like the first vertex. + if (!nextVertex && closed) { + nextVertex = vertices[1]; + } - if (nextVertex) { - // if two consecutive vertices exist, skip one - if (currentVertex.x == nextVertex.x && currentVertex.y == nextVertex.y) continue; - } + if (nextVertex) { + // if two consecutive vertices exist, skip one + if (currentVertex.x == nextVertex.x && currentVertex.y == nextVertex.y) continue; + } - // Calculate the normal towards the next vertex in this line. In case - // there is no next vertex, pretend that the line is continuing straight, - // meaning that we are just reversing the previous normal - if (nextVertex) { - nextNormal = util::normal(currentVertex, nextVertex); - } else { - nextNormal = { -prevNormal.x, -prevNormal.y }; - } + // Calculate the normal towards the next vertex in this line. In case + // there is no next vertex, pretend that the line is continuing straight, + // meaning that we are just reversing the previous normal + if (nextVertex) { + nextNormal = util::normal(currentVertex, nextVertex); + } else { + nextNormal = { -prevNormal.x, -prevNormal.y }; + } - // If we still don't have a previous normal, this is the beginning of a - // non-closed line, so we're doing a straight "join". - if (!prevNormal) { - prevNormal = { -nextNormal.x, -nextNormal.y }; - } + // If we still don't have a previous normal, this is the beginning of a + // non-closed line, so we're doing a straight "join". + if (!prevNormal) { + prevNormal = { -nextNormal.x, -nextNormal.y }; + } - // Determine the normal of the join extrusion. It is the angle bisector - // of the segments between the previous line and the next line. - vec2 joinNormal = { - prevNormal.x + nextNormal.x, - prevNormal.y + nextNormal.y - }; - - // Cross product yields 0..1 depending on whether they are parallel - // or perpendicular. - double joinAngularity = nextNormal.x * joinNormal.y - nextNormal.y * joinNormal.x; - joinNormal.x /= joinAngularity; - joinNormal.y /= joinAngularity; - double roundness = std::fmax(std::abs(joinNormal.x), std::abs(joinNormal.y)); - - - // Switch to miter joins if the angle is very low. - if (currentJoin != JoinType::Miter) { - if (std::fabs(joinAngularity) < 0.5 && roundness < layout.miter_limit) { - currentJoin = JoinType::Miter; - } + // Determine the normal of the join extrusion. It is the angle bisector + // of the segments between the previous line and the next line. + vec2 joinNormal = { + prevNormal.x + nextNormal.x, + prevNormal.y + nextNormal.y + }; + + // Cross product yields 0..1 depending on whether they are parallel + // or perpendicular. + double joinAngularity = nextNormal.x * joinNormal.y - nextNormal.y * joinNormal.x; + joinNormal.x /= joinAngularity; + joinNormal.y /= joinAngularity; + double roundness = std::fmax(std::abs(joinNormal.x), std::abs(joinNormal.y)); + + + // Switch to miter joins if the angle is very low. + if (currentJoin != JoinType::Miter) { + if (std::fabs(joinAngularity) < 0.5 && roundness < layout.miter_limit) { + currentJoin = JoinType::Miter; } + } - // Add offset square begin cap. - if (!prevVertex && beginCap == CapType::Square) { - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * (prevNormal.x + prevNormal.y), flip * (-prevNormal.x + prevNormal.y), // extrude normal - 0, 0, distance) - start_vertex; // texture normal + // Add offset square begin cap. + if (!prevVertex && beginCap == CapType::Square) { + // Add first vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + flip * (prevNormal.x + prevNormal.y), flip * (-prevNormal.x + prevNormal.y), // extrude normal + 0, 0, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - // Add second vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * (prevNormal.x - prevNormal.y), flip * (prevNormal.x + prevNormal.y), // extrude normal - 0, 1, distance) - start_vertex; // texture normal + // Add second vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + flip * (prevNormal.x - prevNormal.y), flip * (prevNormal.x + prevNormal.y), // extrude normal + 0, 1, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - } + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; + } - // Add offset square end cap. - else if (!nextVertex && endCap == CapType::Square) { - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - nextNormal.x - flip * nextNormal.y, flip * nextNormal.x + nextNormal.y, // extrude normal - 0, 0, distance) - start_vertex; // texture normal + // Add offset square end cap. + else if (!nextVertex && endCap == CapType::Square) { + // Add first vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + nextNormal.x - flip * nextNormal.y, flip * nextNormal.x + nextNormal.y, // extrude normal + 0, 0, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - // Add second vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - nextNormal.x + flip * nextNormal.y, -flip * nextNormal.x + nextNormal.y, // extrude normal - 0, 1, distance) - start_vertex; // texture normal + // Add second vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + nextNormal.x + flip * nextNormal.y, -flip * nextNormal.x + nextNormal.y, // extrude normal + 0, 1, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - } + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; + } - else if (currentJoin == JoinType::Miter) { - // MITER JOIN - if (std::fabs(joinAngularity) < 0.01) { - // The two normals are almost parallel. - joinNormal.x = -nextNormal.y; - joinNormal.y = nextNormal.x; - } else if (roundness > layout.miter_limit) { - // If the miter grows too large, flip the direction to make a - // bevel join. - joinNormal.x = (prevNormal.x - nextNormal.x) / joinAngularity; - joinNormal.y = (prevNormal.y - nextNormal.y) / joinAngularity; - } + else if (currentJoin == JoinType::Miter) { + // MITER JOIN + if (std::fabs(joinAngularity) < 0.01) { + // The two normals are almost parallel. + joinNormal.x = -nextNormal.y; + joinNormal.y = nextNormal.x; + } else if (roundness > layout.miter_limit) { + // If the miter grows too large, flip the direction to make a + // bevel join. + joinNormal.x = (prevNormal.x - nextNormal.x) / joinAngularity; + joinNormal.y = (prevNormal.y - nextNormal.y) / joinAngularity; + } - if (roundness > layout.miter_limit) { - flip = -flip; - } + if (roundness > layout.miter_limit) { + flip = -flip; + } - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * joinNormal.x, flip * joinNormal.y, // extrude normal - 0, 0, distance) - start_vertex; // texture normal + // Add first vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + flip * joinNormal.x, flip * joinNormal.y, // extrude normal + 0, 0, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - // Add second vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - -flip * joinNormal.x, -flip * joinNormal.y, // extrude normal - 0, 1, distance) - start_vertex; // texture normal + // Add second vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + -flip * joinNormal.x, -flip * joinNormal.y, // extrude normal + 0, 1, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - if ((!prevVertex && beginCap == CapType::Round) || - (!nextVertex && endCap == CapType::Round)) { - point_store.emplace_back(e1); - } + if ((!prevVertex && beginCap == CapType::Round) || + (!nextVertex && endCap == CapType::Round)) { + point_store.emplace_back(e1); } + } - else { - // Close up the previous line - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * prevNormal.y, -flip * prevNormal.x, // extrude normal - 0, 0, distance) - start_vertex; // texture normal - - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + else { + // Close up the previous line + // Add first vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + flip * prevNormal.y, -flip * prevNormal.x, // extrude normal + 0, 0, distance) - start_vertex; // texture normal - // Add second vertex. - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - -flip * prevNormal.y, flip * prevNormal.x, // extrude normal - 0, 1, distance) - start_vertex; // texture normal + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + // Add second vertex. + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + -flip * prevNormal.y, flip * prevNormal.x, // extrude normal + 0, 1, distance) - start_vertex; // texture normal - prevNormal = { -nextNormal.x, -nextNormal.y }; - flip = 1; + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; + prevNormal = { -nextNormal.x, -nextNormal.y }; + flip = 1; - // begin/end caps - if ((!prevVertex && beginCap == CapType::Round) || - (!nextVertex && endCap == CapType::Round)) { - point_store.emplace_back(e1); - } + // begin/end caps + if ((!prevVertex && beginCap == CapType::Round) || + (!nextVertex && endCap == CapType::Round)) { + point_store.emplace_back(e1); + } - if (currentJoin == JoinType::Round) { - if (prevVertex && nextVertex && (!closed || i > 0)) { - point_store.emplace_back(e1); - } - // Reset the previous vertices so that we don't accidentally create - // any triangles. - e1 = -1; e2 = -1; e3 = -1; + if (currentJoin == JoinType::Round) { + if (prevVertex && nextVertex && (!closed || i > 0)) { + point_store.emplace_back(e1); } - // Start the new quad. - // Add first vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - -flip * nextNormal.y, flip * nextNormal.x, // extrude normal - 0, 0, distance) - start_vertex; // texture normal + // Reset the previous vertices so that we don't accidentally create + // any triangles. + e1 = -1; e2 = -1; e3 = -1; + } + + // Start the new quad. + // Add first vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + -flip * nextNormal.y, flip * nextNormal.x, // extrude normal + 0, 0, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; - // Add second vertex - e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos - flip * nextNormal.y, -flip * nextNormal.x, // extrude normal - 0, 1, distance) - start_vertex; // texture normal + // Add second vertex + e3 = (int32_t)vertexBuffer.add(currentVertex.x, currentVertex.y, // vertex pos + flip * nextNormal.y, -flip * nextNormal.x, // extrude normal + 0, 1, distance) - start_vertex; // texture normal - if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); - e1 = e2; e2 = e3; - } + if (e1 >= 0 && e2 >= 0 && e3 >= 0) triangle_store.emplace_back(e1, e2, e3); + e1 = e2; e2 = e3; } + } - size_t end_vertex = vertexBuffer.index(); - size_t vertex_count = end_vertex - start_vertex; - - // Store the triangle/line groups. - { - if (!triangleGroups.size() || (triangleGroups.back()->vertex_length + vertex_count > 65535)) { - // Move to a new group because the old one can't hold the geometry. - triangleGroups.emplace_back(util::make_unique()); - } + size_t end_vertex = vertexBuffer.index(); + size_t vertex_count = end_vertex - start_vertex; - assert(triangleGroups.back()); - triangle_group_type& group = *triangleGroups.back(); - for (const TriangleElement& triangle : triangle_store) { - triangleElementsBuffer.add( - group.vertex_length + triangle.a, - group.vertex_length + triangle.b, - group.vertex_length + triangle.c - ); - } + // Store the triangle/line groups. + { + if (!triangleGroups.size() || (triangleGroups.back()->vertex_length + vertex_count > 65535)) { + // Move to a new group because the old one can't hold the geometry. + triangleGroups.emplace_back(util::make_unique()); + } - group.vertex_length += vertex_count; - group.elements_length += triangle_store.size(); + assert(triangleGroups.back()); + triangle_group_type& group = *triangleGroups.back(); + for (const TriangleElement& triangle : triangle_store) { + triangleElementsBuffer.add( + group.vertex_length + triangle.a, + group.vertex_length + triangle.b, + group.vertex_length + triangle.c + ); } - // Store the line join/cap groups. - { - if (!pointGroups.size() || (pointGroups.back()->vertex_length + vertex_count > 65535)) { - // Move to a new group because the old one can't hold the geometry. - pointGroups.emplace_back(util::make_unique()); - } + group.vertex_length += vertex_count; + group.elements_length += triangle_store.size(); + } - assert(pointGroups.back()); - point_group_type& group = *pointGroups.back(); - for (PointElement point : point_store) { - pointElementsBuffer.add(group.vertex_length + point); - } + // Store the line join/cap groups. + { + if (!pointGroups.size() || (pointGroups.back()->vertex_length + vertex_count > 65535)) { + // Move to a new group because the old one can't hold the geometry. + pointGroups.emplace_back(util::make_unique()); + } - group.vertex_length += vertex_count; - group.elements_length += point_store.size(); + assert(pointGroups.back()); + point_group_type& group = *pointGroups.back(); + for (PointElement point : point_store) { + pointElementsBuffer.add(group.vertex_length + point); } + + group.vertex_length += vertex_count; + group.elements_length += point_store.size(); } } diff --git a/src/mbgl/renderer/line_bucket.hpp b/src/mbgl/renderer/line_bucket.hpp index 4190b79f574..25b21901766 100644 --- a/src/mbgl/renderer/line_bucket.hpp +++ b/src/mbgl/renderer/line_bucket.hpp @@ -38,6 +38,7 @@ class LineBucket : public Bucket { bool hasData() const override; 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 1d94714f76d..c755573df9c 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -107,9 +107,7 @@ std::vector SymbolBucket::processFeatures(const GeometryTileLayer auto &multiline = ft.geometry; GeometryCollection geometryCollection = feature->getGeometries(); - multiline.emplace_back(); - for (auto& geometry : geometryCollection) { - const GeometryLine& line = geometry.get(); + for (auto& line : geometryCollection) { multiline.emplace_back(); for (auto& point : line) { multiline.back().emplace_back(point.x, point.y); From 4d3dcea82c44f36d3b3cc4e284373d98410ae689 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 9 Mar 2015 17:58:33 -0700 Subject: [PATCH 24/27] Revert FeatureType rename --- src/mbgl/map/geometry_tile.hpp | 4 ++-- src/mbgl/map/vector_tile.cpp | 2 +- src/mbgl/map/vector_tile.hpp | 4 ++-- src/mbgl/style/filter_expression.cpp | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index 037b7a0db26..f94ce15d7cd 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -19,7 +19,7 @@ namespace mbgl { -enum class GeometryFeatureType : uint8_t { +enum class FeatureType : uint8_t { Unknown = 0, Point = 1, LineString = 2, @@ -30,7 +30,7 @@ typedef std::vector> GeometryCollection; class GeometryTileFeature : public mbgl::util::noncopyable { public: - virtual GeometryFeatureType getType() const = 0; + virtual FeatureType getType() const = 0; virtual mapbox::util::optional getValue(const std::string& key) const = 0; virtual GeometryCollection getGeometries() const = 0; }; diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index b90237e72b1..501ae4ff62f 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -34,7 +34,7 @@ VectorTileFeature::VectorTileFeature(pbf feature_pbf, const VectorTileLayer& lay } } } else if (feature_pbf.tag == 3) { // type - type = (GeometryFeatureType)feature_pbf.varint(); + type = (FeatureType)feature_pbf.varint(); } else if (feature_pbf.tag == 4) { // geometry geometry_pbf = feature_pbf.message(); } else { diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index b9298356926..a7521cd3279 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -12,13 +12,13 @@ class VectorTileFeature : public GeometryTileFeature { public: VectorTileFeature(pbf, const VectorTileLayer&); - virtual GeometryFeatureType getType() const { return type; } + virtual FeatureType getType() const { return type; } virtual mapbox::util::optional getValue(const std::string&) const; virtual GeometryCollection getGeometries() const; private: uint64_t id = 0; - GeometryFeatureType type = GeometryFeatureType::Unknown; + FeatureType type = FeatureType::Unknown; std::map properties; pbf geometry_pbf; }; diff --git a/src/mbgl/style/filter_expression.cpp b/src/mbgl/style/filter_expression.cpp index e5a2e3abc3d..ec44b57b550 100644 --- a/src/mbgl/style/filter_expression.cpp +++ b/src/mbgl/style/filter_expression.cpp @@ -5,14 +5,14 @@ namespace mbgl { Value parseFeatureType(const Value& value) { if (value == std::string("Point")) { - return Value(uint64_t(GeometryFeatureType::Point)); + return Value(uint64_t(FeatureType::Point)); } else if (value == std::string("LineString")) { - return Value(uint64_t(GeometryFeatureType::LineString)); + return Value(uint64_t(FeatureType::LineString)); } else if (value == std::string("Polygon")) { - return Value(uint64_t(GeometryFeatureType::Polygon)); + return Value(uint64_t(FeatureType::Polygon)); } else { Log::Warning(Event::ParseStyle, "value for $type filter must be Point, LineString, or Polygon"); - return Value(uint64_t(GeometryFeatureType::Unknown)); + return Value(uint64_t(FeatureType::Unknown)); } } From 5fa628bc001dd19cb84f816d3834a1ec126da089 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 10 Mar 2015 10:31:24 -0700 Subject: [PATCH 25/27] Inline PBFGeometry --- src/mbgl/geometry/pbf_geometry.hpp | 77 ------------------------------ src/mbgl/map/vector_tile.cpp | 57 +++++++++++++--------- 2 files changed, 35 insertions(+), 99 deletions(-) delete mode 100644 src/mbgl/geometry/pbf_geometry.hpp diff --git a/src/mbgl/geometry/pbf_geometry.hpp b/src/mbgl/geometry/pbf_geometry.hpp deleted file mode 100644 index 84e15d10102..00000000000 --- a/src/mbgl/geometry/pbf_geometry.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef MBGL_GEOMETRY_PBF_GEOMETRY -#define MBGL_GEOMETRY_PBF_GEOMETRY - -#include -#include - -#include - -namespace mbgl { - -class PBFGeometry : private util::noncopyable { - -public: - inline explicit PBFGeometry(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; -}; - -PBFGeometry::PBFGeometry(pbf data_) - : data(data_), - cmd(1), - length(0), - x(0), y(0), - ox(0), oy(0) {} - -PBFGeometry::command PBFGeometry::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/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 501ae4ff62f..9ea57f4f670 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -1,10 +1,4 @@ #include -#include -#include -#include - -#include -#include using namespace mbgl; @@ -52,29 +46,48 @@ mapbox::util::optional VectorTileFeature::getValue(const std::string& key } GeometryCollection VectorTileFeature::getGeometries() const { - GeometryCollection result; + pbf data(geometry_pbf); + uint8_t cmd = 1; + uint32_t length = 0; + int32_t x = 0; + int32_t y = 0; + + GeometryCollection lines; + + lines.emplace_back(); + std::vector* line = &lines.back(); + + while (data.data < data.end) { + if (length == 0) { + uint32_t cmd_length = data.varint(); + cmd = cmd_length & 0x7; + length = cmd_length >> 3; + } - PBFGeometry geometry(geometry_pbf); - PBFGeometry::command cmd; - int32_t x, y; + --length; - std::vector line; + if (cmd == 1 || cmd == 2) { + x += data.svarint(); + y += data.svarint(); - while ((cmd = geometry.next(x, y)) != PBFGeometry::end) { - if (cmd == PBFGeometry::move_to) { - if (!line.empty()) { - result.push_back(line); - line.clear(); + if (cmd == 1 && !line->empty()) { // moveTo + lines.emplace_back(); + line = &lines.back(); } - } - line.emplace_back(x, y); - } - if (!line.empty()) { - result.push_back(line); + line->emplace_back(x, y); + + } else if (cmd == 7) { // closePolygon + if (!line->empty()) { + line->push_back((*line)[0]); + } + + } else { + throw std::runtime_error("unknown command"); + } } - return std::move(result); + return lines; } VectorTile::VectorTile(pbf tile_pbf) { From 05df041c15ba9e509bc98b043f5368c9a23fa688 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 10 Mar 2015 10:32:25 -0700 Subject: [PATCH 26/27] Don't use const on value-type returns --- src/mbgl/map/geometry_tile.hpp | 4 ++-- src/mbgl/map/vector_tile.cpp | 4 ++-- src/mbgl/map/vector_tile.hpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mbgl/map/geometry_tile.hpp b/src/mbgl/map/geometry_tile.hpp index f94ce15d7cd..f303a32bde6 100644 --- a/src/mbgl/map/geometry_tile.hpp +++ b/src/mbgl/map/geometry_tile.hpp @@ -38,12 +38,12 @@ class GeometryTileFeature : public mbgl::util::noncopyable { class GeometryTileLayer : public mbgl::util::noncopyable { public: virtual std::size_t featureCount() const = 0; - virtual const util::ptr feature(std::size_t i) const = 0; + virtual util::ptr feature(std::size_t i) const = 0; }; class GeometryTile : public mbgl::util::noncopyable { public: - virtual const util::ptr getLayer(const std::string&) const = 0; + virtual util::ptr getLayer(const std::string&) const = 0; }; class GeometryTileFeatureExtractor { diff --git a/src/mbgl/map/vector_tile.cpp b/src/mbgl/map/vector_tile.cpp index 9ea57f4f670..e9ae52e9ad1 100644 --- a/src/mbgl/map/vector_tile.cpp +++ b/src/mbgl/map/vector_tile.cpp @@ -101,7 +101,7 @@ VectorTile::VectorTile(pbf tile_pbf) { } } -const util::ptr VectorTile::getLayer(const std::string& name) const { +util::ptr VectorTile::getLayer(const std::string& name) const { auto layer_it = layers.find(name); if (layer_it != layers.end()) { return layer_it->second; @@ -127,6 +127,6 @@ VectorTileLayer::VectorTileLayer(pbf layer_pbf) { } } -const util::ptr VectorTileLayer::feature(std::size_t i) const { +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 a7521cd3279..b27f6bb397d 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -28,7 +28,7 @@ class VectorTileLayer : public GeometryTileLayer { VectorTileLayer(pbf); virtual std::size_t featureCount() const { return features.size(); } - virtual const util::ptr feature(std::size_t) const; + virtual util::ptr feature(std::size_t) const; private: friend class VectorTile; @@ -45,7 +45,7 @@ class VectorTile : public GeometryTile { public: VectorTile(pbf); - virtual const util::ptr getLayer(const std::string&) const; + virtual util::ptr getLayer(const std::string&) const; private: std::map> layers; From 062d33c8dbf0b753fccf5b48e5d0ec338515161e Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 10 Mar 2015 10:33:04 -0700 Subject: [PATCH 27/27] =?UTF-8?q?virtual=20=E2=87=A2=20override=20in=20der?= =?UTF-8?q?ived=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mbgl/map/vector_tile.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mbgl/map/vector_tile.hpp b/src/mbgl/map/vector_tile.hpp index b27f6bb397d..fc8c5966a03 100644 --- a/src/mbgl/map/vector_tile.hpp +++ b/src/mbgl/map/vector_tile.hpp @@ -12,9 +12,9 @@ class VectorTileFeature : public GeometryTileFeature { public: VectorTileFeature(pbf, const VectorTileLayer&); - virtual FeatureType getType() const { return type; } - virtual mapbox::util::optional getValue(const std::string&) const; - virtual GeometryCollection getGeometries() const; + FeatureType getType() const override { return type; } + mapbox::util::optional getValue(const std::string&) const override; + GeometryCollection getGeometries() const override; private: uint64_t id = 0; @@ -27,8 +27,8 @@ class VectorTileLayer : public GeometryTileLayer { public: VectorTileLayer(pbf); - virtual std::size_t featureCount() const { return features.size(); } - virtual util::ptr feature(std::size_t) const; + std::size_t featureCount() const override { return features.size(); } + util::ptr feature(std::size_t) const override; private: friend class VectorTile; @@ -45,7 +45,7 @@ class VectorTile : public GeometryTile { public: VectorTile(pbf); - virtual util::ptr getLayer(const std::string&) const; + util::ptr getLayer(const std::string&) const override; private: std::map> layers;