summaryrefslogtreecommitdiff
path: root/src/mbgl/tile/vector_tile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/tile/vector_tile.cpp')
-rw-r--r--src/mbgl/tile/vector_tile.cpp271
1 files changed, 1 insertions, 270 deletions
diff --git a/src/mbgl/tile/vector_tile.cpp b/src/mbgl/tile/vector_tile.cpp
index 6a3c51c05d..784b6cb1ab 100644
--- a/src/mbgl/tile/vector_tile.cpp
+++ b/src/mbgl/tile/vector_tile.cpp
@@ -1,10 +1,8 @@
#include <mbgl/tile/vector_tile.hpp>
+#include <mbgl/tile/vector_tile_data.hpp>
#include <mbgl/tile/tile_loader_impl.hpp>
-#include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/style/update_parameters.hpp>
-#include <protozero/pbf_reader.hpp>
-
#include <map>
#include <unordered_map>
#include <functional>
@@ -12,62 +10,6 @@
namespace mbgl {
-class VectorTileLayer;
-
-using pbf_iter_type = protozero::pbf_reader::const_uint32_iterator;
-using packed_iter_type = std::pair<pbf_iter_type,pbf_iter_type>;
-
-class VectorTileFeature : public GeometryTileFeature {
-public:
- VectorTileFeature(protozero::pbf_reader, const VectorTileLayer&);
-
- FeatureType getType() const override { return type; }
- optional<Value> getValue(const std::string&) const override;
- std::unordered_map<std::string,Value> getProperties() const override;
- optional<FeatureIdentifier> getID() const override;
- GeometryCollection getGeometries() const override;
-
-private:
- const VectorTileLayer& layer;
- optional<FeatureIdentifier> id;
- FeatureType type = FeatureType::Unknown;
- packed_iter_type tags_iter;
- packed_iter_type geometry_iter;
-};
-
-class VectorTileLayer : public GeometryTileLayer {
-public:
- VectorTileLayer(protozero::pbf_reader);
-
- std::size_t featureCount() const override { return features.size(); }
- util::ptr<const GeometryTileFeature> getFeature(std::size_t) const override;
- std::string getName() const override;
-
-private:
- friend class VectorTileData;
- friend class VectorTileFeature;
-
- std::string name;
- uint32_t version = 1;
- uint32_t extent = 4096;
- std::map<std::string, uint32_t> keysMap;
- std::vector<std::reference_wrapper<const std::string>> keys;
- std::vector<Value> values;
- std::vector<protozero::pbf_reader> features;
-};
-
-class VectorTileData : public GeometryTileData {
-public:
- VectorTileData(std::shared_ptr<const std::string> data);
-
- util::ptr<GeometryTileLayer> getLayer(const std::string&) const override;
-
-private:
- std::shared_ptr<const std::string> data;
- mutable bool parsed = false;
- mutable std::map<std::string, util::ptr<GeometryTileLayer>> layers;
-};
-
VectorTile::VectorTile(const OverscaledTileID& id_,
std::string sourceID_,
const style::UpdateParameters& parameters,
@@ -89,215 +31,4 @@ void VectorTile::setData(std::shared_ptr<const std::string> data_,
GeometryTile::setData(data_ ? std::make_unique<VectorTileData>(data_) : nullptr);
}
-Value parseValue(protozero::pbf_reader data) {
- while (data.next())
- {
- switch (data.tag()) {
- case 1: // string_value
- return data.get_string();
- case 2: // float_value
- return static_cast<double>(data.get_float());
- case 3: // double_value
- return data.get_double();
- case 4: // int_value
- return data.get_int64();
- case 5: // uint_value
- return data.get_uint64();
- case 6: // sint_value
- return data.get_sint64();
- case 7: // bool_value
- return data.get_bool();
- default:
- data.skip();
- break;
- }
- }
- return false;
-}
-
-VectorTileFeature::VectorTileFeature(protozero::pbf_reader feature_pbf, const VectorTileLayer& layer_)
- : layer(layer_) {
- while (feature_pbf.next()) {
- switch (feature_pbf.tag()) {
- case 1: // id
- id = { feature_pbf.get_uint64() };
- break;
- case 2: // tags
- tags_iter = feature_pbf.get_packed_uint32();
- break;
- case 3: // type
- type = static_cast<FeatureType>(feature_pbf.get_enum());
- break;
- case 4: // geometry
- geometry_iter = feature_pbf.get_packed_uint32();
- break;
- default:
- feature_pbf.skip();
- break;
- }
- }
-}
-
-optional<Value> VectorTileFeature::getValue(const std::string& key) const {
- auto keyIter = layer.keysMap.find(key);
- if (keyIter == layer.keysMap.end()) {
- return optional<Value>();
- }
-
- auto start_itr = tags_iter.first;
- const auto & end_itr = tags_iter.second;
- while (start_itr != end_itr) {
- uint32_t tag_key = static_cast<uint32_t>(*start_itr++);
-
- if (layer.keysMap.size() <= tag_key) {
- throw std::runtime_error("feature referenced out of range key");
- }
-
- if (start_itr == end_itr) {
- throw std::runtime_error("uneven number of feature tag ids");
- }
-
- uint32_t tag_val = static_cast<uint32_t>(*start_itr++);;
- if (layer.values.size() <= tag_val) {
- throw std::runtime_error("feature referenced out of range value");
- }
-
- if (tag_key == keyIter->second) {
- return layer.values[tag_val];
- }
- }
-
- return optional<Value>();
-}
-
-std::unordered_map<std::string,Value> VectorTileFeature::getProperties() const {
- std::unordered_map<std::string,Value> properties;
- auto start_itr = tags_iter.first;
- const auto & end_itr = tags_iter.second;
- while (start_itr != end_itr) {
- uint32_t tag_key = static_cast<uint32_t>(*start_itr++);
- if (start_itr == end_itr) {
- throw std::runtime_error("uneven number of feature tag ids");
- }
- uint32_t tag_val = static_cast<uint32_t>(*start_itr++);
- properties[layer.keys.at(tag_key)] = layer.values.at(tag_val);
- }
- return properties;
-}
-
-optional<FeatureIdentifier> VectorTileFeature::getID() const {
- return id;
-}
-
-GeometryCollection VectorTileFeature::getGeometries() const {
- uint8_t cmd = 1;
- uint32_t length = 0;
- int32_t x = 0;
- int32_t y = 0;
- const float scale = float(util::EXTENT) / layer.extent;
-
- GeometryCollection lines;
-
- lines.emplace_back();
- GeometryCoordinates* line = &lines.back();
-
- auto g_itr = geometry_iter;
- while (g_itr.first != g_itr.second) {
- if (length == 0) {
- uint32_t cmd_length = static_cast<uint32_t>(*g_itr.first++);
- cmd = cmd_length & 0x7;
- length = cmd_length >> 3;
- }
-
- --length;
-
- if (cmd == 1 || cmd == 2) {
- x += protozero::decode_zigzag32(static_cast<uint32_t>(*g_itr.first++));
- y += protozero::decode_zigzag32(static_cast<uint32_t>(*g_itr.first++));
-
- if (cmd == 1 && !line->empty()) { // moveTo
- lines.emplace_back();
- line = &lines.back();
- }
-
- line->emplace_back(::round(x * scale), ::round(y * scale));
-
- } else if (cmd == 7) { // closePolygon
- if (!line->empty()) {
- line->push_back((*line)[0]);
- }
-
- } else {
- throw std::runtime_error("unknown command");
- }
- }
-
- if (layer.version >= 2 || type != FeatureType::Polygon) {
- return lines;
- }
-
- return fixupPolygons(lines);
-}
-
-VectorTileData::VectorTileData(std::shared_ptr<const std::string> data_)
- : data(std::move(data_)) {
-}
-
-util::ptr<GeometryTileLayer> VectorTileData::getLayer(const std::string& name) const {
- if (!parsed) {
- parsed = true;
- protozero::pbf_reader tile_pbf(*data);
- while (tile_pbf.next(3)) {
- util::ptr<VectorTileLayer> layer = std::make_shared<VectorTileLayer>(tile_pbf.get_message());
- layers.emplace(layer->name, layer);
- }
- }
-
- auto layer_it = layers.find(name);
- if (layer_it != layers.end()) {
- return layer_it->second;
- }
-
- return nullptr;
-}
-
-VectorTileLayer::VectorTileLayer(protozero::pbf_reader layer_pbf) {
- while (layer_pbf.next()) {
- switch (layer_pbf.tag()) {
- case 1: // name
- name = layer_pbf.get_string();
- break;
- case 2: // feature
- features.push_back(layer_pbf.get_message());
- break;
- case 3: // keys
- {
- auto iter = keysMap.emplace(layer_pbf.get_string(), keysMap.size());
- keys.emplace_back(std::reference_wrapper<const std::string>(iter.first->first));
- }
- break;
- case 4: // values
- values.emplace_back(parseValue(layer_pbf.get_message()));
- break;
- case 5: // extent
- extent = layer_pbf.get_uint32();
- break;
- case 15: // version
- version = layer_pbf.get_uint32();
- break;
- default:
- layer_pbf.skip();
- break;
- }
- }
-}
-
-util::ptr<const GeometryTileFeature> VectorTileLayer::getFeature(std::size_t i) const {
- return std::make_shared<VectorTileFeature>(features.at(i), *this);
-}
-
-std::string VectorTileLayer::getName() const {
- return name;
-}
-
} // namespace mbgl