diff options
author | Molly Lloyd <molly@mapbox.com> | 2018-06-14 14:35:39 -0700 |
---|---|---|
committer | Molly Lloyd <mollymerp@users.noreply.github.com> | 2018-08-31 13:08:47 -0700 |
commit | 4a5dc37245d23805d13865f5ef9c5f26e539a9ca (patch) | |
tree | de77bfeff6f7afbe02210c9189bf72da59293083 /src/mbgl/layout/pattern_layout.hpp | |
parent | ec62e321531b1a836074056e86de8e20018280fb (diff) | |
download | qtlocation-mapboxgl-4a5dc37245d23805d13865f5ef9c5f26e539a9ca.tar.gz |
[core] Implement CrossFadedDataDrivenProperty to add support for feature expressions in `*-pattern` properties
Diffstat (limited to 'src/mbgl/layout/pattern_layout.hpp')
-rw-r--r-- | src/mbgl/layout/pattern_layout.hpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/src/mbgl/layout/pattern_layout.hpp b/src/mbgl/layout/pattern_layout.hpp new file mode 100644 index 0000000000..9f4964ca6b --- /dev/null +++ b/src/mbgl/layout/pattern_layout.hpp @@ -0,0 +1,128 @@ +#pragma once +#include <mbgl/renderer/bucket_parameters.hpp> +#include <mbgl/geometry/feature_index.hpp> +#include <mbgl/renderer/render_layer.hpp> + +namespace mbgl { + +class PatternDependency { +public: + std::string min; + std::string mid; + std::string max; +}; + +using PatternLayerMap = std::unordered_map<std::string, PatternDependency>; + +class PatternFeature { +public: + const uint32_t i; + std::unique_ptr<GeometryTileFeature> feature; + PatternLayerMap patterns; +}; + +template <class B> +class PatternLayout { +public: + PatternLayout(const BucketParameters& parameters, + const std::vector<const RenderLayer*>& layers, + std::unique_ptr<GeometryTileLayer> sourceLayer_, + ImageDependencies& patternDependencies) + : bucketLeaderID(layers.at(0)->getID()), + sourceLayer(std::move(sourceLayer_)), + zoom(parameters.tileID.overscaledZ), + overscaling(parameters.tileID.overscaleFactor()), + hasPattern(false) { + + using PatternLayer = typename B::RenderLayerType; + const auto renderLayer = layers.at(0)->as<PatternLayer>(); + const typename PatternLayer::StyleLayerImpl& leader = renderLayer->impl(); + layout = leader.layout.evaluate(PropertyEvaluationParameters(zoom)); + sourceLayerID = leader.sourceLayer; + groupID = renderLayer->getID(); + + for (const auto& layer : layers) { + const typename B::PossiblyEvaluatedPaintProperties evaluatedProps = layer->as<PatternLayer>()->paintProperties(); + layerPaintProperties.emplace(layer->getID(), std::move(evaluatedProps)); + const auto patternProperty = evaluatedProps.template get<typename PatternLayer::PatternProperty>(); + const auto constantPattern = patternProperty.constantOr(Faded<std::basic_string<char> >{ "", ""}); + // determine if layer group has any layers that use *-pattern property and add + // constant pattern dependencies. + if (!patternProperty.isConstant()) { + hasPattern = true; + } else if (!constantPattern.to.empty()){ + hasPattern = true; + patternDependencies.emplace(constantPattern.to, ImageType::Pattern); + patternDependencies.emplace(constantPattern.from, ImageType::Pattern); + } + } + + const size_t featureCount = sourceLayer->featureCount(); + for (size_t i = 0; i < featureCount; ++i) { + auto feature = sourceLayer->getFeature(i); + if (!leader.filter(style::expression::EvaluationContext { this->zoom, feature.get() })) + continue; + + std::unordered_map<std::string, PatternDependency> patternDependencyMap; + if (hasPattern) { + for (const auto& layer : layers) { + const auto it = layerPaintProperties.find(layer->getID()); + if (it != layerPaintProperties.end()) { + const auto paint = it->second; + const auto patternProperty = paint.template get<typename PatternLayer::PatternProperty>(); + if (!patternProperty.isConstant()) { + // For layers with non-data-constant pattern properties, evaluate their expression and add + // the patterns to the dependency vector + const auto min = patternProperty.evaluate(*feature, zoom - 1, PatternLayer::PatternProperty::defaultValue()); + const auto mid = patternProperty.evaluate(*feature, zoom, PatternLayer::PatternProperty::defaultValue()); + const auto max = patternProperty.evaluate(*feature, zoom + 1, PatternLayer::PatternProperty::defaultValue()); + + patternDependencies.emplace(min.to, ImageType::Pattern); + patternDependencies.emplace(mid.to, ImageType::Pattern); + patternDependencies.emplace(max.to, ImageType::Pattern); + patternDependencyMap.emplace(layer->getID(), PatternDependency {min.to, mid.to, max.to}); + + } + } + } + } + features.push_back({static_cast<uint32_t>(i), std::move(feature), patternDependencyMap}); + } + }; + + bool pattern() { + return hasPattern; + } + + std::unique_ptr<B> createBucket(const ImagePositions& patternPositions, std::unique_ptr<FeatureIndex>& featureIndex) { + auto bucket = std::make_unique<B>(layout, layerPaintProperties, zoom, overscaling); + for (auto & patternFeature : features) { + const auto i = patternFeature.i; + std::unique_ptr<GeometryTileFeature> feature = std::move(patternFeature.feature); + PatternLayerMap patterns = patternFeature.patterns; + GeometryCollection geometries = feature->getGeometries(); + + bucket->addFeature(*feature, geometries, patternPositions, patterns); + featureIndex->insert(geometries, i, sourceLayerID, groupID); + } + return bucket; + }; + + std::map<std::string, typename B::PossiblyEvaluatedPaintProperties> layerPaintProperties; + const std::string bucketLeaderID; + + +private: + const std::unique_ptr<GeometryTileLayer> sourceLayer; + std::vector<PatternFeature> features; + typename B::PossiblyEvaluatedLayoutProperties layout; + + const float zoom; + const uint32_t overscaling; + std::string sourceLayerID; + std::string groupID; + bool hasPattern; +}; + +} // namespace mbgl + |