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.cpp70
1 files changed, 43 insertions, 27 deletions
diff --git a/src/mbgl/tile/vector_tile.cpp b/src/mbgl/tile/vector_tile.cpp
index a195885415..68f48e81fd 100644
--- a/src/mbgl/tile/vector_tile.cpp
+++ b/src/mbgl/tile/vector_tile.cpp
@@ -15,9 +15,23 @@ class VectorTileLayer;
using packed_iter_type = protozero::iterator_range<protozero::pbf_reader::const_uint32_iterator>;
+struct VectorTileLayerData {
+ VectorTileLayerData(std::shared_ptr<const std::string>);
+
+ // Hold a reference to the underlying pbf data that backs the lazily-built
+ // components of the owning VectorTileLayer and VectorTileFeature objects
+ std::shared_ptr<const std::string> data;
+
+ uint32_t version = 1;
+ uint32_t extent = 4096;
+ std::unordered_map<std::string, uint32_t> keysMap;
+ std::vector<std::reference_wrapper<const std::string>> keys;
+ std::vector<Value> values;
+};
+
class VectorTileFeature : public GeometryTileFeature {
public:
- VectorTileFeature(protozero::pbf_reader, const VectorTileLayer&);
+ VectorTileFeature(protozero::pbf_reader, std::shared_ptr<VectorTileLayerData> layerData);
FeatureType getType() const override { return type; }
optional<Value> getValue(const std::string&) const override;
@@ -26,16 +40,16 @@ public:
GeometryCollection getGeometries() const override;
private:
- const VectorTileLayer& layer;
+ std::shared_ptr<VectorTileLayerData> layerData;
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);
+ VectorTileLayer(protozero::pbf_reader, std::shared_ptr<const std::string>);
std::size_t featureCount() const override { return features.size(); }
std::unique_ptr<GeometryTileFeature> getFeature(std::size_t) const override;
@@ -46,12 +60,8 @@ private:
friend class VectorTileFeature;
std::string name;
- uint32_t version = 1;
- uint32_t extent = 4096;
- std::unordered_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;
+ std::shared_ptr<VectorTileLayerData> data;
};
class VectorTileData : public GeometryTileData {
@@ -117,8 +127,8 @@ Value parseValue(protozero::pbf_reader data) {
return false;
}
-VectorTileFeature::VectorTileFeature(protozero::pbf_reader feature_pbf, const VectorTileLayer& layer_)
- : layer(layer_) {
+VectorTileFeature::VectorTileFeature(protozero::pbf_reader feature_pbf, std::shared_ptr<VectorTileLayerData> layerData_)
+ : layerData(std::move(layerData_)) {
while (feature_pbf.next()) {
switch (feature_pbf.tag()) {
case 1: // id
@@ -141,8 +151,8 @@ VectorTileFeature::VectorTileFeature(protozero::pbf_reader feature_pbf, const Ve
}
optional<Value> VectorTileFeature::getValue(const std::string& key) const {
- auto keyIter = layer.keysMap.find(key);
- if (keyIter == layer.keysMap.end()) {
+ auto keyIter = layerData->keysMap.find(key);
+ if (keyIter == layerData->keysMap.end()) {
return optional<Value>();
}
@@ -151,7 +161,7 @@ optional<Value> VectorTileFeature::getValue(const std::string& key) const {
while (start_itr != end_itr) {
uint32_t tag_key = static_cast<uint32_t>(*start_itr++);
- if (layer.keysMap.size() <= tag_key) {
+ if (layerData->keysMap.size() <= tag_key) {
throw std::runtime_error("feature referenced out of range key");
}
@@ -160,12 +170,12 @@ optional<Value> VectorTileFeature::getValue(const std::string& key) const {
}
uint32_t tag_val = static_cast<uint32_t>(*start_itr++);;
- if (layer.values.size() <= tag_val) {
+ if (layerData->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 layerData->values[tag_val];
}
}
@@ -182,7 +192,7 @@ std::unordered_map<std::string,Value> VectorTileFeature::getProperties() const {
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);
+ properties[layerData->keys.at(tag_key)] = layerData->values.at(tag_val);
}
return properties;
}
@@ -196,7 +206,7 @@ GeometryCollection VectorTileFeature::getGeometries() const {
uint32_t length = 0;
int32_t x = 0;
int32_t y = 0;
- const float scale = float(util::EXTENT) / layer.extent;
+ const float scale = float(util::EXTENT) / layerData->extent;
GeometryCollection lines;
@@ -234,7 +244,7 @@ GeometryCollection VectorTileFeature::getGeometries() const {
}
}
- if (layer.version >= 2 || type != FeatureType::Polygon) {
+ if (layerData->version >= 2 || type != FeatureType::Polygon) {
return lines;
}
@@ -250,7 +260,7 @@ const GeometryTileLayer* VectorTileData::getLayer(const std::string& name) const
parsed = true;
protozero::pbf_reader tile_pbf(*data);
while (tile_pbf.next(3)) {
- VectorTileLayer layer(tile_pbf.get_message());
+ VectorTileLayer layer(tile_pbf.get_message(), data);
layers.emplace(layer.name, std::move(layer));
}
}
@@ -262,7 +272,13 @@ const GeometryTileLayer* VectorTileData::getLayer(const std::string& name) const
return nullptr;
}
-VectorTileLayer::VectorTileLayer(protozero::pbf_reader layer_pbf) {
+VectorTileLayerData::VectorTileLayerData(std::shared_ptr<const std::string> pbfData) :
+ data(std::move(pbfData))
+{}
+
+VectorTileLayer::VectorTileLayer(protozero::pbf_reader layer_pbf, std::shared_ptr<const std::string> pbfData)
+ : data(std::make_shared<VectorTileLayerData>(std::move(pbfData)))
+{
while (layer_pbf.next()) {
switch (layer_pbf.tag()) {
case 1: // name
@@ -273,18 +289,18 @@ VectorTileLayer::VectorTileLayer(protozero::pbf_reader layer_pbf) {
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));
+ auto iter = data->keysMap.emplace(layer_pbf.get_string(), data->keysMap.size());
+ data->keys.emplace_back(std::reference_wrapper<const std::string>(iter.first->first));
}
break;
case 4: // values
- values.emplace_back(parseValue(layer_pbf.get_message()));
+ data->values.emplace_back(parseValue(layer_pbf.get_message()));
break;
case 5: // extent
- extent = layer_pbf.get_uint32();
+ data->extent = layer_pbf.get_uint32();
break;
case 15: // version
- version = layer_pbf.get_uint32();
+ data->version = layer_pbf.get_uint32();
break;
default:
layer_pbf.skip();
@@ -294,7 +310,7 @@ VectorTileLayer::VectorTileLayer(protozero::pbf_reader layer_pbf) {
}
std::unique_ptr<GeometryTileFeature> VectorTileLayer::getFeature(std::size_t i) const {
- return std::make_unique<VectorTileFeature>(features.at(i), *this);
+ return std::make_unique<VectorTileFeature>(features.at(i), data);
}
std::string VectorTileLayer::getName() const {