diff options
author | Anand Thakker <anandthakker@users.noreply.github.com> | 2017-02-28 19:54:24 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-28 19:54:24 -0800 |
commit | f901e776b3e63aaaa6bc0cc4476624bf84127fe6 (patch) | |
tree | 3e311971d57109c64e5ace45c111fb5909e7fb7b /src/mbgl/tile | |
parent | c3ed1f51ca677c8c2045320fe13ec881cbd94772 (diff) | |
download | qtlocation-mapboxgl-f901e776b3e63aaaa6bc0cc4476624bf84127fe6.tar.gz |
[core] Implement data-driven styling for {text,icon}-{color,opacity,halo-color,halo-blur,halo-width} (#7939)
* Add symbol dds attributes and adapt style code generation
* Update to mapbox-gl-js/master
* Refactor SymbolFeature as a subclass of GeometryTileFeature
Prepares for enabling DDS on symbol paint properties by allowing the
SymbolFeatures, which we keep around after constructing SymbolLayout,
to be used in evaluating data-driven paint properties later in the
layout process.
* Draft approach for splitting icon/text paint properties
The `Program` types are set up to bind GL attributes to each of the
data-driven paint properties specified in the `PaintProperties` type
provided. Since `SymbolPaintProperties` specifies both `Text*` and
`Icon*` properties, the symbolIcon, symbolIconSDF, and symbolGlyph
programs each attempt to bind roughly double the number of attributes
that they actually need.
This change addresses this by:
- Adding the more specific `IconPaintProperties` and `TextPaintProperties` types, which are subsets of the full `SymbolPaintProperties`.
- The symbol layer continues to use its `SymbolPaintProperties paint` member to track layer property state, but it provides helpers that construct objects of each the specific `{Icon,Text}PaintProperties::Evaluated` type, for use by the painter.
- The three symbol programs instantiate `Program<>` using the appropriate `{Icon,Text}PaintProperties` type.
* check in generated style code
* Populate paint buffers for symbol DDS properties
* Address first round of review comments
* Refactor VectorTile{Layer,Feature} to explicitly share data
* Update submodule
Diffstat (limited to 'src/mbgl/tile')
-rw-r--r-- | src/mbgl/tile/vector_tile.cpp | 70 |
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 { |