diff options
author | Anand Thakker <github@anandthakker.net> | 2018-03-20 21:08:06 -0400 |
---|---|---|
committer | Anand Thakker <github@anandthakker.net> | 2018-04-05 15:55:57 -0400 |
commit | 0f9953c7f67ed6ac536519ff4467bb8e2f8ae501 (patch) | |
tree | 194d41d98fa2df872a85e27a7bcb72b9dc1e7f3c | |
parent | 05d24448bdea29e302f788f050829459adba8e83 (diff) | |
download | qtlocation-mapboxgl-0f9953c7f67ed6ac536519ff4467bb8e2f8ae501.tar.gz |
Replace vector-tile with vtzero
-rw-r--r-- | CMakeLists.txt | 4 | ||||
-rw-r--r-- | cmake/benchmark.cmake | 2 | ||||
-rw-r--r-- | cmake/core.cmake | 2 | ||||
-rw-r--r-- | src/mbgl/tile/vector_tile_data.cpp | 147 | ||||
-rw-r--r-- | src/mbgl/tile/vector_tile_data.hpp | 20 |
5 files changed, 138 insertions, 37 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 181c91df0f..1a5145e196 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,14 +56,14 @@ mason_use(geojsonvt VERSION 6.3.0 HEADER_ONLY) mason_use(supercluster VERSION 0.2.2 HEADER_ONLY) mason_use(kdbush VERSION 0.1.1-1 HEADER_ONLY) mason_use(earcut VERSION 0.12.4 HEADER_ONLY) -mason_use(protozero VERSION 1.5.2 HEADER_ONLY) +mason_use(protozero VERSION 1.6.1 HEADER_ONLY) mason_use(pixelmatch VERSION 0.10.0 HEADER_ONLY) mason_use(geojson VERSION 0.4.2 HEADER_ONLY) mason_use(polylabel VERSION 1.0.3 HEADER_ONLY) mason_use(wagyu VERSION 0.4.3 HEADER_ONLY) mason_use(shelf-pack VERSION 2.1.1 HEADER_ONLY) mason_use(cheap-ruler VERSION 2.5.3 HEADER_ONLY) -mason_use(vector-tile VERSION 1.0.1 HEADER_ONLY) +mason_use(vtzero VERSION 1.0.0 HEADER_ONLY) add_definitions(-DRAPIDJSON_HAS_STDSTRING=1) diff --git a/cmake/benchmark.cmake b/cmake/benchmark.cmake index ea5b3dfa7a..02c4eb6594 100644 --- a/cmake/benchmark.cmake +++ b/cmake/benchmark.cmake @@ -18,7 +18,7 @@ target_add_mason_package(mbgl-benchmark PRIVATE benchmark) target_add_mason_package(mbgl-benchmark PRIVATE geojson) target_add_mason_package(mbgl-benchmark PRIVATE rapidjson) target_add_mason_package(mbgl-benchmark PRIVATE protozero) -target_add_mason_package(mbgl-benchmark PRIVATE vector-tile) +target_add_mason_package(mbgl-benchmark PRIVATE vtzero) mbgl_platform_benchmark() diff --git a/cmake/core.cmake b/cmake/core.cmake index 43ec141b78..08d281dfbb 100644 --- a/cmake/core.cmake +++ b/cmake/core.cmake @@ -21,7 +21,7 @@ target_add_mason_package(mbgl-core PRIVATE protozero) target_add_mason_package(mbgl-core PRIVATE polylabel) target_add_mason_package(mbgl-core PRIVATE wagyu) target_add_mason_package(mbgl-core PRIVATE shelf-pack) -target_add_mason_package(mbgl-core PRIVATE vector-tile) +target_add_mason_package(mbgl-core PRIVATE vtzero) mbgl_platform_core() diff --git a/src/mbgl/tile/vector_tile_data.cpp b/src/mbgl/tile/vector_tile_data.cpp index 2d4a01bda3..6e619dab48 100644 --- a/src/mbgl/tile/vector_tile_data.cpp +++ b/src/mbgl/tile/vector_tile_data.cpp @@ -3,40 +3,114 @@ namespace mbgl { -VectorTileFeature::VectorTileFeature(const mapbox::vector_tile::layer& layer, - const protozero::data_view& view) - : feature(view, layer) { +VectorTileFeature::VectorTileFeature(const vtzero::layer& layer_, + const vtzero::feature& feature_) + : feature(feature_), layer(layer_) { } FeatureType VectorTileFeature::getType() const { - switch (feature.getType()) { - case mapbox::vector_tile::GeomType::POINT: + switch (feature.geometry_type()) { + case vtzero::GeomType::POINT: return FeatureType::Point; - case mapbox::vector_tile::GeomType::LINESTRING: + case vtzero::GeomType::LINESTRING: return FeatureType::LineString; - case mapbox::vector_tile::GeomType::POLYGON: + case vtzero::GeomType::POLYGON: return FeatureType::Polygon; default: return FeatureType::Unknown; } } +struct PropertyValueMapping : vtzero::property_value_mapping { + using float_type = double; +}; + optional<Value> VectorTileFeature::getValue(const std::string& key) const { - return feature.getValue(key); + optional<Value> result; + feature.for_each_property([&](vtzero::property&& p) { + if (p.key() == key) { + result = vtzero::convert_property_value<Value, PropertyValueMapping>(p.value()); + } + return !result; + }); + return result; } std::unordered_map<std::string, Value> VectorTileFeature::getProperties() const { - return feature.getProperties(); + std::unordered_map<std::string, Value> map; + feature.for_each_property([&](const vtzero::property& p) { + map.emplace(std::string(p.key()), vtzero::convert_property_value<Value, PropertyValueMapping>(p.value())); + return true; + }); + return map; } optional<FeatureIdentifier> VectorTileFeature::getID() const { - return feature.getID(); + return {feature.id()}; } +// Decode every geometry into a common structure: GeometryCollection, aka +// std::vector<std::vector<mapbox::geometry::Point<int16_t>>> +struct GeometryHandler { + GeometryHandler(const float scale_) : scale(scale_) {} + + void begin(uint32_t count) { + // cap allocation to 1MB + constexpr std::uint32_t MAX_LENGTH = (1024 * 1024) / 16; + if (count > MAX_LENGTH) { + count = MAX_LENGTH; + } + result_.emplace_back(); + result_.back().reserve(count); + } + + void add_point(vtzero::point point) { + float scaled_x = ::roundf(static_cast<float>(point.x) * scale); + float scaled_y = ::roundf(static_cast<float>(point.y) * scale); + static const float max_coord = static_cast<float>(std::numeric_limits<typename GeometryCollection::coordinate_type>::max()); + static const float min_coord = static_cast<float>(std::numeric_limits<typename GeometryCollection::coordinate_type>::min()); + + if (scaled_x > max_coord || + scaled_x < min_coord || + scaled_y > max_coord || + scaled_y < min_coord + ) { + std::runtime_error("paths outside valid range of coordinate_type"); + } else { + result_.back().emplace_back( + static_cast<typename GeometryCollection::coordinate_type>(scaled_x), + static_cast<typename GeometryCollection::coordinate_type>(scaled_y)); + } + } + + // decode_point_geometry handlers + void points_begin(uint32_t count) { begin(count); } + void points_point(vtzero::point point) { add_point(point); } + void points_end() {} + + // decode_linestring_geometry handlers + void linestring_begin(uint32_t count) { begin(count); } + void linestring_point(vtzero::point point) { add_point(point); } + void linestring_end() {} + + // decode_polygon_geometry handlers + void ring_begin(uint32_t count) { begin(count); } + void ring_point(vtzero::point point) { add_point(point); } + void ring_end(vtzero::ring_type) {} + + GeometryCollection result() { + return result_; + } + + const float scale; + GeometryCollection result_; +}; + GeometryCollection VectorTileFeature::getGeometries() const { - const float scale = float(util::EXTENT) / feature.getExtent(); - auto lines = feature.getGeometries<GeometryCollection>(scale); - if (feature.getVersion() >= 2 || feature.getType() != mapbox::vector_tile::GeomType::POLYGON) { + const float scale = float(util::EXTENT) / layer.extent(); + const vtzero::geometry geometry = feature.geometry(); + GeometryCollection lines = vtzero::decode_geometry(geometry, GeometryHandler(scale)); + if (layer.version() >= 2 || feature.geometry_type() != vtzero::GeomType::POLYGON) { return lines; } else { return fixupPolygons(lines); @@ -44,23 +118,30 @@ GeometryCollection VectorTileFeature::getGeometries() const { } VectorTileLayer::VectorTileLayer(std::shared_ptr<const std::string> data_, - const protozero::data_view& view) - : data(std::move(data_)), layer(view) { + const vtzero::layer& layer_) + : data(std::move(data_)), layer(layer_) { + layer.for_each_feature([&](vtzero::feature&& f) { + features.push_back(f); + return true; + }); } std::size_t VectorTileLayer::featureCount() const { - return layer.featureCount(); + return layer.num_features(); } std::unique_ptr<GeometryTileFeature> VectorTileLayer::getFeature(std::size_t i) const { - return std::make_unique<VectorTileFeature>(layer, layer.getFeature(i)); + return std::make_unique<VectorTileFeature>(layer, features[i]); } std::string VectorTileLayer::getName() const { - return layer.getName(); + return static_cast<std::string>(layer.name()); } -VectorTileData::VectorTileData(std::shared_ptr<const std::string> data_) : data(std::move(data_)) { +VectorTileData::VectorTileData(std::shared_ptr<const std::string> data_) : + data(std::move(data_)), + tile(*data) +{ } std::unique_ptr<GeometryTileData> VectorTileData::clone() const { @@ -68,13 +149,7 @@ std::unique_ptr<GeometryTileData> VectorTileData::clone() const { } std::unique_ptr<GeometryTileLayer> VectorTileData::getLayer(const std::string& name) const { - if (!parsed) { - // We're parsing this lazily so that we can construct VectorTileData objects on the main - // thread without incurring the overhead of parsing immediately. - layers = mapbox::vector_tile::buffer(*data).getLayers(); - parsed = true; - } - + parseLayers(); auto it = layers.find(name); if (it != layers.end()) { return std::make_unique<VectorTileLayer>(data, it->second); @@ -83,7 +158,25 @@ std::unique_ptr<GeometryTileLayer> VectorTileData::getLayer(const std::string& n } std::vector<std::string> VectorTileData::layerNames() const { - return mapbox::vector_tile::buffer(*data).layerNames(); + parseLayers(); + std::vector<std::string> names; + names.reserve(layers.size()); + for (const auto& entry : layers) { + names.emplace_back(entry.first); + } + return names; +} + +void VectorTileData::parseLayers() const { + if (!parsed) { + // We're parsing this lazily so that we can construct VectorTileData objects on the main + // thread without incurring the overhead of parsing immediately. + tile.for_each_layer([&](vtzero::layer&& layer) { + layers[static_cast<std::string>(layer.name())] = std::move(layer); + return true; + }); + parsed = true; + } } } // namespace mbgl diff --git a/src/mbgl/tile/vector_tile_data.hpp b/src/mbgl/tile/vector_tile_data.hpp index 48beaf9d07..4eadff3571 100644 --- a/src/mbgl/tile/vector_tile_data.hpp +++ b/src/mbgl/tile/vector_tile_data.hpp @@ -1,8 +1,9 @@ #include <mbgl/tile/geometry_tile_data.hpp> -#include <mapbox/vector_tile.hpp> +#include <vtzero/vector_tile.hpp> #include <protozero/pbf_reader.hpp> +#include <map> #include <unordered_map> #include <functional> #include <utility> @@ -11,7 +12,7 @@ namespace mbgl { class VectorTileFeature : public GeometryTileFeature { public: - VectorTileFeature(const mapbox::vector_tile::layer&, const protozero::data_view&); + VectorTileFeature(const vtzero::layer&, const vtzero::feature&); FeatureType getType() const override; optional<Value> getValue(const std::string& key) const override; @@ -20,12 +21,15 @@ public: GeometryCollection getGeometries() const override; private: - mapbox::vector_tile::feature feature; + vtzero::feature feature; + + // hold this reference because feature depends on it + const vtzero::layer& layer; }; class VectorTileLayer : public GeometryTileLayer { public: - VectorTileLayer(std::shared_ptr<const std::string> data, const protozero::data_view&); + VectorTileLayer(std::shared_ptr<const std::string> data, const vtzero::layer&); std::size_t featureCount() const override; std::unique_ptr<GeometryTileFeature> getFeature(std::size_t i) const override; @@ -33,7 +37,8 @@ public: private: std::shared_ptr<const std::string> data; - mapbox::vector_tile::layer layer; + vtzero::layer layer; + std::vector<vtzero::feature> features; }; class VectorTileData : public GeometryTileData { @@ -46,9 +51,12 @@ public: std::vector<std::string> layerNames() const; private: + void parseLayers() const; + std::shared_ptr<const std::string> data; + vtzero::vector_tile tile; mutable bool parsed = false; - mutable std::map<std::string, const protozero::data_view> layers; + mutable std::map<std::string, vtzero::layer> layers; }; } // namespace mbgl |