Don't copy VT keys / values into each feature
Instead, maintain a key index ⇢ value index map and look up the value in getValue().
This commit is contained in:
@@ -29,7 +29,8 @@ Value parseValue(pbf data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
VectorTileFeature::VectorTileFeature(pbf feature_pbf, const VectorTileLayer& layer) {
|
||||
VectorTileFeature::VectorTileFeature(pbf feature_pbf, const VectorTileLayer& layer_)
|
||||
: layer(layer_) {
|
||||
while (feature_pbf.next()) {
|
||||
if (feature_pbf.tag == 1) { // id
|
||||
id = feature_pbf.varint<uint64_t>();
|
||||
@@ -43,16 +44,16 @@ VectorTileFeature::VectorTileFeature(pbf feature_pbf, const VectorTileLayer& lay
|
||||
throw std::runtime_error("feature referenced out of range key");
|
||||
}
|
||||
|
||||
if (tags) {
|
||||
uint32_t tag_val = tags.varint();
|
||||
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]);
|
||||
} else {
|
||||
if (!tags) {
|
||||
throw std::runtime_error("uneven number of feature tag ids");
|
||||
}
|
||||
|
||||
uint32_t tag_val = tags.varint();
|
||||
if (layer.values.size() <= tag_val) {
|
||||
throw std::runtime_error("feature referenced out of range value");
|
||||
}
|
||||
|
||||
properties.emplace(tag_key, tag_val);
|
||||
}
|
||||
} else if (feature_pbf.tag == 3) { // type
|
||||
type = (FeatureType)feature_pbf.varint();
|
||||
@@ -65,11 +66,15 @@ VectorTileFeature::VectorTileFeature(pbf feature_pbf, const VectorTileLayer& lay
|
||||
}
|
||||
|
||||
mapbox::util::optional<Value> VectorTileFeature::getValue(const std::string& key) const {
|
||||
auto it = properties.find(key);
|
||||
if (it != properties.end()) {
|
||||
return it->second;
|
||||
auto keyIter = layer.keys.find(key);
|
||||
if (keyIter == layer.keys.end()) {
|
||||
return mapbox::util::optional<Value>();
|
||||
}
|
||||
return mapbox::util::optional<Value>();
|
||||
auto propIter = properties.find(keyIter->second);
|
||||
if (propIter == properties.end()) {
|
||||
return mapbox::util::optional<Value>();
|
||||
}
|
||||
return layer.values[propIter->second];
|
||||
}
|
||||
|
||||
GeometryCollection VectorTileFeature::getGeometries() const {
|
||||
@@ -143,7 +148,7 @@ VectorTileLayer::VectorTileLayer(pbf layer_pbf) {
|
||||
} 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());
|
||||
keys.emplace(layer_pbf.string(), keys.size());
|
||||
} else if (layer_pbf.tag == 4) { // values
|
||||
values.emplace_back(std::move(parseValue(layer_pbf.message())));
|
||||
} else if (layer_pbf.tag == 5) { // extent
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <mbgl/map/geometry_tile.hpp>
|
||||
#include <mbgl/util/pbf.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -19,9 +19,10 @@ public:
|
||||
GeometryCollection getGeometries() const override;
|
||||
|
||||
private:
|
||||
const VectorTileLayer& layer;
|
||||
uint64_t id = 0;
|
||||
FeatureType type = FeatureType::Unknown;
|
||||
std::map<std::string, Value> properties;
|
||||
std::unordered_map<uint32_t, uint32_t> properties;
|
||||
pbf geometry_pbf;
|
||||
};
|
||||
|
||||
@@ -38,7 +39,7 @@ private:
|
||||
|
||||
std::string name;
|
||||
uint32_t extent = 4096;
|
||||
std::vector<std::string> keys;
|
||||
std::unordered_map<std::string, uint32_t> keys;
|
||||
std::vector<Value> values;
|
||||
std::vector<pbf> features;
|
||||
};
|
||||
@@ -50,7 +51,7 @@ public:
|
||||
util::ptr<const GeometryTileLayer> getLayer(const std::string&) const override;
|
||||
|
||||
private:
|
||||
std::map<std::string, util::ptr<const GeometryTileLayer>> layers;
|
||||
std::unordered_map<std::string, util::ptr<const GeometryTileLayer>> layers;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user