#pragma once #include #include #include #include #include namespace mbgl { class PatternDependency { public: std::string min; std::string mid; std::string max; }; using PatternLayerMap = std::map; class PatternFeature { public: const uint32_t i; std::unique_ptr feature; PatternLayerMap patterns; }; template ::PossiblyEvaluated> class PatternLayout : public Layout { public: PatternLayout(const BucketParameters& parameters, const std::vector>& group, std::unique_ptr sourceLayer_, ImageDependencies& patternDependencies) : sourceLayer(std::move(sourceLayer_)), zoom(parameters.tileID.overscaledZ), overscaling(parameters.tileID.overscaleFactor()), hasPattern(false) { assert(!group.empty()); auto leaderLayerProperties = staticImmutableCast(group.front()); layout = leaderLayerProperties->layerImpl().layout.evaluate(PropertyEvaluationParameters(zoom)); sourceLayerID = leaderLayerProperties->layerImpl().sourceLayer; bucketLeaderID = leaderLayerProperties->layerImpl().id; for (const auto& layerProperties : group) { const std::string& layerId = layerProperties->baseImpl->id; const auto& evaluated = style::getEvaluated(layerProperties); const auto patternProperty = evaluated.template get(); const auto constantPattern = patternProperty.constantOr(Faded >{ "", ""}); // 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); } layerPropertiesMap.emplace(layerId, layerProperties); } const size_t featureCount = sourceLayer->featureCount(); for (size_t i = 0; i < featureCount; ++i) { auto feature = sourceLayer->getFeature(i); if (!leaderLayerProperties->layerImpl().filter(style::expression::EvaluationContext { this->zoom, feature.get() })) continue; PatternLayerMap patternDependencyMap; if (hasPattern) { for (const auto& layerProperties : group) { const std::string& layerId = layerProperties->baseImpl->id; const auto it = layerPropertiesMap.find(layerId); if (it != layerPropertiesMap.end()) { const auto paint = static_cast(*it->second).evaluated; const auto patternProperty = paint.template get(); 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, PatternPropertyType::defaultValue()); const auto mid = patternProperty.evaluate(*feature, zoom, PatternPropertyType::defaultValue()); const auto max = patternProperty.evaluate(*feature, zoom + 1, PatternPropertyType::defaultValue()); patternDependencies.emplace(min.to, ImageType::Pattern); patternDependencies.emplace(mid.to, ImageType::Pattern); patternDependencies.emplace(max.to, ImageType::Pattern); patternDependencyMap.emplace(layerId, PatternDependency {min.to, mid.to, max.to}); } } } } features.push_back({static_cast(i), std::move(feature), patternDependencyMap}); } }; ~PatternLayout() final = default; bool hasDependencies() const override { return hasPattern; } void createBucket(const ImagePositions& patternPositions, std::unique_ptr& featureIndex, std::unordered_map& renderData, const bool, const bool) override { auto bucket = std::make_shared(layout, layerPropertiesMap, zoom, overscaling); for (auto & patternFeature : features) { const auto i = patternFeature.i; std::unique_ptr feature = std::move(patternFeature.feature); const PatternLayerMap& patterns = patternFeature.patterns; GeometryCollection geometries = feature->getGeometries(); bucket->addFeature(*feature, geometries, patternPositions, patterns); featureIndex->insert(geometries, i, sourceLayerID, bucketLeaderID); } if (bucket->hasData()) { for (const auto& pair : layerPropertiesMap) { renderData.emplace(pair.first, LayerRenderData {bucket, pair.second}); } } }; private: std::map> layerPropertiesMap; std::string bucketLeaderID; const std::unique_ptr sourceLayer; std::vector features; PossiblyEvaluatedLayoutPropertiesType layout; const float zoom; const uint32_t overscaling; std::string sourceLayerID; bool hasPattern; }; } // namespace mbgl