summaryrefslogtreecommitdiff
path: root/src/mbgl/style
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/style')
-rw-r--r--src/mbgl/style/bucket_parameters.cpp14
-rw-r--r--src/mbgl/style/bucket_parameters.hpp21
-rw-r--r--src/mbgl/style/conversion/stringify.hpp148
-rw-r--r--src/mbgl/style/cross_faded_property_evaluator.cpp19
-rw-r--r--src/mbgl/style/cross_faded_property_evaluator.hpp2
-rw-r--r--src/mbgl/style/data_driven_property_evaluator.hpp42
-rw-r--r--src/mbgl/style/function.cpp81
-rw-r--r--src/mbgl/style/function/categorical_stops.cpp35
-rw-r--r--src/mbgl/style/function/identity_stops.cpp43
-rw-r--r--src/mbgl/style/layer_impl.hpp2
-rw-r--r--src/mbgl/style/layer_observer.hpp1
-rw-r--r--src/mbgl/style/layers/background_layer_impl.cpp3
-rw-r--r--src/mbgl/style/layers/background_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/background_layer_properties.hpp1
-rw-r--r--src/mbgl/style/layers/circle_layer.cpp84
-rw-r--r--src/mbgl/style/layers/circle_layer_impl.cpp22
-rw-r--r--src/mbgl/style/layers/circle_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/circle_layer_properties.hpp15
-rw-r--r--src/mbgl/style/layers/custom_layer_impl.cpp3
-rw-r--r--src/mbgl/style/layers/custom_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/fill_extrusion_layer.cpp36
-rw-r--r--src/mbgl/style/layers/fill_extrusion_layer_impl.cpp2
-rw-r--r--src/mbgl/style/layers/fill_extrusion_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/fill_extrusion_layer_properties.hpp7
-rw-r--r--src/mbgl/style/layers/fill_layer.cpp36
-rw-r--r--src/mbgl/style/layers/fill_layer_impl.cpp17
-rw-r--r--src/mbgl/style/layers/fill_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/fill_layer_properties.hpp7
-rw-r--r--src/mbgl/style/layers/layer.cpp.ejs20
-rw-r--r--src/mbgl/style/layers/layer_properties.hpp.ejs11
-rw-r--r--src/mbgl/style/layers/line_layer.cpp60
-rw-r--r--src/mbgl/style/layers/line_layer_impl.cpp35
-rw-r--r--src/mbgl/style/layers/line_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/line_layer_properties.hpp11
-rw-r--r--src/mbgl/style/layers/raster_layer_impl.cpp3
-rw-r--r--src/mbgl/style/layers/raster_layer_impl.hpp2
-rw-r--r--src/mbgl/style/layers/raster_layer_properties.hpp1
-rw-r--r--src/mbgl/style/layers/symbol_layer.cpp12
-rw-r--r--src/mbgl/style/layers/symbol_layer_impl.cpp49
-rw-r--r--src/mbgl/style/layers/symbol_layer_impl.hpp6
-rw-r--r--src/mbgl/style/layers/symbol_layer_properties.hpp5
-rw-r--r--src/mbgl/style/layout_property.hpp13
-rw-r--r--src/mbgl/style/paint_property.hpp86
-rw-r--r--src/mbgl/style/paint_property_binder.hpp283
-rw-r--r--src/mbgl/style/parser.cpp12
-rw-r--r--src/mbgl/style/possibly_evaluated_property_value.hpp74
-rw-r--r--src/mbgl/style/property_evaluator.hpp2
-rw-r--r--src/mbgl/style/style.cpp5
-rw-r--r--src/mbgl/style/style.hpp1
49 files changed, 957 insertions, 387 deletions
diff --git a/src/mbgl/style/bucket_parameters.cpp b/src/mbgl/style/bucket_parameters.cpp
index e641120c5e..2b02ac4a4a 100644
--- a/src/mbgl/style/bucket_parameters.cpp
+++ b/src/mbgl/style/bucket_parameters.cpp
@@ -1,21 +1,7 @@
#include <mbgl/style/bucket_parameters.hpp>
-#include <mbgl/style/filter_evaluator.hpp>
-#include <mbgl/tile/geometry_tile_data.hpp>
namespace mbgl {
namespace style {
-void BucketParameters::eachFilteredFeature(const Filter& filter,
- const GeometryTileLayer& layer,
- std::function<void (const GeometryTileFeature&, std::size_t index, const std::string& layerName)> function) {
- auto name = layer.getName();
- for (std::size_t i = 0; !cancelled() && i < layer.featureCount(); i++) {
- auto feature = layer.getFeature(i);
- if (!filter(feature->getType(), feature->getID(), [&] (const auto& key) { return feature->getValue(key); }))
- continue;
- function(*feature, i, name);
- }
-}
-
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/bucket_parameters.hpp b/src/mbgl/style/bucket_parameters.hpp
index d5e05c5dd2..d0edbcac30 100644
--- a/src/mbgl/style/bucket_parameters.hpp
+++ b/src/mbgl/style/bucket_parameters.hpp
@@ -2,33 +2,14 @@
#include <mbgl/map/mode.hpp>
#include <mbgl/tile/tile_id.hpp>
-#include <mbgl/style/filter.hpp>
-
-#include <atomic>
-#include <functional>
namespace mbgl {
-
-class GeometryTileLayer;
-class GeometryTileFeature;
-class FeatureIndex;
-
namespace style {
class BucketParameters {
public:
- const OverscaledTileID& tileID;
- const std::atomic<bool>& obsolete;
- FeatureIndex& featureIndex;
+ const OverscaledTileID tileID;
const MapMode mode;
-
- bool cancelled() const {
- return obsolete;
- }
-
- void eachFilteredFeature(const Filter&,
- const GeometryTileLayer&,
- std::function<void (const GeometryTileFeature&, std::size_t index, const std::string& layerName)>);
};
} // namespace style
diff --git a/src/mbgl/style/conversion/stringify.hpp b/src/mbgl/style/conversion/stringify.hpp
index d06b2f2814..71755bd9d6 100644
--- a/src/mbgl/style/conversion/stringify.hpp
+++ b/src/mbgl/style/conversion/stringify.hpp
@@ -214,20 +214,131 @@ void stringify(Writer& writer, const Undefined&) {
writer.Null();
}
-template <class Writer, class T>
-void stringify(Writer& writer, const Function<T>& f) {
- writer.StartObject();
- writer.Key("base");
- writer.Double(f.getBase());
- writer.Key("stops");
- writer.StartArray();
- for (const auto& stop : f.getStops()) {
+template <class Writer>
+void stringify(Writer& writer, const CategoricalValue& v) {
+ CategoricalValue::visit(v, [&] (const auto& v_) { stringify(writer, v_); });
+}
+
+template <class Writer>
+class StringifyStops {
+public:
+ Writer& writer;
+
+ template <class T>
+ void operator()(const ExponentialStops<T>& f) {
+ writer.Key("type");
+ writer.String("exponential");
+ writer.Key("base");
+ writer.Double(f.base);
+ writer.Key("stops");
+ stringifyStops(f.stops);
+ }
+
+ template <class T>
+ void operator()(const IntervalStops<T>& f) {
+ writer.Key("type");
+ writer.String("interval");
+ writer.Key("stops");
+ stringifyStops(f.stops);
+ }
+
+ template <class T>
+ void operator()(const CategoricalStops<T>& f) {
+ writer.Key("type");
+ writer.String("categorical");
+ writer.Key("stops");
+ stringifyStops(f.stops);
+ }
+
+ template <class T>
+ void operator()(const IdentityStops<T>&) {
+ writer.Key("type");
+ writer.String("identity");
+ }
+
+ template <class T>
+ void operator()(const std::map<float, ExponentialStops<T>>& f) {
+ writer.Key("type");
+ writer.String("exponential");
+ if (!f.empty()) {
+ writer.Key("base");
+ writer.Double(f.begin()->second.base);
+ }
+ writer.Key("stops");
+ stringifyCompositeStops(f);
+ }
+
+ template <class T>
+ void operator()(const std::map<float, IntervalStops<T>>& f) {
+ writer.Key("type");
+ writer.String("interval");
+ writer.Key("stops");
+ stringifyCompositeStops(f);
+ }
+
+ template <class T>
+ void operator()(const std::map<float, CategoricalStops<T>>& f) {
+ writer.Key("type");
+ writer.String("categorical");
+ writer.Key("stops");
+ stringifyCompositeStops(f);
+ }
+
+private:
+ template <class K, class V>
+ void stringifyStops(const std::map<K, V>& stops) {
writer.StartArray();
- writer.Double(stop.first);
- stringify(writer, stop.second);
+ for (const auto& stop : stops) {
+ writer.StartArray();
+ stringify(writer, stop.first);
+ stringify(writer, stop.second);
+ writer.EndArray();
+ }
writer.EndArray();
}
- writer.EndArray();
+
+ template <class InnerStops>
+ void stringifyCompositeStops(const std::map<float, InnerStops>& stops) {
+ writer.StartArray();
+ for (const auto& outer : stops) {
+ for (const auto& inner : outer.second.stops) {
+ writer.StartArray();
+ writer.StartObject();
+ writer.Key("zoom");
+ writer.Double(outer.first);
+ writer.Key("value");
+ stringify(writer, inner.first);
+ writer.EndObject();
+ stringify(writer, inner.second);
+ writer.EndArray();
+ }
+ }
+ writer.EndArray();
+ }
+};
+
+template <class Writer, class T>
+void stringify(Writer& writer, const CameraFunction<T>& f) {
+ writer.StartObject();
+ CameraFunction<T>::Stops::visit(f.stops, StringifyStops<Writer> { writer });
+ writer.EndObject();
+}
+
+template <class Writer, class T>
+void stringify(Writer& writer, const SourceFunction<T>& f) {
+ writer.StartObject();
+ writer.Key("property");
+ writer.String(f.property);
+ SourceFunction<T>::Stops::visit(f.stops, StringifyStops<Writer> { writer });
+ writer.EndObject();
+}
+
+template <class Writer, class T>
+void stringify(Writer& writer, const CompositeFunction<T>& f) {
+ writer.StartObject();
+ writer.Key("property");
+ writer.String(f.property);
+ CompositeFunction<T>::Stops::visit(f.stops, StringifyStops<Writer> { writer });
writer.EndObject();
}
@@ -238,7 +349,20 @@ void stringify(Writer& writer, const PropertyValue<T>& v) {
template <class Property, class Writer, class T>
void stringify(Writer& writer, const PropertyValue<T>& value) {
- if (value) {
+ if (!value.isUndefined()) {
+ writer.Key(Property::key);
+ stringify(writer, value);
+ }
+}
+
+template <class Writer, class T>
+void stringify(Writer& writer, const DataDrivenPropertyValue<T>& v) {
+ v.evaluate([&] (const auto& v_) { stringify(writer, v_); });
+}
+
+template <class Property, class Writer, class T>
+void stringify(Writer& writer, const DataDrivenPropertyValue<T>& value) {
+ if (!value.isUndefined()) {
writer.Key(Property::key);
stringify(writer, value);
}
diff --git a/src/mbgl/style/cross_faded_property_evaluator.cpp b/src/mbgl/style/cross_faded_property_evaluator.cpp
index 4de939576e..796ca00bbf 100644
--- a/src/mbgl/style/cross_faded_property_evaluator.cpp
+++ b/src/mbgl/style/cross_faded_property_evaluator.cpp
@@ -17,21 +17,10 @@ Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const T& constant) const {
}
template <typename T>
-T getBiggestStopLessThan(const Function<T>& function, float z) {
- const auto& stops = function.getStops();
- for (uint32_t i = 0; i < stops.size(); i++) {
- if (stops[i].first > z) {
- return stops[i == 0 ? i : i - 1].second;
- }
- }
- return stops.at(stops.size() - 1).second;
-}
-
-template <typename T>
-Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const Function<T>& function) const {
- return calculate(getBiggestStopLessThan(function, parameters.z - 1.0f),
- getBiggestStopLessThan(function, parameters.z),
- getBiggestStopLessThan(function, parameters.z + 1.0f));
+Faded<T> CrossFadedPropertyEvaluator<T>::operator()(const CameraFunction<T>& function) const {
+ return calculate(function.evaluate(parameters.z - 1.0f),
+ function.evaluate(parameters.z),
+ function.evaluate(parameters.z + 1.0f));
}
template <typename T>
diff --git a/src/mbgl/style/cross_faded_property_evaluator.hpp b/src/mbgl/style/cross_faded_property_evaluator.hpp
index 70c8c0c978..c5642f5cfb 100644
--- a/src/mbgl/style/cross_faded_property_evaluator.hpp
+++ b/src/mbgl/style/cross_faded_property_evaluator.hpp
@@ -28,7 +28,7 @@ public:
Faded<T> operator()(const Undefined&) const;
Faded<T> operator()(const T& constant) const;
- Faded<T> operator()(const Function<T>&) const;
+ Faded<T> operator()(const CameraFunction<T>&) const;
private:
Faded<T> calculate(const T& min, const T& mid, const T& max) const;
diff --git a/src/mbgl/style/data_driven_property_evaluator.hpp b/src/mbgl/style/data_driven_property_evaluator.hpp
new file mode 100644
index 0000000000..7a0ff9a094
--- /dev/null
+++ b/src/mbgl/style/data_driven_property_evaluator.hpp
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/property_evaluation_parameters.hpp>
+#include <mbgl/style/possibly_evaluated_property_value.hpp>
+
+namespace mbgl {
+namespace style {
+
+template <typename T>
+class DataDrivenPropertyEvaluator {
+public:
+ using ResultType = PossiblyEvaluatedPropertyValue<T>;
+
+ DataDrivenPropertyEvaluator(const PropertyEvaluationParameters& parameters_, T defaultValue_)
+ : parameters(parameters_),
+ defaultValue(std::move(defaultValue_)) {}
+
+ ResultType operator()(const Undefined&) const {
+ return ResultType(defaultValue);
+ }
+
+ ResultType operator()(const T& constant) const {
+ return ResultType(constant);
+ }
+
+ ResultType operator()(const CameraFunction<T>& function) const {
+ return ResultType(function.evaluate(parameters.z));
+ }
+
+ template <class Function>
+ ResultType operator()(const Function& function) const {
+ return ResultType(function);
+ }
+
+private:
+ const PropertyEvaluationParameters& parameters;
+ T defaultValue;
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/function.cpp b/src/mbgl/style/function.cpp
deleted file mode 100644
index 02750c7d2e..0000000000
--- a/src/mbgl/style/function.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-#include <mbgl/style/function.hpp>
-#include <mbgl/style/types.hpp>
-#include <mbgl/util/color.hpp>
-#include <mbgl/util/interpolate.hpp>
-
-#include <cmath>
-
-namespace mbgl {
-namespace style {
-
-template <typename T>
-T Function<T>::evaluate(float z) const {
- bool smaller = false;
- float smaller_z = 0.0f;
- T smaller_val = T();
- bool larger = false;
- float larger_z = 0.0f;
- T larger_val = T();
-
- for (uint32_t i = 0; i < stops.size(); i++) {
- float stop_z = stops[i].first;
- T stop_val = stops[i].second;
- if (stop_z <= z && (!smaller || smaller_z < stop_z)) {
- smaller = true;
- smaller_z = stop_z;
- smaller_val = stop_val;
- }
- if (stop_z >= z && (!larger || larger_z > stop_z)) {
- larger = true;
- larger_z = stop_z;
- larger_val = stop_val;
- }
- }
-
- if (smaller && larger) {
- if (larger_z == smaller_z || larger_val == smaller_val) {
- return smaller_val;
- }
- const float zoomDiff = larger_z - smaller_z;
- const float zoomProgress = z - smaller_z;
- if (base == 1.0f) {
- const float t = zoomProgress / zoomDiff;
- return util::interpolate(smaller_val, larger_val, t);
- } else {
- const float t = (std::pow(base, zoomProgress) - 1) / (std::pow(base, zoomDiff) - 1);
- return util::interpolate(smaller_val, larger_val, t);
- }
- } else if (larger) {
- return larger_val;
- } else if (smaller) {
- return smaller_val;
- } else {
- // No stop defined.
- assert(false);
- return T();
- }
-}
-
-template class Function<bool>;
-template class Function<float>;
-template class Function<Color>;
-template class Function<std::vector<float>>;
-template class Function<std::vector<std::string>>;
-template class Function<std::array<float, 2>>;
-template class Function<std::array<float, 4>>;
-
-template class Function<std::string>;
-template class Function<TranslateAnchorType>;
-template class Function<RotateAnchorType>;
-template class Function<CirclePitchScaleType>;
-template class Function<LineCapType>;
-template class Function<LineJoinType>;
-template class Function<SymbolPlacementType>;
-template class Function<TextAnchorType>;
-template class Function<TextJustifyType>;
-template class Function<TextTransformType>;
-template class Function<AlignmentType>;
-template class Function<IconTextFitType>;
-
-} // namespace style
-} // namespace mbgl
diff --git a/src/mbgl/style/function/categorical_stops.cpp b/src/mbgl/style/function/categorical_stops.cpp
new file mode 100644
index 0000000000..bcdf170f17
--- /dev/null
+++ b/src/mbgl/style/function/categorical_stops.cpp
@@ -0,0 +1,35 @@
+#include <mbgl/style/function/categorical_stops.hpp>
+#include <mbgl/util/color.hpp>
+
+#include <array>
+
+namespace mbgl {
+namespace style {
+
+optional<CategoricalValue> categoricalValue(const Value& value) {
+ return value.match(
+ [] (bool t) { return optional<CategoricalValue>(t); },
+ [] (uint64_t t) { return optional<CategoricalValue>(int64_t(t)); },
+ [] (int64_t t) { return optional<CategoricalValue>(t); },
+ [] (double t) { return optional<CategoricalValue>(int64_t(t)); },
+ [] (const std::string& t) { return optional<CategoricalValue>(t); },
+ [] (const auto&) { return optional<CategoricalValue>(); }
+ );
+}
+
+template <class T>
+T CategoricalStops<T>::evaluate(const Value& value) const {
+ auto v = categoricalValue(value);
+ if (!v) {
+ return defaultValue;
+ }
+ auto it = stops.find(*v);
+ return it == stops.end() ? defaultValue : it->second;
+}
+
+template class CategoricalStops<float>;
+template class CategoricalStops<Color>;
+template class CategoricalStops<std::array<float, 2>>;
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/function/identity_stops.cpp b/src/mbgl/style/function/identity_stops.cpp
new file mode 100644
index 0000000000..e210b4d773
--- /dev/null
+++ b/src/mbgl/style/function/identity_stops.cpp
@@ -0,0 +1,43 @@
+#include <mbgl/style/function/identity_stops.hpp>
+#include <mbgl/util/color.hpp>
+
+#include <array>
+
+namespace mbgl {
+namespace style {
+
+template <>
+float IdentityStops<float>::evaluate(const Value& value) const {
+ return numericValue<float>(value)
+ .value_or(0.0f);
+}
+
+template <>
+Color IdentityStops<Color>::evaluate(const Value& value) const {
+ if (!value.is<std::string>()) {
+ return Color::black();
+ }
+
+ return Color::parse(value.get<std::string>())
+ .value_or(Color::black());
+}
+
+template <>
+std::array<float, 2> IdentityStops<std::array<float, 2>>::evaluate(const Value& value) const {
+ if (!value.is<std::vector<Value>>()) {
+ return {{ 0, 0 }};
+ }
+
+ const std::vector<Value>& vector = value.get<std::vector<Value>>();
+ if (vector.size() != 2 || !numericValue<float>(vector[0]) || !numericValue<float>(vector[1])) {
+ return {{ 0, 0 }};
+ }
+
+ return {{
+ *numericValue<float>(vector[0]),
+ *numericValue<float>(vector[1])
+ }};
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/layer_impl.hpp b/src/mbgl/style/layer_impl.hpp
index 0fea70c10b..9b2bfe4d2c 100644
--- a/src/mbgl/style/layer_impl.hpp
+++ b/src/mbgl/style/layer_impl.hpp
@@ -61,7 +61,7 @@ public:
// Returns true if any paint properties have active transitions.
virtual bool evaluate(const PropertyEvaluationParameters&) = 0;
- virtual std::unique_ptr<Bucket> createBucket(BucketParameters&, const GeometryTileLayer&) const = 0;
+ virtual std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const Layer*>&) const = 0;
// Checks whether this layer needs to be rendered in the given render pass.
bool hasRenderPass(RenderPass) const;
diff --git a/src/mbgl/style/layer_observer.hpp b/src/mbgl/style/layer_observer.hpp
index a3f9ca7528..2fa1c39660 100644
--- a/src/mbgl/style/layer_observer.hpp
+++ b/src/mbgl/style/layer_observer.hpp
@@ -12,6 +12,7 @@ public:
virtual void onLayerFilterChanged(Layer&) {}
virtual void onLayerVisibilityChanged(Layer&) {}
virtual void onLayerPaintPropertyChanged(Layer&) {}
+ virtual void onLayerDataDrivenPaintPropertyChanged(Layer&) {}
virtual void onLayerLayoutPropertyChanged(Layer&, const char *) {}
};
diff --git a/src/mbgl/style/layers/background_layer_impl.cpp b/src/mbgl/style/layers/background_layer_impl.cpp
index 4a8fe39c9a..f25ba9cfb4 100644
--- a/src/mbgl/style/layers/background_layer_impl.cpp
+++ b/src/mbgl/style/layers/background_layer_impl.cpp
@@ -16,7 +16,8 @@ bool BackgroundLayer::Impl::evaluate(const PropertyEvaluationParameters& paramet
return paint.hasTransition();
}
-std::unique_ptr<Bucket> BackgroundLayer::Impl::createBucket(BucketParameters&, const GeometryTileLayer&) const {
+std::unique_ptr<Bucket> BackgroundLayer::Impl::createBucket(const BucketParameters&, const std::vector<const Layer*>&) const {
+ assert(false);
return nullptr;
}
diff --git a/src/mbgl/style/layers/background_layer_impl.hpp b/src/mbgl/style/layers/background_layer_impl.hpp
index 4629217e6d..02a8c423d6 100644
--- a/src/mbgl/style/layers/background_layer_impl.hpp
+++ b/src/mbgl/style/layers/background_layer_impl.hpp
@@ -16,7 +16,7 @@ public:
void cascade(const CascadeParameters&) override;
bool evaluate(const PropertyEvaluationParameters&) override;
- std::unique_ptr<Bucket> createBucket(BucketParameters&, const GeometryTileLayer&) const override;
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const Layer*>&) const override;
BackgroundPaintProperties paint;
};
diff --git a/src/mbgl/style/layers/background_layer_properties.hpp b/src/mbgl/style/layers/background_layer_properties.hpp
index 792bf3de94..fae6c26a4b 100644
--- a/src/mbgl/style/layers/background_layer_properties.hpp
+++ b/src/mbgl/style/layers/background_layer_properties.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/types.hpp>
#include <mbgl/style/layout_property.hpp>
#include <mbgl/style/paint_property.hpp>
+#include <mbgl/programs/attributes.hpp>
namespace mbgl {
namespace style {
diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp
index 389ab93403..f8d06e2644 100644
--- a/src/mbgl/style/layers/circle_layer.cpp
+++ b/src/mbgl/style/layers/circle_layer.cpp
@@ -65,64 +65,80 @@ const Filter& CircleLayer::getFilter() const {
// Paint properties
-PropertyValue<float> CircleLayer::getDefaultCircleRadius() {
+DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleRadius() {
return { 5 };
}
-PropertyValue<float> CircleLayer::getCircleRadius(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<float> CircleLayer::getCircleRadius(const optional<std::string>& klass) const {
return impl->paint.get<CircleRadius>(klass);
}
-void CircleLayer::setCircleRadius(PropertyValue<float> value, const optional<std::string>& klass) {
+void CircleLayer::setCircleRadius(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleRadius(klass))
return;
impl->paint.set<CircleRadius>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
-PropertyValue<Color> CircleLayer::getDefaultCircleColor() {
+DataDrivenPropertyValue<Color> CircleLayer::getDefaultCircleColor() {
return { Color::black() };
}
-PropertyValue<Color> CircleLayer::getCircleColor(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<Color> CircleLayer::getCircleColor(const optional<std::string>& klass) const {
return impl->paint.get<CircleColor>(klass);
}
-void CircleLayer::setCircleColor(PropertyValue<Color> value, const optional<std::string>& klass) {
+void CircleLayer::setCircleColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getCircleColor(klass))
return;
impl->paint.set<CircleColor>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
-PropertyValue<float> CircleLayer::getDefaultCircleBlur() {
+DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleBlur() {
return { 0 };
}
-PropertyValue<float> CircleLayer::getCircleBlur(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<float> CircleLayer::getCircleBlur(const optional<std::string>& klass) const {
return impl->paint.get<CircleBlur>(klass);
}
-void CircleLayer::setCircleBlur(PropertyValue<float> value, const optional<std::string>& klass) {
+void CircleLayer::setCircleBlur(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleBlur(klass))
return;
impl->paint.set<CircleBlur>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
-PropertyValue<float> CircleLayer::getDefaultCircleOpacity() {
+DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleOpacity() {
return { 1 };
}
-PropertyValue<float> CircleLayer::getCircleOpacity(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<float> CircleLayer::getCircleOpacity(const optional<std::string>& klass) const {
return impl->paint.get<CircleOpacity>(klass);
}
-void CircleLayer::setCircleOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
+void CircleLayer::setCircleOpacity(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleOpacity(klass))
return;
impl->paint.set<CircleOpacity>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
PropertyValue<std::array<float, 2>> CircleLayer::getDefaultCircleTranslate() {
@@ -170,49 +186,61 @@ void CircleLayer::setCirclePitchScale(PropertyValue<CirclePitchScaleType> value,
impl->observer->onLayerPaintPropertyChanged(*this);
}
-PropertyValue<float> CircleLayer::getDefaultCircleStrokeWidth() {
+DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleStrokeWidth() {
return { 0 };
}
-PropertyValue<float> CircleLayer::getCircleStrokeWidth(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<float> CircleLayer::getCircleStrokeWidth(const optional<std::string>& klass) const {
return impl->paint.get<CircleStrokeWidth>(klass);
}
-void CircleLayer::setCircleStrokeWidth(PropertyValue<float> value, const optional<std::string>& klass) {
+void CircleLayer::setCircleStrokeWidth(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleStrokeWidth(klass))
return;
impl->paint.set<CircleStrokeWidth>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
-PropertyValue<Color> CircleLayer::getDefaultCircleStrokeColor() {
+DataDrivenPropertyValue<Color> CircleLayer::getDefaultCircleStrokeColor() {
return { Color::black() };
}
-PropertyValue<Color> CircleLayer::getCircleStrokeColor(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<Color> CircleLayer::getCircleStrokeColor(const optional<std::string>& klass) const {
return impl->paint.get<CircleStrokeColor>(klass);
}
-void CircleLayer::setCircleStrokeColor(PropertyValue<Color> value, const optional<std::string>& klass) {
+void CircleLayer::setCircleStrokeColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getCircleStrokeColor(klass))
return;
impl->paint.set<CircleStrokeColor>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
-PropertyValue<float> CircleLayer::getDefaultCircleStrokeOpacity() {
+DataDrivenPropertyValue<float> CircleLayer::getDefaultCircleStrokeOpacity() {
return { 1 };
}
-PropertyValue<float> CircleLayer::getCircleStrokeOpacity(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<float> CircleLayer::getCircleStrokeOpacity(const optional<std::string>& klass) const {
return impl->paint.get<CircleStrokeOpacity>(klass);
}
-void CircleLayer::setCircleStrokeOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
+void CircleLayer::setCircleStrokeOpacity(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getCircleStrokeOpacity(klass))
return;
impl->paint.set<CircleStrokeOpacity>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
} // namespace style
diff --git a/src/mbgl/style/layers/circle_layer_impl.cpp b/src/mbgl/style/layers/circle_layer_impl.cpp
index 136522e41c..655ad9b5b9 100644
--- a/src/mbgl/style/layers/circle_layer_impl.cpp
+++ b/src/mbgl/style/layers/circle_layer_impl.cpp
@@ -1,5 +1,4 @@
#include <mbgl/style/layers/circle_layer_impl.hpp>
-#include <mbgl/style/bucket_parameters.hpp>
#include <mbgl/renderer/circle_bucket.hpp>
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/util/math.hpp>
@@ -15,27 +14,22 @@ void CircleLayer::Impl::cascade(const CascadeParameters& parameters) {
bool CircleLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) {
paint.evaluate(parameters);
- passes = (paint.evaluated.get<CircleRadius>() > 0 && paint.evaluated.get<CircleColor>().a > 0 && paint.evaluated.get<CircleOpacity>() > 0)
+ passes = (paint.evaluated.get<CircleRadius>().constantOr(1) > 0
+ && paint.evaluated.get<CircleColor>().constantOr(Color::black()).a > 0
+ && paint.evaluated.get<CircleOpacity>().constantOr(1) > 0)
? RenderPass::Translucent : RenderPass::None;
return paint.hasTransition();
}
-std::unique_ptr<Bucket> CircleLayer::Impl::createBucket(BucketParameters& parameters, const GeometryTileLayer& layer) const {
- auto bucket = std::make_unique<CircleBucket>(parameters.mode);
-
- parameters.eachFilteredFeature(filter, layer, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
- auto geometries = feature.getGeometries();
- bucket->addGeometry(geometries);
- parameters.featureIndex.insert(geometries, index, layerName, id);
- });
-
- return std::move(bucket);
+std::unique_ptr<Bucket> CircleLayer::Impl::createBucket(const BucketParameters& parameters, const std::vector<const Layer*>& layers) const {
+ return std::make_unique<CircleBucket>(parameters, layers);
}
float CircleLayer::Impl::getQueryRadius() const {
const std::array<float, 2>& translate = paint.evaluated.get<CircleTranslate>();
- return paint.evaluated.get<CircleRadius>() + util::length(translate[0], translate[1]);
+ return paint.evaluated.get<CircleRadius>().constantOr(CircleRadius::defaultValue())
+ + util::length(translate[0], translate[1]);
}
bool CircleLayer::Impl::queryIntersectsGeometry(
@@ -47,7 +41,7 @@ bool CircleLayer::Impl::queryIntersectsGeometry(
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
queryGeometry, paint.evaluated.get<CircleTranslate>(), paint.evaluated.get<CircleTranslateAnchor>(), bearing, pixelsToTileUnits);
- auto circleRadius = paint.evaluated.get<CircleRadius>() * pixelsToTileUnits;
+ auto circleRadius = paint.evaluated.get<CircleRadius>().constantOr(CircleRadius::defaultValue()) * pixelsToTileUnits;
return util::polygonIntersectsBufferedMultiPoint(
translatedQueryGeometry.value_or(queryGeometry), geometry, circleRadius);
diff --git a/src/mbgl/style/layers/circle_layer_impl.hpp b/src/mbgl/style/layers/circle_layer_impl.hpp
index 744a56898c..0f9611d589 100644
--- a/src/mbgl/style/layers/circle_layer_impl.hpp
+++ b/src/mbgl/style/layers/circle_layer_impl.hpp
@@ -16,7 +16,7 @@ public:
void cascade(const CascadeParameters&) override;
bool evaluate(const PropertyEvaluationParameters&) override;
- std::unique_ptr<Bucket> createBucket(BucketParameters&, const GeometryTileLayer&) const override;
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const Layer*>&) const override;
float getQueryRadius() const override;
bool queryIntersectsGeometry(
diff --git a/src/mbgl/style/layers/circle_layer_properties.hpp b/src/mbgl/style/layers/circle_layer_properties.hpp
index ea36b31949..1cb4f5a635 100644
--- a/src/mbgl/style/layers/circle_layer_properties.hpp
+++ b/src/mbgl/style/layers/circle_layer_properties.hpp
@@ -5,23 +5,24 @@
#include <mbgl/style/types.hpp>
#include <mbgl/style/layout_property.hpp>
#include <mbgl/style/paint_property.hpp>
+#include <mbgl/programs/attributes.hpp>
namespace mbgl {
namespace style {
-struct CircleRadius : PaintProperty<float> {
+struct CircleRadius : DataDrivenPaintProperty<float, attributes::a_radius> {
static float defaultValue() { return 5; }
};
-struct CircleColor : PaintProperty<Color> {
+struct CircleColor : DataDrivenPaintProperty<Color, attributes::a_color> {
static Color defaultValue() { return Color::black(); }
};
-struct CircleBlur : PaintProperty<float> {
+struct CircleBlur : DataDrivenPaintProperty<float, attributes::a_blur> {
static float defaultValue() { return 0; }
};
-struct CircleOpacity : PaintProperty<float> {
+struct CircleOpacity : DataDrivenPaintProperty<float, attributes::a_opacity> {
static float defaultValue() { return 1; }
};
@@ -37,15 +38,15 @@ struct CirclePitchScale : PaintProperty<CirclePitchScaleType> {
static CirclePitchScaleType defaultValue() { return CirclePitchScaleType::Map; }
};
-struct CircleStrokeWidth : PaintProperty<float> {
+struct CircleStrokeWidth : DataDrivenPaintProperty<float, attributes::a_stroke_width> {
static float defaultValue() { return 0; }
};
-struct CircleStrokeColor : PaintProperty<Color> {
+struct CircleStrokeColor : DataDrivenPaintProperty<Color, attributes::a_stroke_color> {
static Color defaultValue() { return Color::black(); }
};
-struct CircleStrokeOpacity : PaintProperty<float> {
+struct CircleStrokeOpacity : DataDrivenPaintProperty<float, attributes::a_stroke_opacity> {
static float defaultValue() { return 1; }
};
diff --git a/src/mbgl/style/layers/custom_layer_impl.cpp b/src/mbgl/style/layers/custom_layer_impl.cpp
index cecd60a296..379de25e8f 100644
--- a/src/mbgl/style/layers/custom_layer_impl.cpp
+++ b/src/mbgl/style/layers/custom_layer_impl.cpp
@@ -70,7 +70,8 @@ bool CustomLayer::Impl::evaluate(const PropertyEvaluationParameters&) {
return false;
}
-std::unique_ptr<Bucket> CustomLayer::Impl::createBucket(BucketParameters&, const GeometryTileLayer&) const {
+std::unique_ptr<Bucket> CustomLayer::Impl::createBucket(const BucketParameters&, const std::vector<const Layer*>&) const {
+ assert(false);
return nullptr;
}
diff --git a/src/mbgl/style/layers/custom_layer_impl.hpp b/src/mbgl/style/layers/custom_layer_impl.hpp
index 71fb46d0d9..33eb86828c 100644
--- a/src/mbgl/style/layers/custom_layer_impl.hpp
+++ b/src/mbgl/style/layers/custom_layer_impl.hpp
@@ -32,7 +32,7 @@ private:
void cascade(const CascadeParameters&) final {}
bool evaluate(const PropertyEvaluationParameters&) final;
- std::unique_ptr<Bucket> createBucket(BucketParameters&, const GeometryTileLayer&) const final;
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const Layer*>&) const final;
CustomLayerInitializeFunction initializeFn = nullptr;
CustomLayerRenderFunction renderFn = nullptr;
diff --git a/src/mbgl/style/layers/fill_extrusion_layer.cpp b/src/mbgl/style/layers/fill_extrusion_layer.cpp
index 34f0267d16..0ef5c9bcbc 100644
--- a/src/mbgl/style/layers/fill_extrusion_layer.cpp
+++ b/src/mbgl/style/layers/fill_extrusion_layer.cpp
@@ -80,19 +80,23 @@ void FillExtrusionLayer::setFillExtrusionOpacity(PropertyValue<float> value, con
impl->observer->onLayerPaintPropertyChanged(*this);
}
-PropertyValue<Color> FillExtrusionLayer::getDefaultFillExtrusionColor() {
+DataDrivenPropertyValue<Color> FillExtrusionLayer::getDefaultFillExtrusionColor() {
return { Color::black() };
}
-PropertyValue<Color> FillExtrusionLayer::getFillExtrusionColor(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<Color> FillExtrusionLayer::getFillExtrusionColor(const optional<std::string>& klass) const {
return impl->paint.get<FillExtrusionColor>(klass);
}
-void FillExtrusionLayer::setFillExtrusionColor(PropertyValue<Color> value, const optional<std::string>& klass) {
+void FillExtrusionLayer::setFillExtrusionColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getFillExtrusionColor(klass))
return;
impl->paint.set<FillExtrusionColor>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
PropertyValue<std::array<float, 2>> FillExtrusionLayer::getDefaultFillExtrusionTranslate() {
@@ -140,34 +144,42 @@ void FillExtrusionLayer::setFillExtrusionPattern(PropertyValue<std::string> valu
impl->observer->onLayerPaintPropertyChanged(*this);
}
-PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionHeight() {
+DataDrivenPropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionHeight() {
return { 0 };
}
-PropertyValue<float> FillExtrusionLayer::getFillExtrusionHeight(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<float> FillExtrusionLayer::getFillExtrusionHeight(const optional<std::string>& klass) const {
return impl->paint.get<FillExtrusionHeight>(klass);
}
-void FillExtrusionLayer::setFillExtrusionHeight(PropertyValue<float> value, const optional<std::string>& klass) {
+void FillExtrusionLayer::setFillExtrusionHeight(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getFillExtrusionHeight(klass))
return;
impl->paint.set<FillExtrusionHeight>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
-PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionBase() {
+DataDrivenPropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionBase() {
return { 0 };
}
-PropertyValue<float> FillExtrusionLayer::getFillExtrusionBase(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<float> FillExtrusionLayer::getFillExtrusionBase(const optional<std::string>& klass) const {
return impl->paint.get<FillExtrusionBase>(klass);
}
-void FillExtrusionLayer::setFillExtrusionBase(PropertyValue<float> value, const optional<std::string>& klass) {
+void FillExtrusionLayer::setFillExtrusionBase(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getFillExtrusionBase(klass))
return;
impl->paint.set<FillExtrusionBase>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
} // namespace style
diff --git a/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp b/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp
index ebe9009312..a809820644 100644
--- a/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp
+++ b/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp
@@ -11,7 +11,7 @@ bool FillExtrusionLayer::Impl::evaluate(const PropertyEvaluationParameters&) {
return false;
}
-std::unique_ptr<Bucket> FillExtrusionLayer::Impl::createBucket(BucketParameters&, const GeometryTileLayer&) const {
+std::unique_ptr<Bucket> FillExtrusionLayer::Impl::createBucket(const BucketParameters&, const std::vector<const Layer*>&) const {
return nullptr;
}
diff --git a/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp b/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp
index 3dd8bb270a..ed7ef747fb 100644
--- a/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp
+++ b/src/mbgl/style/layers/fill_extrusion_layer_impl.hpp
@@ -16,7 +16,7 @@ public:
void cascade(const CascadeParameters&) override;
bool evaluate(const PropertyEvaluationParameters&) override;
- std::unique_ptr<Bucket> createBucket(BucketParameters&, const GeometryTileLayer&) const override;
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const Layer*>&) const override;
FillExtrusionPaintProperties paint;
};
diff --git a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp
index a2d01199a5..c1dd3b079d 100644
--- a/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp
+++ b/src/mbgl/style/layers/fill_extrusion_layer_properties.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/types.hpp>
#include <mbgl/style/layout_property.hpp>
#include <mbgl/style/paint_property.hpp>
+#include <mbgl/programs/attributes.hpp>
namespace mbgl {
namespace style {
@@ -13,7 +14,7 @@ struct FillExtrusionOpacity : PaintProperty<float> {
static float defaultValue() { return 1; }
};
-struct FillExtrusionColor : PaintProperty<Color> {
+struct FillExtrusionColor : DataDrivenPaintProperty<Color, attributes::a_color> {
static Color defaultValue() { return Color::black(); }
};
@@ -29,11 +30,11 @@ struct FillExtrusionPattern : CrossFadedPaintProperty<std::string> {
static std::string defaultValue() { return ""; }
};
-struct FillExtrusionHeight : PaintProperty<float> {
+struct FillExtrusionHeight : DataDrivenPaintProperty<float, attributes::a_height> {
static float defaultValue() { return 0; }
};
-struct FillExtrusionBase : PaintProperty<float> {
+struct FillExtrusionBase : DataDrivenPaintProperty<float, attributes::a_base> {
static float defaultValue() { return 0; }
};
diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp
index b8fa8cad8b..e1c0d4d243 100644
--- a/src/mbgl/style/layers/fill_layer.cpp
+++ b/src/mbgl/style/layers/fill_layer.cpp
@@ -80,49 +80,61 @@ void FillLayer::setFillAntialias(PropertyValue<bool> value, const optional<std::
impl->observer->onLayerPaintPropertyChanged(*this);
}
-PropertyValue<float> FillLayer::getDefaultFillOpacity() {
+DataDrivenPropertyValue<float> FillLayer::getDefaultFillOpacity() {
return { 1 };
}
-PropertyValue<float> FillLayer::getFillOpacity(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<float> FillLayer::getFillOpacity(const optional<std::string>& klass) const {
return impl->paint.get<FillOpacity>(klass);
}
-void FillLayer::setFillOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
+void FillLayer::setFillOpacity(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getFillOpacity(klass))
return;
impl->paint.set<FillOpacity>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
-PropertyValue<Color> FillLayer::getDefaultFillColor() {
+DataDrivenPropertyValue<Color> FillLayer::getDefaultFillColor() {
return { Color::black() };
}
-PropertyValue<Color> FillLayer::getFillColor(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<Color> FillLayer::getFillColor(const optional<std::string>& klass) const {
return impl->paint.get<FillColor>(klass);
}
-void FillLayer::setFillColor(PropertyValue<Color> value, const optional<std::string>& klass) {
+void FillLayer::setFillColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getFillColor(klass))
return;
impl->paint.set<FillColor>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
-PropertyValue<Color> FillLayer::getDefaultFillOutlineColor() {
+DataDrivenPropertyValue<Color> FillLayer::getDefaultFillOutlineColor() {
return { {} };
}
-PropertyValue<Color> FillLayer::getFillOutlineColor(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<Color> FillLayer::getFillOutlineColor(const optional<std::string>& klass) const {
return impl->paint.get<FillOutlineColor>(klass);
}
-void FillLayer::setFillOutlineColor(PropertyValue<Color> value, const optional<std::string>& klass) {
+void FillLayer::setFillOutlineColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getFillOutlineColor(klass))
return;
impl->paint.set<FillOutlineColor>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
PropertyValue<std::array<float, 2>> FillLayer::getDefaultFillTranslate() {
diff --git a/src/mbgl/style/layers/fill_layer_impl.cpp b/src/mbgl/style/layers/fill_layer_impl.cpp
index 1ff26aa003..c7c89f8c20 100644
--- a/src/mbgl/style/layers/fill_layer_impl.cpp
+++ b/src/mbgl/style/layers/fill_layer_impl.cpp
@@ -1,5 +1,4 @@
#include <mbgl/style/layers/fill_layer_impl.hpp>
-#include <mbgl/style/bucket_parameters.hpp>
#include <mbgl/renderer/fill_bucket.hpp>
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/util/math.hpp>
@@ -25,7 +24,9 @@ bool FillLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) {
passes |= RenderPass::Translucent;
}
- if (!paint.evaluated.get<FillPattern>().from.empty() || (paint.evaluated.get<FillColor>().a * paint.evaluated.get<FillOpacity>()) < 1.0f) {
+ if (!paint.unevaluated.get<FillPattern>().isUndefined()
+ || paint.evaluated.get<FillColor>().constantOr(Color()).a < 1.0f
+ || paint.evaluated.get<FillOpacity>().constantOr(0) < 1.0f) {
passes |= RenderPass::Translucent;
} else {
passes |= RenderPass::Opaque;
@@ -34,16 +35,8 @@ bool FillLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) {
return paint.hasTransition();
}
-std::unique_ptr<Bucket> FillLayer::Impl::createBucket(BucketParameters& parameters, const GeometryTileLayer& layer) const {
- auto bucket = std::make_unique<FillBucket>();
-
- parameters.eachFilteredFeature(filter, layer, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
- auto geometries = feature.getGeometries();
- bucket->addGeometry(geometries);
- parameters.featureIndex.insert(geometries, index, layerName, id);
- });
-
- return std::move(bucket);
+std::unique_ptr<Bucket> FillLayer::Impl::createBucket(const BucketParameters& parameters, const std::vector<const Layer*>& layers) const {
+ return std::make_unique<FillBucket>(parameters, layers);
}
float FillLayer::Impl::getQueryRadius() const {
diff --git a/src/mbgl/style/layers/fill_layer_impl.hpp b/src/mbgl/style/layers/fill_layer_impl.hpp
index 28e2fa7edc..bd25a8bebf 100644
--- a/src/mbgl/style/layers/fill_layer_impl.hpp
+++ b/src/mbgl/style/layers/fill_layer_impl.hpp
@@ -16,7 +16,7 @@ public:
void cascade(const CascadeParameters&) override;
bool evaluate(const PropertyEvaluationParameters&) override;
- std::unique_ptr<Bucket> createBucket(BucketParameters&, const GeometryTileLayer&) const override;
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const Layer*>&) const override;
float getQueryRadius() const override;
bool queryIntersectsGeometry(
diff --git a/src/mbgl/style/layers/fill_layer_properties.hpp b/src/mbgl/style/layers/fill_layer_properties.hpp
index b2d926c31e..f44a18d0e0 100644
--- a/src/mbgl/style/layers/fill_layer_properties.hpp
+++ b/src/mbgl/style/layers/fill_layer_properties.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/types.hpp>
#include <mbgl/style/layout_property.hpp>
#include <mbgl/style/paint_property.hpp>
+#include <mbgl/programs/attributes.hpp>
namespace mbgl {
namespace style {
@@ -13,15 +14,15 @@ struct FillAntialias : PaintProperty<bool> {
static bool defaultValue() { return true; }
};
-struct FillOpacity : PaintProperty<float> {
+struct FillOpacity : DataDrivenPaintProperty<float, attributes::a_opacity> {
static float defaultValue() { return 1; }
};
-struct FillColor : PaintProperty<Color> {
+struct FillColor : DataDrivenPaintProperty<Color, attributes::a_color> {
static Color defaultValue() { return Color::black(); }
};
-struct FillOutlineColor : PaintProperty<Color> {
+struct FillOutlineColor : DataDrivenPaintProperty<Color, attributes::a_outline_color> {
static Color defaultValue() { return {}; }
};
diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs
index e730e3a29b..4a91a5c7e3 100644
--- a/src/mbgl/style/layers/layer.cpp.ejs
+++ b/src/mbgl/style/layers/layer.cpp.ejs
@@ -86,15 +86,15 @@ const Filter& <%- camelize(type) %>Layer::getFilter() const {
// Layout properties
<% for (const property of layoutProperties) { -%>
-PropertyValue<<%- propertyType(property) %>> <%- camelize(type) %>Layer::getDefault<%- camelize(property.name) %>() {
+<%- propertyValueType(property) %> <%- camelize(type) %>Layer::getDefault<%- camelize(property.name) %>() {
return <%- camelize(property.name) %>::defaultValue();
}
-PropertyValue<<%- propertyType(property) %>> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const {
+<%- propertyValueType(property) %> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const {
return impl->layout.unevaluated.get<<%- camelize(property.name) %>>();
}
-void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(PropertyValue<<%- propertyType(property) %>> value) {
+void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> value) {
if (value == get<%- camelize(property.name) %>())
return;
impl->layout.unevaluated.get<<%- camelize(property.name) %>>() = value;
@@ -104,19 +104,27 @@ void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(PropertyValue
// Paint properties
<% for (const property of paintProperties) { %>
-PropertyValue<<%- propertyType(property) %>> <%- camelize(type) %>Layer::getDefault<%- camelize(property.name) %>() {
+<%- propertyValueType(property) %> <%- camelize(type) %>Layer::getDefault<%- camelize(property.name) %>() {
return { <%- defaultValue(property) %> };
}
-PropertyValue<<%- propertyType(property) %>> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>(const optional<std::string>& klass) const {
+<%- propertyValueType(property) %> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>(const optional<std::string>& klass) const {
return impl->paint.get<<%- camelize(property.name) %>>(klass);
}
-void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(PropertyValue<<%- propertyType(property) %>> value, const optional<std::string>& klass) {
+void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyValueType(property) %> value, const optional<std::string>& klass) {
if (value == get<%- camelize(property.name) %>(klass))
return;
impl->paint.set<<%- camelize(property.name) %>>(value, klass);
+<% if (isDataDriven(property)) { -%>
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
+<% } else { -%>
impl->observer->onLayerPaintPropertyChanged(*this);
+<% } -%>
}
<% } -%>
diff --git a/src/mbgl/style/layers/layer_properties.hpp.ejs b/src/mbgl/style/layers/layer_properties.hpp.ejs
index d18ad44efd..2a736ca388 100644
--- a/src/mbgl/style/layers/layer_properties.hpp.ejs
+++ b/src/mbgl/style/layers/layer_properties.hpp.ejs
@@ -10,22 +10,21 @@
#include <mbgl/style/types.hpp>
#include <mbgl/style/layout_property.hpp>
#include <mbgl/style/paint_property.hpp>
+#include <mbgl/programs/attributes.hpp>
namespace mbgl {
namespace style {
<% for (const property of layoutProperties) { -%>
-struct <%- camelize(property.name) %> : LayoutProperty<<%- propertyType(property) %>> {
+struct <%- camelize(property.name) %> : <%- layoutPropertyType(property, type) %> {
static constexpr const char * key = "<%- property.name %>";
- static <%- propertyType(property) %> defaultValue() { return <%- defaultValue(property) %>; }
+ static <%- evaluatedType(property) %> defaultValue() { return <%- defaultValue(property) %>; }
};
<% } -%>
<% for (const property of paintProperties) { -%>
-struct <%- camelize(property.name) %> : <%
-if (/-pattern$/.test(property.name) || property.name === 'line-dasharray') {
-%>CrossFaded<% } -%>PaintProperty<<%- propertyType(property) %>> {
- static <%- propertyType(property) %> defaultValue() { return <%- defaultValue(property) %>; }
+struct <%- camelize(property.name) %> : <%- paintPropertyType(property, type) %> {
+ static <%- evaluatedType(property) %> defaultValue() { return <%- defaultValue(property) %>; }
};
<% } -%>
diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp
index 7f6c148cd1..fcad1eacb6 100644
--- a/src/mbgl/style/layers/line_layer.cpp
+++ b/src/mbgl/style/layers/line_layer.cpp
@@ -122,34 +122,42 @@ void LineLayer::setLineRoundLimit(PropertyValue<float> value) {
// Paint properties
-PropertyValue<float> LineLayer::getDefaultLineOpacity() {
+DataDrivenPropertyValue<float> LineLayer::getDefaultLineOpacity() {
return { 1 };
}
-PropertyValue<float> LineLayer::getLineOpacity(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<float> LineLayer::getLineOpacity(const optional<std::string>& klass) const {
return impl->paint.get<LineOpacity>(klass);
}
-void LineLayer::setLineOpacity(PropertyValue<float> value, const optional<std::string>& klass) {
+void LineLayer::setLineOpacity(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineOpacity(klass))
return;
impl->paint.set<LineOpacity>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
-PropertyValue<Color> LineLayer::getDefaultLineColor() {
+DataDrivenPropertyValue<Color> LineLayer::getDefaultLineColor() {
return { Color::black() };
}
-PropertyValue<Color> LineLayer::getLineColor(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<Color> LineLayer::getLineColor(const optional<std::string>& klass) const {
return impl->paint.get<LineColor>(klass);
}
-void LineLayer::setLineColor(PropertyValue<Color> value, const optional<std::string>& klass) {
+void LineLayer::setLineColor(DataDrivenPropertyValue<Color> value, const optional<std::string>& klass) {
if (value == getLineColor(klass))
return;
impl->paint.set<LineColor>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
PropertyValue<std::array<float, 2>> LineLayer::getDefaultLineTranslate() {
@@ -197,49 +205,61 @@ void LineLayer::setLineWidth(PropertyValue<float> value, const optional<std::str
impl->observer->onLayerPaintPropertyChanged(*this);
}
-PropertyValue<float> LineLayer::getDefaultLineGapWidth() {
+DataDrivenPropertyValue<float> LineLayer::getDefaultLineGapWidth() {
return { 0 };
}
-PropertyValue<float> LineLayer::getLineGapWidth(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<float> LineLayer::getLineGapWidth(const optional<std::string>& klass) const {
return impl->paint.get<LineGapWidth>(klass);
}
-void LineLayer::setLineGapWidth(PropertyValue<float> value, const optional<std::string>& klass) {
+void LineLayer::setLineGapWidth(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineGapWidth(klass))
return;
impl->paint.set<LineGapWidth>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
-PropertyValue<float> LineLayer::getDefaultLineOffset() {
+DataDrivenPropertyValue<float> LineLayer::getDefaultLineOffset() {
return { 0 };
}
-PropertyValue<float> LineLayer::getLineOffset(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<float> LineLayer::getLineOffset(const optional<std::string>& klass) const {
return impl->paint.get<LineOffset>(klass);
}
-void LineLayer::setLineOffset(PropertyValue<float> value, const optional<std::string>& klass) {
+void LineLayer::setLineOffset(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineOffset(klass))
return;
impl->paint.set<LineOffset>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
-PropertyValue<float> LineLayer::getDefaultLineBlur() {
+DataDrivenPropertyValue<float> LineLayer::getDefaultLineBlur() {
return { 0 };
}
-PropertyValue<float> LineLayer::getLineBlur(const optional<std::string>& klass) const {
+DataDrivenPropertyValue<float> LineLayer::getLineBlur(const optional<std::string>& klass) const {
return impl->paint.get<LineBlur>(klass);
}
-void LineLayer::setLineBlur(PropertyValue<float> value, const optional<std::string>& klass) {
+void LineLayer::setLineBlur(DataDrivenPropertyValue<float> value, const optional<std::string>& klass) {
if (value == getLineBlur(klass))
return;
impl->paint.set<LineBlur>(value, klass);
- impl->observer->onLayerPaintPropertyChanged(*this);
+ if (value.isDataDriven()) {
+ impl->observer->onLayerDataDrivenPaintPropertyChanged(*this);
+ } else {
+ impl->observer->onLayerPaintPropertyChanged(*this);
+ }
}
PropertyValue<std::vector<float>> LineLayer::getDefaultLineDasharray() {
diff --git a/src/mbgl/style/layers/line_layer_impl.cpp b/src/mbgl/style/layers/line_layer_impl.cpp
index 477579a43c..ef0131e3d5 100644
--- a/src/mbgl/style/layers/line_layer_impl.cpp
+++ b/src/mbgl/style/layers/line_layer_impl.cpp
@@ -1,5 +1,5 @@
#include <mbgl/style/layers/line_layer_impl.hpp>
-#include <mbgl/style/bucket_parameters.hpp>
+#include <mbgl/style/property_evaluation_parameters.hpp>
#include <mbgl/renderer/line_bucket.hpp>
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/util/math.hpp>
@@ -20,31 +20,25 @@ bool LineLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) {
paint.evaluate(parameters);
- passes = (paint.evaluated.get<LineOpacity>() > 0 && paint.evaluated.get<LineColor>().a > 0 && paint.evaluated.get<LineWidth>() > 0)
+ passes = (paint.evaluated.get<LineOpacity>().constantOr(1.0) > 0
+ && paint.evaluated.get<LineColor>().constantOr(Color::black()).a > 0
+ && paint.evaluated.get<LineWidth>() > 0)
? RenderPass::Translucent : RenderPass::None;
return paint.hasTransition();
}
-std::unique_ptr<Bucket> LineLayer::Impl::createBucket(BucketParameters& parameters, const GeometryTileLayer& layer) const {
- auto bucket = std::make_unique<LineBucket>(parameters.tileID.overscaleFactor());
-
- bucket->layout = layout.evaluate(PropertyEvaluationParameters(parameters.tileID.overscaledZ));
-
- parameters.eachFilteredFeature(filter, layer, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
- auto geometries = feature.getGeometries();
- bucket->addGeometry(geometries);
- parameters.featureIndex.insert(geometries, index, layerName, id);
- });
-
- return std::move(bucket);
+std::unique_ptr<Bucket> LineLayer::Impl::createBucket(const BucketParameters& parameters, const std::vector<const Layer*>& layers) const {
+ return std::make_unique<LineBucket>(parameters, layers, layout);
}
float LineLayer::Impl::getLineWidth() const {
- if (paint.evaluated.get<LineGapWidth>() > 0) {
- return paint.evaluated.get<LineGapWidth>() + 2 * paint.evaluated.get<LineWidth>();
+ float lineWidth = paint.evaluated.get<LineWidth>();
+ float gapWidth = paint.evaluated.get<LineGapWidth>().constantOr(0);
+ if (gapWidth) {
+ return gapWidth + 2 * lineWidth;
} else {
- return paint.evaluated.get<LineWidth>();
+ return lineWidth;
}
}
@@ -80,7 +74,8 @@ optional<GeometryCollection> offsetLine(const GeometryCollection& rings, const d
float LineLayer::Impl::getQueryRadius() const {
const std::array<float, 2>& translate = paint.evaluated.get<LineTranslate>();
- return getLineWidth() / 2.0 + std::abs(paint.evaluated.get<LineOffset>()) + util::length(translate[0], translate[1]);
+ auto offset = paint.evaluated.get<LineOffset>().constantOr(LineOffset::defaultValue());
+ return getLineWidth() / 2.0 + std::abs(offset) + util::length(translate[0], translate[1]);
}
bool LineLayer::Impl::queryIntersectsGeometry(
@@ -93,7 +88,9 @@ bool LineLayer::Impl::queryIntersectsGeometry(
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
queryGeometry, paint.evaluated.get<LineTranslate>(), paint.evaluated.get<LineTranslateAnchor>(), bearing, pixelsToTileUnits);
- auto offsetGeometry = offsetLine(geometry, paint.evaluated.get<LineOffset>() * pixelsToTileUnits);
+
+ auto offset = paint.evaluated.get<LineOffset>().constantOr(LineOffset::defaultValue());
+ auto offsetGeometry = offsetLine(geometry, offset * pixelsToTileUnits);
return util::polygonIntersectsBufferedMultiLine(
translatedQueryGeometry.value_or(queryGeometry),
diff --git a/src/mbgl/style/layers/line_layer_impl.hpp b/src/mbgl/style/layers/line_layer_impl.hpp
index 1955c019af..67e793f2ea 100644
--- a/src/mbgl/style/layers/line_layer_impl.hpp
+++ b/src/mbgl/style/layers/line_layer_impl.hpp
@@ -16,7 +16,7 @@ public:
void cascade(const CascadeParameters&) override;
bool evaluate(const PropertyEvaluationParameters&) override;
- std::unique_ptr<Bucket> createBucket(BucketParameters&, const GeometryTileLayer&) const override;
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const Layer*>&) const override;
float getQueryRadius() const override;
bool queryIntersectsGeometry(
diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp
index 2ea7f6b125..724026e3a6 100644
--- a/src/mbgl/style/layers/line_layer_properties.hpp
+++ b/src/mbgl/style/layers/line_layer_properties.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/types.hpp>
#include <mbgl/style/layout_property.hpp>
#include <mbgl/style/paint_property.hpp>
+#include <mbgl/programs/attributes.hpp>
namespace mbgl {
namespace style {
@@ -29,11 +30,11 @@ struct LineRoundLimit : LayoutProperty<float> {
static float defaultValue() { return 1; }
};
-struct LineOpacity : PaintProperty<float> {
+struct LineOpacity : DataDrivenPaintProperty<float, attributes::a_opacity> {
static float defaultValue() { return 1; }
};
-struct LineColor : PaintProperty<Color> {
+struct LineColor : DataDrivenPaintProperty<Color, attributes::a_color> {
static Color defaultValue() { return Color::black(); }
};
@@ -49,15 +50,15 @@ struct LineWidth : PaintProperty<float> {
static float defaultValue() { return 1; }
};
-struct LineGapWidth : PaintProperty<float> {
+struct LineGapWidth : DataDrivenPaintProperty<float, attributes::a_gap_width> {
static float defaultValue() { return 0; }
};
-struct LineOffset : PaintProperty<float> {
+struct LineOffset : DataDrivenPaintProperty<float, attributes::a_offset<1>> {
static float defaultValue() { return 0; }
};
-struct LineBlur : PaintProperty<float> {
+struct LineBlur : DataDrivenPaintProperty<float, attributes::a_blur> {
static float defaultValue() { return 0; }
};
diff --git a/src/mbgl/style/layers/raster_layer_impl.cpp b/src/mbgl/style/layers/raster_layer_impl.cpp
index a78614aee9..a667ccb5a8 100644
--- a/src/mbgl/style/layers/raster_layer_impl.cpp
+++ b/src/mbgl/style/layers/raster_layer_impl.cpp
@@ -16,7 +16,8 @@ bool RasterLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters)
return paint.hasTransition();
}
-std::unique_ptr<Bucket> RasterLayer::Impl::createBucket(BucketParameters&, const GeometryTileLayer&) const {
+std::unique_ptr<Bucket> RasterLayer::Impl::createBucket(const BucketParameters&, const std::vector<const Layer*>&) const {
+ assert(false);
return nullptr;
}
diff --git a/src/mbgl/style/layers/raster_layer_impl.hpp b/src/mbgl/style/layers/raster_layer_impl.hpp
index 8e69c21ca8..42985ce0f1 100644
--- a/src/mbgl/style/layers/raster_layer_impl.hpp
+++ b/src/mbgl/style/layers/raster_layer_impl.hpp
@@ -16,7 +16,7 @@ public:
void cascade(const CascadeParameters&) override;
bool evaluate(const PropertyEvaluationParameters&) override;
- std::unique_ptr<Bucket> createBucket(BucketParameters&, const GeometryTileLayer&) const override;
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const Layer*>&) const override;
RasterPaintProperties paint;
};
diff --git a/src/mbgl/style/layers/raster_layer_properties.hpp b/src/mbgl/style/layers/raster_layer_properties.hpp
index caa6d0c58d..219fe34d8c 100644
--- a/src/mbgl/style/layers/raster_layer_properties.hpp
+++ b/src/mbgl/style/layers/raster_layer_properties.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/types.hpp>
#include <mbgl/style/layout_property.hpp>
#include <mbgl/style/paint_property.hpp>
+#include <mbgl/programs/attributes.hpp>
namespace mbgl {
namespace style {
diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp
index c9014e7ee7..94c47f48b7 100644
--- a/src/mbgl/style/layers/symbol_layer.cpp
+++ b/src/mbgl/style/layers/symbol_layer.cpp
@@ -217,15 +217,15 @@ void SymbolLayer::setIconImage(PropertyValue<std::string> value) {
impl->layout.unevaluated.get<IconImage>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-image");
}
-PropertyValue<float> SymbolLayer::getDefaultIconRotate() {
+DataDrivenPropertyValue<float> SymbolLayer::getDefaultIconRotate() {
return IconRotate::defaultValue();
}
-PropertyValue<float> SymbolLayer::getIconRotate() const {
+DataDrivenPropertyValue<float> SymbolLayer::getIconRotate() const {
return impl->layout.unevaluated.get<IconRotate>();
}
-void SymbolLayer::setIconRotate(PropertyValue<float> value) {
+void SymbolLayer::setIconRotate(DataDrivenPropertyValue<float> value) {
if (value == getIconRotate())
return;
impl->layout.unevaluated.get<IconRotate>() = value;
@@ -259,15 +259,15 @@ void SymbolLayer::setIconKeepUpright(PropertyValue<bool> value) {
impl->layout.unevaluated.get<IconKeepUpright>() = value;
impl->observer->onLayerLayoutPropertyChanged(*this, "icon-keep-upright");
}
-PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconOffset() {
+DataDrivenPropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconOffset() {
return IconOffset::defaultValue();
}
-PropertyValue<std::array<float, 2>> SymbolLayer::getIconOffset() const {
+DataDrivenPropertyValue<std::array<float, 2>> SymbolLayer::getIconOffset() const {
return impl->layout.unevaluated.get<IconOffset>();
}
-void SymbolLayer::setIconOffset(PropertyValue<std::array<float, 2>> value) {
+void SymbolLayer::setIconOffset(DataDrivenPropertyValue<std::array<float, 2>> value) {
if (value == getIconOffset())
return;
impl->layout.unevaluated.get<IconOffset>() = value;
diff --git a/src/mbgl/style/layers/symbol_layer_impl.cpp b/src/mbgl/style/layers/symbol_layer_impl.cpp
index f058598f5f..32547e465a 100644
--- a/src/mbgl/style/layers/symbol_layer_impl.cpp
+++ b/src/mbgl/style/layers/symbol_layer_impl.cpp
@@ -1,5 +1,5 @@
#include <mbgl/style/layers/symbol_layer_impl.hpp>
-#include <mbgl/style/bucket_parameters.hpp>
+#include <mbgl/style/property_evaluation_parameters.hpp>
#include <mbgl/layout/symbol_layout.hpp>
#include <mbgl/renderer/bucket.hpp>
@@ -24,52 +24,17 @@ bool SymbolLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters)
return paint.hasTransition();
}
-std::unique_ptr<Bucket> SymbolLayer::Impl::createBucket(BucketParameters&, const GeometryTileLayer&) const {
+std::unique_ptr<Bucket> SymbolLayer::Impl::createBucket(const BucketParameters&, const std::vector<const Layer*>&) const {
assert(false); // Should be calling createLayout() instead.
return nullptr;
}
-std::unique_ptr<SymbolLayout> SymbolLayer::Impl::createLayout(BucketParameters& parameters,
- const GeometryTileLayer& layer,
- std::vector<std::string> group) const {
- PropertyEvaluationParameters p(parameters.tileID.overscaledZ);
- SymbolLayoutProperties::Evaluated evaluated = layout.evaluate(p);
-
- if (evaluated.get<IconRotationAlignment>() == AlignmentType::Auto) {
- if (evaluated.get<SymbolPlacement>() == SymbolPlacementType::Line) {
- evaluated.get<IconRotationAlignment>() = AlignmentType::Map;
- } else {
- evaluated.get<IconRotationAlignment>() = AlignmentType::Viewport;
- }
- }
-
- if (evaluated.get<TextRotationAlignment>() == AlignmentType::Auto) {
- if (evaluated.get<SymbolPlacement>() == SymbolPlacementType::Line) {
- evaluated.get<TextRotationAlignment>() = AlignmentType::Map;
- } else {
- evaluated.get<TextRotationAlignment>() = AlignmentType::Viewport;
- }
- }
-
- // If unspecified `text-pitch-alignment` inherits `text-rotation-alignment`
- if (evaluated.get<TextPitchAlignment>() == AlignmentType::Auto) {
- evaluated.get<TextPitchAlignment>() = evaluated.get<TextRotationAlignment>();
- }
-
- float textMaxSize = layout.evaluate<TextSize>(PropertyEvaluationParameters(18));
-
- evaluated.get<IconSize>() = layout.evaluate<IconSize>(PropertyEvaluationParameters(p.z + 1));
- evaluated.get<TextSize>() = layout.evaluate<TextSize>(PropertyEvaluationParameters(p.z + 1));
-
- return std::make_unique<SymbolLayout>(std::move(group),
- layer.getName(),
- parameters.tileID.overscaleFactor(),
- parameters.tileID.overscaledZ,
- parameters.mode,
+std::unique_ptr<SymbolLayout> SymbolLayer::Impl::createLayout(const BucketParameters& parameters,
+ const std::vector<const Layer*>& group,
+ const GeometryTileLayer& layer) const {
+ return std::make_unique<SymbolLayout>(parameters,
+ group,
layer,
- filter,
- evaluated,
- textMaxSize,
*spriteAtlas);
}
diff --git a/src/mbgl/style/layers/symbol_layer_impl.hpp b/src/mbgl/style/layers/symbol_layer_impl.hpp
index db18da07e2..c00c2b0bba 100644
--- a/src/mbgl/style/layers/symbol_layer_impl.hpp
+++ b/src/mbgl/style/layers/symbol_layer_impl.hpp
@@ -50,9 +50,9 @@ public:
void cascade(const CascadeParameters&) override;
bool evaluate(const PropertyEvaluationParameters&) override;
- std::unique_ptr<Bucket> createBucket(BucketParameters&, const GeometryTileLayer&) const override;
- std::unique_ptr<SymbolLayout> createLayout(BucketParameters&, const GeometryTileLayer&,
- std::vector<std::string>) const;
+ std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const Layer*>&) const override;
+ std::unique_ptr<SymbolLayout> createLayout(const BucketParameters&, const std::vector<const Layer*>&,
+ const GeometryTileLayer&) const;
SymbolPropertyValues iconPropertyValues(const SymbolLayoutProperties::Evaluated&) const;
SymbolPropertyValues textPropertyValues(const SymbolLayoutProperties::Evaluated&) const;
diff --git a/src/mbgl/style/layers/symbol_layer_properties.hpp b/src/mbgl/style/layers/symbol_layer_properties.hpp
index f5fd6ce3df..a447eb7efa 100644
--- a/src/mbgl/style/layers/symbol_layer_properties.hpp
+++ b/src/mbgl/style/layers/symbol_layer_properties.hpp
@@ -5,6 +5,7 @@
#include <mbgl/style/types.hpp>
#include <mbgl/style/layout_property.hpp>
#include <mbgl/style/paint_property.hpp>
+#include <mbgl/programs/attributes.hpp>
namespace mbgl {
namespace style {
@@ -64,7 +65,7 @@ struct IconImage : LayoutProperty<std::string> {
static std::string defaultValue() { return ""; }
};
-struct IconRotate : LayoutProperty<float> {
+struct IconRotate : DataDrivenLayoutProperty<float> {
static constexpr const char * key = "icon-rotate";
static float defaultValue() { return 0; }
};
@@ -79,7 +80,7 @@ struct IconKeepUpright : LayoutProperty<bool> {
static bool defaultValue() { return false; }
};
-struct IconOffset : LayoutProperty<std::array<float, 2>> {
+struct IconOffset : DataDrivenLayoutProperty<std::array<float, 2>> {
static constexpr const char * key = "icon-offset";
static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
};
diff --git a/src/mbgl/style/layout_property.hpp b/src/mbgl/style/layout_property.hpp
index 6ea06ce556..7ce2ecc7b8 100644
--- a/src/mbgl/style/layout_property.hpp
+++ b/src/mbgl/style/layout_property.hpp
@@ -1,6 +1,9 @@
#pragma once
+#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/data_driven_property_value.hpp>
#include <mbgl/style/property_evaluator.hpp>
+#include <mbgl/style/data_driven_property_evaluator.hpp>
#include <mbgl/util/indexed_tuple.hpp>
namespace mbgl {
@@ -11,11 +14,19 @@ class PropertyEvaluationParameters;
template <class T>
class LayoutProperty {
public:
- using EvaluatorType = PropertyEvaluator<T>;
using UnevaluatedType = PropertyValue<T>;
+ using EvaluatorType = PropertyEvaluator<T>;
using EvaluatedType = T;
};
+template <class T>
+class DataDrivenLayoutProperty {
+public:
+ using UnevaluatedType = DataDrivenPropertyValue<T>;
+ using EvaluatorType = DataDrivenPropertyEvaluator<T>;
+ using EvaluatedType = PossiblyEvaluatedPropertyValue<T>;
+};
+
template <class... Ps>
class LayoutProperties {
public:
diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp
index 7b56f6415d..9031d590fe 100644
--- a/src/mbgl/style/paint_property.hpp
+++ b/src/mbgl/style/paint_property.hpp
@@ -1,11 +1,15 @@
#pragma once
#include <mbgl/style/class_dictionary.hpp>
+#include <mbgl/style/property_value.hpp>
+#include <mbgl/style/data_driven_property_value.hpp>
#include <mbgl/style/property_evaluator.hpp>
#include <mbgl/style/cross_faded_property_evaluator.hpp>
+#include <mbgl/style/data_driven_property_evaluator.hpp>
+#include <mbgl/style/property_evaluation_parameters.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/cascade_parameters.hpp>
-#include <mbgl/style/property_evaluation_parameters.hpp>
+#include <mbgl/style/paint_property_binder.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/interpolate.hpp>
#include <mbgl/util/indexed_tuple.hpp>
@@ -15,17 +19,18 @@
#include <utility>
namespace mbgl {
+
+class GeometryTileFeature;
+
namespace style {
-template <class T, class Evaluator>
+template <class Value>
class UnevaluatedPaintProperty {
public:
- using Result = typename Evaluator::ResultType;
-
UnevaluatedPaintProperty() = default;
- UnevaluatedPaintProperty(PropertyValue<T> value_,
- UnevaluatedPaintProperty<T, Evaluator> prior_,
+ UnevaluatedPaintProperty(Value value_,
+ UnevaluatedPaintProperty<Value> prior_,
TransitionOptions transition,
TimePoint now)
: begin(now + transition.delay.value_or(Duration::zero())),
@@ -36,22 +41,23 @@ public:
}
}
- Result evaluate(const PropertyEvaluationParameters& parameters, T defaultValue) {
- Result finalValue = value.evaluate(Evaluator(parameters, defaultValue));
+ template <class Evaluator>
+ auto evaluate(const Evaluator& evaluator, TimePoint now) {
+ auto finalValue = value.evaluate(evaluator);
if (!prior) {
// No prior value.
return finalValue;
- } else if (parameters.now >= end) {
+ } else if (now >= end) {
// Transition from prior value is now complete.
prior = {};
return finalValue;
- } else if (parameters.now < begin) {
+ } else if (now < begin) {
// Transition hasn't started yet.
- return prior->get().evaluate(parameters, defaultValue);
+ return prior->get().evaluate(evaluator, now);
} else {
// Interpolate between recursively-calculated prior value and final.
- float t = std::chrono::duration<float>(parameters.now - begin) / (end - begin);
- return util::interpolate(prior->get().evaluate(parameters, defaultValue), finalValue, util::DEFAULT_TRANSITION_EASE.solve(t, 0.001));
+ float t = std::chrono::duration<float>(now - begin) / (end - begin);
+ return util::interpolate(prior->get().evaluate(evaluator, now), finalValue, util::DEFAULT_TRANSITION_EASE.solve(t, 0.001));
}
}
@@ -63,27 +69,31 @@ public:
return value.isUndefined();
}
+ const Value& getValue() const {
+ return value;
+ }
+
private:
- optional<mapbox::util::recursive_wrapper<UnevaluatedPaintProperty<T, Evaluator>>> prior;
+ optional<mapbox::util::recursive_wrapper<UnevaluatedPaintProperty<Value>>> prior;
TimePoint begin;
TimePoint end;
- PropertyValue<T> value;
+ Value value;
};
-template <class T>
+template <class Value>
class CascadingPaintProperty {
public:
bool isUndefined() const {
return values.find(ClassID::Default) == values.end();
}
- const PropertyValue<T>& get(const optional<std::string>& klass) const {
- static const PropertyValue<T> staticValue;
+ const Value& get(const optional<std::string>& klass) const {
+ static const Value staticValue{};
const auto it = values.find(klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default);
return it == values.end() ? staticValue : it->second;
}
- void set(const PropertyValue<T>& value_, const optional<std::string>& klass) {
+ void set(const Value& value_, const optional<std::string>& klass) {
values[klass ? ClassDictionary::Get().lookup(*klass) : ClassID::Default] = value_;
}
@@ -94,7 +104,7 @@ public:
template <class UnevaluatedPaintProperty>
UnevaluatedPaintProperty cascade(const CascadeParameters& params, UnevaluatedPaintProperty prior) const {
TransitionOptions transition;
- PropertyValue<T> value;
+ Value value;
for (const auto classID : params.classes) {
if (values.find(classID) != values.end()) {
@@ -117,7 +127,7 @@ public:
}
private:
- std::unordered_map<ClassID, PropertyValue<T>> values;
+ std::unordered_map<ClassID, Value> values;
std::unordered_map<ClassID, TransitionOptions> transitions;
};
@@ -125,26 +135,48 @@ template <class T>
class PaintProperty {
public:
using ValueType = PropertyValue<T>;
- using CascadingType = CascadingPaintProperty<T>;
+ using CascadingType = CascadingPaintProperty<ValueType>;
+ using UnevaluatedType = UnevaluatedPaintProperty<ValueType>;
using EvaluatorType = PropertyEvaluator<T>;
- using UnevaluatedType = UnevaluatedPaintProperty<T, EvaluatorType>;
using EvaluatedType = T;
+ static constexpr bool IsDataDriven = false;
+};
+
+template <class T, class A>
+class DataDrivenPaintProperty {
+public:
+ using ValueType = DataDrivenPropertyValue<T>;
+ using CascadingType = CascadingPaintProperty<ValueType>;
+ using UnevaluatedType = UnevaluatedPaintProperty<ValueType>;
+ using EvaluatorType = DataDrivenPropertyEvaluator<T>;
+ using EvaluatedType = PossiblyEvaluatedPropertyValue<T>;
+ static constexpr bool IsDataDriven = true;
+
+ using Type = T;
+ using Attribute = A;
};
template <class T>
class CrossFadedPaintProperty {
public:
using ValueType = PropertyValue<T>;
- using CascadingType = CascadingPaintProperty<T>;
+ using CascadingType = CascadingPaintProperty<ValueType>;
+ using UnevaluatedType = UnevaluatedPaintProperty<ValueType>;
using EvaluatorType = CrossFadedPropertyEvaluator<T>;
- using UnevaluatedType = UnevaluatedPaintProperty<T, EvaluatorType>;
using EvaluatedType = Faded<T>;
+ static constexpr bool IsDataDriven = false;
};
+template <class P>
+struct IsDataDriven : std::integral_constant<bool, P::IsDataDriven> {};
+
template <class... Ps>
class PaintProperties {
public:
using Properties = TypeList<Ps...>;
+ using DataDrivenProperties = FilteredTypeList<Properties, IsDataDriven>;
+ using Binders = PaintPropertyBinders<DataDrivenProperties>;
+
using EvaluatedTypes = TypeList<typename Ps::EvaluatedType...>;
using UnevaluatedTypes = TypeList<typename Ps::UnevaluatedType...>;
using CascadingTypes = TypeList<typename Ps::CascadingType...>;
@@ -186,7 +218,9 @@ public:
template <class P>
auto evaluate(const PropertyEvaluationParameters& parameters) {
- return unevaluated.template get<P>().evaluate(parameters, P::defaultValue());
+ using Evaluator = typename P::EvaluatorType;
+ return unevaluated.template get<P>()
+ .evaluate(Evaluator(parameters, P::defaultValue()), parameters.now);
}
void evaluate(const PropertyEvaluationParameters& parameters) {
diff --git a/src/mbgl/style/paint_property_binder.hpp b/src/mbgl/style/paint_property_binder.hpp
new file mode 100644
index 0000000000..964f33d2ec
--- /dev/null
+++ b/src/mbgl/style/paint_property_binder.hpp
@@ -0,0 +1,283 @@
+#pragma once
+
+#include <mbgl/programs/attributes.hpp>
+#include <mbgl/gl/attribute.hpp>
+#include <mbgl/gl/uniform.hpp>
+#include <mbgl/util/type_list.hpp>
+
+namespace mbgl {
+namespace style {
+
+template <class T, class A>
+class ConstantPaintPropertyBinder {
+public:
+ using Attribute = A;
+ using AttributeValue = typename Attribute::Value;
+ using AttributeBinding = typename Attribute::Binding;
+
+ ConstantPaintPropertyBinder(T constant_)
+ : constant(std::move(constant_)) {
+ }
+
+ void populateVertexVector(const GeometryTileFeature&, std::size_t) {}
+ void upload(gl::Context&) {}
+
+ AttributeBinding minAttributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const {
+ return typename Attribute::ConstantBinding {
+ Attribute::value(currentValue.constantOr(constant))
+ };
+ }
+
+ AttributeBinding maxAttributeBinding(const PossiblyEvaluatedPropertyValue<T>&) const {
+ return AttributeBinding();
+ }
+
+ float interpolationFactor(float) const {
+ return 0.0f;
+ }
+
+private:
+ T constant;
+};
+
+template <class T, class A>
+class SourceFunctionPaintPropertyBinder {
+public:
+ using Attribute = A;
+ using AttributeValue = typename Attribute::Value;
+ using AttributeBinding = typename Attribute::Binding;
+
+ using Attributes = gl::Attributes<Attribute>;
+ using Vertex = typename Attributes::Vertex;
+
+ SourceFunctionPaintPropertyBinder(SourceFunction<T> function_)
+ : function(std::move(function_)) {
+ }
+
+ void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) {
+ AttributeValue value = Attribute::value(function.evaluate(feature));
+ for (std::size_t i = vertexVector.vertexSize(); i < length; ++i) {
+ vertexVector.emplace_back(Vertex { value });
+ }
+ }
+
+ void upload(gl::Context& context) {
+ vertexBuffer = context.createVertexBuffer(std::move(vertexVector));
+ }
+
+ AttributeBinding minAttributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const {
+ if (currentValue.isConstant()) {
+ return typename Attribute::ConstantBinding {
+ Attribute::value(*currentValue.constant())
+ };
+ } else {
+ return Attributes::allVariableBindings(*vertexBuffer)
+ .template get<Attribute>();
+ }
+ }
+
+ AttributeBinding maxAttributeBinding(const PossiblyEvaluatedPropertyValue<T>&) const {
+ return AttributeBinding();
+ }
+
+ float interpolationFactor(float) const {
+ return 0.0f;
+ }
+
+private:
+ SourceFunction<T> function;
+ gl::VertexVector<Vertex> vertexVector;
+ optional<gl::VertexBuffer<Vertex>> vertexBuffer;
+};
+
+template <class T, class A>
+class CompositeFunctionPaintPropertyBinder {
+public:
+ using Attribute = A;
+ using AttributeValue = typename Attribute::Value;
+ using AttributeBinding = typename Attribute::Binding;
+
+ using MinAttribute = attributes::Min<Attribute>;
+ using MaxAttribute = attributes::Max<Attribute>;
+
+ using Attributes = gl::Attributes<MinAttribute, MaxAttribute>;
+ using Vertex = typename Attributes::Vertex;
+
+ CompositeFunctionPaintPropertyBinder(CompositeFunction<T> function_, float zoom)
+ : function(std::move(function_)),
+ coveringRanges(function.coveringRanges(zoom)) {
+ }
+
+ void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) {
+ Range<T> range = function.evaluate(std::get<1>(coveringRanges), feature);
+ AttributeValue min = Attribute::value(range.min);
+ AttributeValue max = Attribute::value(range.max);
+ for (std::size_t i = vertexVector.vertexSize(); i < length; ++i) {
+ vertexVector.emplace_back(Vertex { min, max });
+ }
+ }
+
+ void upload(gl::Context& context) {
+ vertexBuffer = context.createVertexBuffer(std::move(vertexVector));
+ }
+
+ AttributeBinding minAttributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const {
+ if (currentValue.isConstant()) {
+ return typename Attribute::ConstantBinding {
+ Attribute::value(*currentValue.constant())
+ };
+ } else {
+ return Attributes::allVariableBindings(*vertexBuffer)
+ .template get<MinAttribute>();
+ }
+ }
+
+ AttributeBinding maxAttributeBinding(const PossiblyEvaluatedPropertyValue<T>& currentValue) const {
+ if (currentValue.isConstant()) {
+ return AttributeBinding();
+ } else {
+ return Attributes::allVariableBindings(*vertexBuffer)
+ .template get<MaxAttribute>();
+ }
+ }
+
+ float interpolationFactor(float currentZoom) const {
+ return util::interpolationFactor(1.0f, std::get<0>(coveringRanges), currentZoom);
+ }
+
+private:
+ using InnerStops = typename CompositeFunction<T>::InnerStops;
+ CompositeFunction<T> function;
+ std::tuple<Range<float>, Range<InnerStops>> coveringRanges;
+ gl::VertexVector<Vertex> vertexVector;
+ optional<gl::VertexBuffer<Vertex>> vertexBuffer;
+};
+
+template <class PaintProperty>
+class PaintPropertyBinder {
+public:
+ using Type = typename PaintProperty::Type;
+ using Attribute = typename PaintProperty::Attribute;
+ using PropertyValue = typename PaintProperty::EvaluatedType;
+
+ using Binder = variant<
+ ConstantPaintPropertyBinder<Type, Attribute>,
+ SourceFunctionPaintPropertyBinder<Type, Attribute>,
+ CompositeFunctionPaintPropertyBinder<Type, Attribute>>;
+
+ PaintPropertyBinder(const PropertyValue& value, float zoom)
+ : binder(value.match(
+ [&] (const Type& constant) -> Binder {
+ return ConstantPaintPropertyBinder<Type, Attribute>(constant);
+ },
+ [&] (const SourceFunction<Type>& function) {
+ return SourceFunctionPaintPropertyBinder<Type, Attribute>(function);
+ },
+ [&] (const CompositeFunction<Type>& function) {
+ return CompositeFunctionPaintPropertyBinder<Type, Attribute>(function, zoom);
+ }
+ )) {
+ }
+
+ void populateVertexVector(const GeometryTileFeature& feature, std::size_t length) {
+ binder.match([&] (auto& b) {
+ b.populateVertexVector(feature, length);
+ });
+ }
+
+ void upload(gl::Context& context) {
+ binder.match([&] (auto& b) {
+ b.upload(context);
+ });
+ }
+
+ using MinAttribute = attributes::Min<Attribute>;
+ using MaxAttribute = attributes::Max<Attribute>;
+ using AttributeBinding = typename Attribute::Binding;
+
+ AttributeBinding minAttributeBinding(const PropertyValue& currentValue) const {
+ return binder.match([&] (const auto& b) {
+ return b.minAttributeBinding(currentValue);
+ });
+ }
+
+ AttributeBinding maxAttributeBinding(const PropertyValue& currentValue) const {
+ return binder.match([&] (const auto& b) {
+ return b.maxAttributeBinding(currentValue);
+ });
+ }
+
+ using InterpolationUniform = attributes::InterpolationUniform<Attribute>;
+ using InterpolationUniformValue = typename InterpolationUniform::Value;
+
+ InterpolationUniformValue interpolationUniformValue(float currentZoom) const {
+ return InterpolationUniformValue {
+ binder.match([&] (const auto& b) {
+ return b.interpolationFactor(currentZoom);
+ })
+ };
+ }
+
+private:
+ Binder binder;
+};
+
+template <class Ps>
+class PaintPropertyBinders;
+
+template <class... Ps>
+class PaintPropertyBinders<TypeList<Ps...>> {
+public:
+ using Binders = IndexedTuple<TypeList<Ps...>, TypeList<PaintPropertyBinder<Ps>...>>;
+
+ template <class EvaluatedProperties>
+ PaintPropertyBinders(const EvaluatedProperties& properties, float z)
+ : binders(PaintPropertyBinder<Ps>(properties.template get<Ps>(), z)...) {
+ (void)z; // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56958
+ }
+
+ void populateVertexVectors(const GeometryTileFeature& feature, std::size_t length) {
+ util::ignore({
+ (binders.template get<Ps>().populateVertexVector(feature, length), 0)...
+ });
+ }
+
+ void upload(gl::Context& context) {
+ util::ignore({
+ (binders.template get<Ps>().upload(context), 0)...
+ });
+ }
+
+ using MinAttributes = gl::Attributes<typename PaintPropertyBinder<Ps>::MinAttribute...>;
+ using MaxAttributes = gl::Attributes<typename PaintPropertyBinder<Ps>::MaxAttribute...>;
+
+ using Attributes = gl::ConcatenateAttributes<MinAttributes, MaxAttributes>;
+ using AttributeBindings = typename Attributes::Bindings;
+
+ template <class EvaluatedProperties>
+ AttributeBindings attributeBindings(const EvaluatedProperties& currentProperties) const {
+ const typename MinAttributes::Bindings min {
+ binders.template get<Ps>().minAttributeBinding(currentProperties.template get<Ps>())...
+ };
+ const typename MaxAttributes::Bindings max {
+ binders.template get<Ps>().maxAttributeBinding(currentProperties.template get<Ps>())...
+ };
+ return min.concat(max);
+ }
+
+ using Uniforms = gl::Uniforms<typename PaintPropertyBinder<Ps>::InterpolationUniform...>;
+ using UniformValues = typename Uniforms::Values;
+
+ UniformValues uniformValues(float currentZoom) const {
+ (void)currentZoom; // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56958
+ return UniformValues {
+ binders.template get<Ps>().interpolationUniformValue(currentZoom)...
+ };
+ }
+
+private:
+ Binders binders;
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp
index c6c6e50dd7..926c243733 100644
--- a/src/mbgl/style/parser.cpp
+++ b/src/mbgl/style/parser.cpp
@@ -241,10 +241,14 @@ std::vector<FontStack> Parser::fontStacks() const {
result.insert({"Open Sans Regular", "Arial Unicode MS Regular"});
} else if (textFont.isConstant()) {
result.insert(textFont.asConstant());
- } else if (textFont.isFunction()) {
- for (const auto& stop : textFont.asFunction().getStops()) {
- result.insert(stop.second);
- }
+ } else if (textFont.isCameraFunction()) {
+ textFont.asCameraFunction().stops.match(
+ [&] (const auto& stops) {
+ for (const auto& stop : stops.stops) {
+ result.insert(stop.second);
+ }
+ }
+ );
}
}
}
diff --git a/src/mbgl/style/possibly_evaluated_property_value.hpp b/src/mbgl/style/possibly_evaluated_property_value.hpp
new file mode 100644
index 0000000000..bb917442f6
--- /dev/null
+++ b/src/mbgl/style/possibly_evaluated_property_value.hpp
@@ -0,0 +1,74 @@
+#pragma once
+
+#include <mbgl/style/function/source_function.hpp>
+#include <mbgl/style/function/composite_function.hpp>
+#include <mbgl/util/interpolate.hpp>
+#include <mbgl/util/variant.hpp>
+
+namespace mbgl {
+
+class GeometryTileFeature;
+
+namespace style {
+
+template <class T>
+class PossiblyEvaluatedPropertyValue {
+private:
+ using Value = variant<
+ T,
+ SourceFunction<T>,
+ CompositeFunction<T>>;
+
+ Value value;
+
+public:
+ PossiblyEvaluatedPropertyValue() = default;
+ PossiblyEvaluatedPropertyValue(Value v) : value(std::move(v)) {}
+
+ bool isConstant() const {
+ return value.template is<T>();
+ }
+
+ optional<T> constant() const {
+ return value.match(
+ [&] (const T& t) { return optional<T>(t); },
+ [&] (const auto&) { return optional<T>(); });
+ }
+
+ T constantOr(const T& t) const {
+ return constant().value_or(t);
+ }
+
+ template <class... Ts>
+ auto match(Ts&&... ts) const {
+ return value.match(std::forward<Ts>(ts)...);
+ }
+
+ T evaluate(float z, const GeometryTileFeature& feature) const {
+ return value.match(
+ [&] (const T& t) { return t; },
+ [&] (const SourceFunction<T>& t) { return t.evaluate(feature); },
+ [&] (const CompositeFunction<T>& t) { return t.evaluate(z, feature); });
+ }
+};
+
+} // namespace style
+
+namespace util {
+
+template <typename T>
+struct Interpolator<style::PossiblyEvaluatedPropertyValue<T>> {
+ style::PossiblyEvaluatedPropertyValue<T> operator()(const style::PossiblyEvaluatedPropertyValue<T>& a,
+ const style::PossiblyEvaluatedPropertyValue<T>& b,
+ const double t) const {
+ if (a.isConstant() && b.isConstant()) {
+ return { interpolate(*a.constant(), *b.constant(), t) };
+ } else {
+ return { a };
+ }
+ }
+};
+
+} // namespace util
+
+} // namespace mbgl
diff --git a/src/mbgl/style/property_evaluator.hpp b/src/mbgl/style/property_evaluator.hpp
index ca4962d948..3f629ada4f 100644
--- a/src/mbgl/style/property_evaluator.hpp
+++ b/src/mbgl/style/property_evaluator.hpp
@@ -17,7 +17,7 @@ public:
T operator()(const Undefined&) const { return defaultValue; }
T operator()(const T& constant) const { return constant; }
- T operator()(const Function<T>& fn) const { return fn.evaluate(parameters.z); }
+ T operator()(const CameraFunction<T>& fn) const { return fn.evaluate(parameters.z); }
private:
const PropertyEvaluationParameters& parameters;
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index d6a525f502..61fbba67b5 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -662,6 +662,11 @@ void Style::onLayerPaintPropertyChanged(Layer&) {
observer->onUpdate(Update::RecalculateStyle | Update::Classes);
}
+void Style::onLayerDataDrivenPaintPropertyChanged(Layer& layer) {
+ layer.accept(QueueSourceReloadVisitor { updateBatch });
+ observer->onUpdate(Update::RecalculateStyle | Update::Classes | Update::Layout);
+}
+
void Style::onLayerLayoutPropertyChanged(Layer& layer, const char * property) {
layer.accept(QueueSourceReloadVisitor { updateBatch });
diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp
index d46e80e8bf..4c4bcec63a 100644
--- a/src/mbgl/style/style.hpp
+++ b/src/mbgl/style/style.hpp
@@ -146,6 +146,7 @@ private:
void onLayerFilterChanged(Layer&) override;
void onLayerVisibilityChanged(Layer&) override;
void onLayerPaintPropertyChanged(Layer&) override;
+ void onLayerDataDrivenPaintPropertyChanged(Layer&) override;
void onLayerLayoutPropertyChanged(Layer&, const char *) override;
Observer nullObserver;