@@ -49,8 +49,16 @@ class CompositeFunction {
49
49
defaultValue(std::move(defaultValue_)) {
50
50
}
51
51
52
- std::tuple<Range<float >, Range<InnerStops>>
53
- coveringRanges (float zoom) const {
52
+ struct CoveringRanges {
53
+ float zoom;
54
+ Range<float > coveringZoomRange;
55
+ Range<InnerStops> coveringStopsRange;
56
+ };
57
+
58
+ // Return the relevant stop zoom values and inner stops that bracket a given zoom level. This
59
+ // is the first step toward evaluating the function, and is used for in the course of both partial
60
+ // evaluation of data-driven paint properties, and full evaluation of data-driven layout properties.
61
+ CoveringRanges coveringRanges (float zoom) const {
54
62
return stops.match (
55
63
[&] (const auto & s) {
56
64
assert (!s.stops .empty ());
@@ -63,7 +71,8 @@ class CompositeFunction {
63
71
minIt--;
64
72
}
65
73
66
- return std::make_tuple (
74
+ return CoveringRanges {
75
+ zoom,
67
76
Range<float > {
68
77
minIt == s.stops .end () ? s.stops .rbegin ()->first : minIt->first ,
69
78
maxIt == s.stops .end () ? s.stops .rbegin ()->first : maxIt->first
@@ -72,38 +81,49 @@ class CompositeFunction {
72
81
s.innerStops (minIt == s.stops .end () ? s.stops .rbegin ()->second : minIt->second ),
73
82
s.innerStops (maxIt == s.stops .end () ? s.stops .rbegin ()->second : maxIt->second )
74
83
}
75
- ) ;
84
+ } ;
76
85
}
77
86
);
78
87
}
79
88
89
+ // Given a range of zoom values (typically two adjacent integer zoom levels, e.g. 5.0 and 6.0),
90
+ // return the covering ranges for both. This is used in the course of partial evaluation for
91
+ // data-driven paint properties.
92
+ Range<CoveringRanges> rangeOfCoveringRanges (Range<float > zoomRange) {
93
+ return Range<CoveringRanges> {
94
+ coveringRanges (zoomRange.min ),
95
+ coveringRanges (zoomRange.max )
96
+ };
97
+ }
98
+
99
+ // Given the covering ranges for range of zoom values (typically two adjacent integer zoom levels,
100
+ // e.g. 5.0 and 6.0), and a feature, return the results of fully evaluating the function for that
101
+ // feature at each of the two zoom levels. These two results are what go into the paint vertex buffers
102
+ // for vertices associated with this feature. The shader will interpolate between them at render time.
80
103
template <class Feature >
81
- Range<T> evaluate (Range<InnerStops> coveringStops,
82
- const Feature& feature,
83
- T finalDefaultValue) const {
84
- optional<Value> v = feature.getValue (property);
85
- if (!v) {
86
- return {
104
+ Range<T> evaluate (const Range<CoveringRanges>& ranges, const Feature& feature, T finalDefaultValue) {
105
+ optional<Value> value = feature.getValue (property);
106
+ if (!value) {
107
+ return Range<T> {
87
108
defaultValue.value_or (finalDefaultValue),
88
109
defaultValue.value_or (finalDefaultValue)
89
110
};
90
111
}
91
- auto eval = [&] (const auto & s) {
92
- return s.evaluate (*v).value_or (defaultValue.value_or (finalDefaultValue));
93
- };
94
112
return Range<T> {
95
- coveringStops .min . match (eval ),
96
- coveringStops .max . match (eval )
113
+ evaluateFinal (ranges .min , *value, finalDefaultValue ),
114
+ evaluateFinal (ranges .max , *value, finalDefaultValue )
97
115
};
98
116
}
99
117
100
- T evaluate (float zoom, const GeometryTileFeature& feature, T finalDefaultValue) const {
101
- std::tuple<Range<float >, Range<InnerStops>> ranges = coveringRanges (zoom);
102
- Range<T> resultRange = evaluate (std::get<1 >(ranges), feature, finalDefaultValue);
103
- return util::interpolate (
104
- resultRange.min ,
105
- resultRange.max ,
106
- util::interpolationFactor (1 .0f , std::get<0 >(ranges), zoom));
118
+ // Fully evaluate the function for a zoom value and feature. This is used when evaluating data-driven
119
+ // layout properties.
120
+ template <class Feature >
121
+ T evaluate (float zoom, const Feature& feature, T finalDefaultValue) const {
122
+ optional<Value> value = feature.getValue (property);
123
+ if (!value) {
124
+ return defaultValue.value_or (finalDefaultValue);
125
+ }
126
+ return evaluateFinal (coveringRanges (zoom), *value, finalDefaultValue);
107
127
}
108
128
109
129
friend bool operator ==(const CompositeFunction& lhs,
@@ -115,6 +135,17 @@ class CompositeFunction {
115
135
std::string property;
116
136
Stops stops;
117
137
optional<T> defaultValue;
138
+
139
+ private:
140
+ T evaluateFinal (const CoveringRanges& ranges, const Value& value, T finalDefaultValue) const {
141
+ auto eval = [&] (const auto & s) {
142
+ return s.evaluate (value).value_or (defaultValue.value_or (finalDefaultValue));
143
+ };
144
+ return util::interpolate (
145
+ ranges.coveringStopsRange .min .match (eval),
146
+ ranges.coveringStopsRange .max .match (eval),
147
+ util::interpolationFactor (1 .0f , ranges.coveringZoomRange , ranges.zoom ));
148
+ }
118
149
};
119
150
120
151
} // namespace style
0 commit comments