diff options
author | Lauren Budorick <lauren@mapbox.com> | 2018-02-13 17:49:37 -0800 |
---|---|---|
committer | Lauren Budorick <lauren@mapbox.com> | 2018-02-14 17:32:09 -0800 |
commit | 314c241ab965d9534af5d0645eb6b3557af3e9cc (patch) | |
tree | 200e73cc4854c9fd295145bed7154f09077eb295 | |
parent | b2c7becf19533ee186fab85ad1ce10aabfcb55ff (diff) | |
download | qtlocation-mapboxgl-upstream/gradient-base_heatmap.tar.gz |
Implement line-gradientupstream/gradient-base_heatmap
51 files changed, 719 insertions, 325 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index f24482e301..471b8dd05e 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -315,6 +315,8 @@ set(MBGL_CORE_FILES src/mbgl/shaders/hillshade_prepare.hpp src/mbgl/shaders/line.cpp src/mbgl/shaders/line.hpp + src/mbgl/shaders/line_gradient.cpp + src/mbgl/shaders/line_gradient.hpp src/mbgl/shaders/line_pattern.cpp src/mbgl/shaders/line_pattern.hpp src/mbgl/shaders/line_sdf.cpp @@ -357,11 +359,11 @@ set(MBGL_CORE_FILES src/mbgl/storage/response.cpp # style + include/mbgl/style/color_ramp_property_value.hpp include/mbgl/style/conversion.hpp include/mbgl/style/data_driven_property_value.hpp include/mbgl/style/filter.hpp include/mbgl/style/filter_evaluator.hpp - include/mbgl/style/heatmap_color_property_value.hpp include/mbgl/style/image.hpp include/mbgl/style/layer.hpp include/mbgl/style/layer_type.hpp @@ -404,6 +406,7 @@ set(MBGL_CORE_FILES src/mbgl/style/types.cpp # style/conversion + include/mbgl/style/conversion/color_ramp_property_value.hpp include/mbgl/style/conversion/constant.hpp include/mbgl/style/conversion/coordinate.hpp include/mbgl/style/conversion/custom_geometry_source_options.hpp @@ -414,7 +417,6 @@ set(MBGL_CORE_FILES include/mbgl/style/conversion/geojson.hpp include/mbgl/style/conversion/geojson_options.hpp include/mbgl/style/conversion/get_json_type.hpp - include/mbgl/style/conversion/heatmap_color_property_value.hpp include/mbgl/style/conversion/layer.hpp include/mbgl/style/conversion/light.hpp include/mbgl/style/conversion/position.hpp diff --git a/include/mbgl/style/heatmap_color_property_value.hpp b/include/mbgl/style/color_ramp_property_value.hpp index 130639c6e2..03d74fae0c 100644 --- a/include/mbgl/style/heatmap_color_property_value.hpp +++ b/include/mbgl/style/color_ramp_property_value.hpp @@ -11,21 +11,21 @@ namespace style { * Special-case implementation of (a subset of) the PropertyValue<T> interface * used for building the HeatmapColor paint property traits class. */ -class HeatmapColorPropertyValue { +class ColorRampPropertyValue { private: std::shared_ptr<expression::Expression> value; - friend bool operator==(const HeatmapColorPropertyValue& lhs, const HeatmapColorPropertyValue& rhs) { + friend bool operator==(const ColorRampPropertyValue& lhs, const ColorRampPropertyValue& rhs) { return (lhs.isUndefined() && rhs.isUndefined()) || (lhs.value && rhs.value && *(lhs.value) == *(rhs.value)); } - friend bool operator!=(const HeatmapColorPropertyValue& lhs, const HeatmapColorPropertyValue& rhs) { + friend bool operator!=(const ColorRampPropertyValue& lhs, const ColorRampPropertyValue& rhs) { return !(lhs == rhs); } public: - HeatmapColorPropertyValue() : value(nullptr) {} - HeatmapColorPropertyValue(std::shared_ptr<expression::Expression> value_) : value(std::move(value_)) {} + ColorRampPropertyValue() : value(nullptr) {} + ColorRampPropertyValue(std::shared_ptr<expression::Expression> value_) : value(std::move(value_)) {} bool isUndefined() const { return value.get() == nullptr; } @@ -33,13 +33,13 @@ public: template <typename Evaluator> Color evaluate(const Evaluator&, TimePoint = {}) const { return {}; } - Color evaluate(double heatmapDensity) const { - const auto result = value->evaluate(expression::EvaluationContext({}, nullptr, {heatmapDensity})); + Color evaluate(double rampEvaluationParameter) const { + const auto result = value->evaluate(expression::EvaluationContext({}, nullptr, {rampEvaluationParameter})); return *expression::fromExpressionValue<Color>(*result); } bool isDataDriven() const { return false; } - bool hasDataDrivenPropertyDifference(const HeatmapColorPropertyValue&) const { return false; } + bool hasDataDrivenPropertyDifference(const ColorRampPropertyValue&) const { return false; } const expression::Expression& getExpression() const { return *value; } }; diff --git a/include/mbgl/style/conversion/heatmap_color_property_value.hpp b/include/mbgl/style/conversion/color_ramp_property_value.hpp index e3689c524c..eeb9d0ae34 100644 --- a/include/mbgl/style/conversion/heatmap_color_property_value.hpp +++ b/include/mbgl/style/conversion/color_ramp_property_value.hpp @@ -1,6 +1,6 @@ #pragma once -#include <mbgl/style/heatmap_color_property_value.hpp> +#include <mbgl/style/color_ramp_property_value.hpp> #include <mbgl/style/conversion.hpp> #include <mbgl/style/conversion/constant.hpp> #include <mbgl/style/conversion/function.hpp> @@ -15,10 +15,10 @@ namespace style { namespace conversion { template <> -struct Converter<HeatmapColorPropertyValue> { - optional<HeatmapColorPropertyValue> operator()(const Convertible& value, Error& error) const { +struct Converter<ColorRampPropertyValue> { + optional<ColorRampPropertyValue> operator()(const Convertible& value, Error& error) const { if (isUndefined(value)) { - return HeatmapColorPropertyValue(); + return ColorRampPropertyValue(); } else if (isExpression(value)) { optional<std::unique_ptr<Expression>> expression = convert<std::unique_ptr<Expression>>(value, error, expression::type::Color); if (!expression) { @@ -33,9 +33,9 @@ struct Converter<HeatmapColorPropertyValue> { error = { "zoom expressions not supported" }; return {}; } - return {HeatmapColorPropertyValue(std::move(*expression))}; + return {ColorRampPropertyValue(std::move(*expression))}; } else { - error = { "heatmap-color must be an expression" }; + error = { "color ramp must be an expression" }; return {}; } } diff --git a/include/mbgl/style/expression/expression.hpp b/include/mbgl/style/expression/expression.hpp index cf9fa0cb21..41205d5a99 100644 --- a/include/mbgl/style/expression/expression.hpp +++ b/include/mbgl/style/expression/expression.hpp @@ -30,13 +30,13 @@ public: EvaluationContext(float zoom_, GeometryTileFeature const * feature_) : zoom(zoom_), feature(feature_) {} - EvaluationContext(optional<float> zoom_, GeometryTileFeature const * feature_, optional<double> heatmapDensity_) : - zoom(std::move(zoom_)), feature(feature_), heatmapDensity(std::move(heatmapDensity_)) + EvaluationContext(optional<float> zoom_, GeometryTileFeature const * feature_, optional<double> rampEvaluationParameter_) : + zoom(std::move(zoom_)), feature(feature_), rampEvaluationParameter(std::move(rampEvaluationParameter_)) {} - + optional<float> zoom; GeometryTileFeature const * feature; - optional<double> heatmapDensity; + optional<double> rampEvaluationParameter; }; template <typename T> @@ -127,7 +127,7 @@ public: type::Type getType() const { return type; }; - EvaluationResult evaluate(optional<float> zoom, const Feature& feature, optional<double> heatmapDensity) const; + EvaluationResult evaluate(optional<float> zoom, const Feature& feature, optional<double> rampEvaluationParameter) const; /** * Statically analyze the expression, attempting to enumerate possible outputs. Returns diff --git a/include/mbgl/style/layers/heatmap_layer.hpp b/include/mbgl/style/layers/heatmap_layer.hpp index 33d927ad38..79619d4bb5 100644 --- a/include/mbgl/style/layers/heatmap_layer.hpp +++ b/include/mbgl/style/layers/heatmap_layer.hpp @@ -6,7 +6,7 @@ #include <mbgl/style/filter.hpp> #include <mbgl/style/property_value.hpp> #include <mbgl/style/data_driven_property_value.hpp> -#include <mbgl/style/heatmap_color_property_value.hpp> +#include <mbgl/style/color_ramp_property_value.hpp> #include <mbgl/util/color.hpp> @@ -55,9 +55,9 @@ public: void setHeatmapIntensityTransition(const TransitionOptions&); TransitionOptions getHeatmapIntensityTransition() const; - static HeatmapColorPropertyValue getDefaultHeatmapColor(); - HeatmapColorPropertyValue getHeatmapColor() const; - void setHeatmapColor(HeatmapColorPropertyValue); + static ColorRampPropertyValue getDefaultHeatmapColor(); + ColorRampPropertyValue getHeatmapColor() const; + void setHeatmapColor(ColorRampPropertyValue); void setHeatmapColorTransition(const TransitionOptions&); TransitionOptions getHeatmapColorTransition() const; diff --git a/include/mbgl/style/layers/layer.hpp.ejs b/include/mbgl/style/layers/layer.hpp.ejs index 6d40405ccd..3f13b0d7d4 100644 --- a/include/mbgl/style/layers/layer.hpp.ejs +++ b/include/mbgl/style/layers/layer.hpp.ejs @@ -11,8 +11,8 @@ #include <mbgl/style/filter.hpp> #include <mbgl/style/property_value.hpp> #include <mbgl/style/data_driven_property_value.hpp> -<% if (type === 'heatmap') { -%> -#include <mbgl/style/heatmap_color_property_value.hpp> +<% if (type === 'heatmap' || type === 'line') { -%> +#include <mbgl/style/color_ramp_property_value.hpp> <% } -%> #include <mbgl/util/color.hpp> diff --git a/include/mbgl/style/layers/line_layer.hpp b/include/mbgl/style/layers/line_layer.hpp index 4519296323..fe3d5d9635 100644 --- a/include/mbgl/style/layers/line_layer.hpp +++ b/include/mbgl/style/layers/line_layer.hpp @@ -6,6 +6,7 @@ #include <mbgl/style/filter.hpp> #include <mbgl/style/property_value.hpp> #include <mbgl/style/data_driven_property_value.hpp> +#include <mbgl/style/color_ramp_property_value.hpp> #include <mbgl/util/color.hpp> @@ -116,6 +117,12 @@ public: void setLinePatternTransition(const TransitionOptions&); TransitionOptions getLinePatternTransition() const; + static ColorRampPropertyValue getDefaultLineGradient(); + ColorRampPropertyValue getLineGradient() const; + void setLineGradient(ColorRampPropertyValue); + void setLineGradientTransition(const TransitionOptions&); + TransitionOptions getLineGradientTransition() const; + // Private implementation class Impl; diff --git a/mapbox-gl-js b/mapbox-gl-js -Subproject d61850a6bd84ce6d697be392c7ef6d4b5555c20 +Subproject 5e853cd4d8b3e9cff546334242675e8f683e7ff diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java index 7b841a2580..b68f91bc5b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/expressions/Expression.java @@ -714,7 +714,7 @@ public class Expression<T> { } // - // Heatmap + // Color ramp properties // /** @@ -728,6 +728,17 @@ public class Expression<T> { return new Expression<>("heatmap-density"); } + /** + * Gets the progress along a line feature in a line layer, if `line-gradient` + * is used and correct distance properties are assigned to the feature. + * Can only be used in the `line-gradient` property. + * + * @return expression + */ + public static Expression<Number> lineProgress() { + return new Expression<>("line-progress"); + } + // // Lookup // @@ -1794,4 +1805,4 @@ public class Expression<T> { builder.append("]"); return builder.toString(); } -}
\ No newline at end of file +} diff --git a/platform/android/scripts/generate-style-code.js b/platform/android/scripts/generate-style-code.js index b9fd165830..e8038d95bd 100755 --- a/platform/android/scripts/generate-style-code.js +++ b/platform/android/scripts/generate-style-code.js @@ -28,7 +28,7 @@ var layers = Object.keys(spec.layer.type.values).map((type) => { }, []); const paintProperties = Object.keys(spec[`paint_${type}`]).reduce((memo, name) => { - if (name === 'heatmap-color') return memo; + if (name === 'heatmap-color' || name === 'line-gradient') return memo; spec[`paint_${type}`][name].name = name; memo.push(spec[`paint_${type}`][name]); return memo; diff --git a/platform/darwin/scripts/generate-style-code.js b/platform/darwin/scripts/generate-style-code.js index 53a668d10b..aabcfd8a45 100755 --- a/platform/darwin/scripts/generate-style-code.js +++ b/platform/darwin/scripts/generate-style-code.js @@ -308,7 +308,8 @@ global.propertyDoc = function (propertyName, property, layerType, kind) { doc += '* Predefined functions, including mathematical and string operators\n' + '* Conditional expressions\n' + '* Variable assignments and references to assigned variables\n'; - const inputVariable = property.name === 'heatmap-color' ? '$heatmapDensity' : '$zoomLevel'; + const inputVariable = property.name === 'heatmap-color' ? '$heatmapDensity' : + property.name === 'line-gradient' ? '$lineProgress': '$zoomLevel'; if (property["property-function"]) { doc += `* Interpolation and step functions applied to the \`${inputVariable}\` variable and/or feature attributes\n`; } else if (property.function === "interpolated") { diff --git a/platform/darwin/src/MGLHeatmapStyleLayer.mm b/platform/darwin/src/MGLHeatmapStyleLayer.mm index a394dbda3b..ab2451ed65 100644 --- a/platform/darwin/src/MGLHeatmapStyleLayer.mm +++ b/platform/darwin/src/MGLHeatmapStyleLayer.mm @@ -71,7 +71,7 @@ - (void)setHeatmapColor:(NSExpression *)heatmapColor { MGLAssertStyleLayerIsValid(); - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::HeatmapColorPropertyValue>(heatmapColor); + auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::ColorRampPropertyValue>(heatmapColor); self.rawLayer->setHeatmapColor(mbglValue); } diff --git a/platform/darwin/src/MGLLineStyleLayer.h b/platform/darwin/src/MGLLineStyleLayer.h index 003f48ae43..2e642f25b5 100644 --- a/platform/darwin/src/MGLLineStyleLayer.h +++ b/platform/darwin/src/MGLLineStyleLayer.h @@ -340,6 +340,26 @@ MGL_EXPORT @property (nonatomic) MGLTransition lineGapWidthTransition; /** + ¡ EXPERIMENTAL, UNSUPPORTED ! Defines the color of a point of a line based on + its progress along the line, if using gradient lines. + + This property is only applied to the style if `lineDasharray` is set to `nil`, + and `linePattern` is set to `nil`. Otherwise, it is ignored. + + You can set this property to an expression containing any of the following: + + * Constant `UIColor` values + * Predefined functions, including mathematical and string operators + * Conditional expressions + * Variable assignments and references to assigned variables + * Interpolation and step functions applied to the `$lineProgress` variable + + This property does not support applying interpolation or step functions to + feature attributes. + */ +@property (nonatomic, null_resettable) NSExpression *lineGradient; + +/** The line's offset. For linear features, a positive value offsets the line to the right, relative to the direction of the line, and a negative value to the left. For polygon features, a positive value results in an inset, and a diff --git a/platform/darwin/src/MGLLineStyleLayer.mm b/platform/darwin/src/MGLLineStyleLayer.mm index 4e6ff27b39..dec57f1500 100644 --- a/platform/darwin/src/MGLLineStyleLayer.mm +++ b/platform/darwin/src/MGLLineStyleLayer.mm @@ -306,6 +306,23 @@ namespace mbgl { return transition; } +- (void)setLineGradient:(NSExpression *)lineGradient { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::ColorRampPropertyValue>(lineGradient); + self.rawLayer->setLineGradient(mbglValue); +} + +- (NSExpression *)lineGradient { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getLineGradient(); + if (propertyValue.isUndefined()) { + propertyValue = self.rawLayer->getDefaultLineGradient(); + } + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toExpression(propertyValue); +} + - (void)setLineOffset:(NSExpression *)lineOffset { MGLAssertStyleLayerIsValid(); diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs index ac7676a1cc..c97cd41b2c 100644 --- a/platform/darwin/src/MGLStyleLayer.mm.ejs +++ b/platform/darwin/src/MGLStyleLayer.mm.ejs @@ -157,8 +157,8 @@ namespace mbgl { - (void)set<%- camelize(property.name) %>:(NSExpression *)<%- objCName(property) %> { MGLAssertStyleLayerIsValid(); -<% if (property.name === 'heatmap-color') { -%> - auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::HeatmapColorPropertyValue>(heatmapColor); +<% if (property.name === 'heatmap-color' || property.name === 'line-gradient') { -%> + auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toPropertyValue<mbgl::style::ColorRampPropertyValue>(<%- objCName(property) %>); <% } else if (property["property-function"]) { -%> auto mbglValue = MGLStyleValueTransformer<<%- valueTransformerArguments(property).join(', ') %>>().toPropertyValue<mbgl::style::DataDrivenPropertyValue<<%- valueTransformerArguments(property)[0] %>>>(<%- objCName(property) %>); <% } else { -%> diff --git a/platform/darwin/src/MGLStyleValue_Private.h b/platform/darwin/src/MGLStyleValue_Private.h index 5124c29a90..2bc0dd0c6d 100644 --- a/platform/darwin/src/MGLStyleValue_Private.h +++ b/platform/darwin/src/MGLStyleValue_Private.h @@ -10,7 +10,7 @@ #import "MGLConversion.h" #include <mbgl/style/conversion/property_value.hpp> #include <mbgl/style/conversion/data_driven_property_value.hpp> -#include <mbgl/style/conversion/heatmap_color_property_value.hpp> +#include <mbgl/style/conversion/color_ramp_property_value.hpp> #include <mbgl/style/conversion/position.hpp> #import <mbgl/style/types.hpp> @@ -54,7 +54,7 @@ public: } // Convert an mbgl heatmap color property value into an mgl style value - NSExpression *toExpression(const mbgl::style::HeatmapColorPropertyValue &mbglValue) { + NSExpression *toExpression(const mbgl::style::ColorRampPropertyValue &mbglValue) { if (mbglValue.isUndefined()) { return nil; } @@ -65,7 +65,7 @@ public: Converts an NSExpression to an mbgl property value. */ template <typename MBGLValue> - typename std::enable_if_t<!std::is_same<MBGLValue, mbgl::style::HeatmapColorPropertyValue>::value, + typename std::enable_if_t<!std::is_same<MBGLValue, mbgl::style::ColorRampPropertyValue>::value, MBGLValue> toPropertyValue(NSExpression *expression) { if (!expression) { return {}; @@ -100,7 +100,7 @@ public: Converts an NSExpression to an mbgl property value. */ template <typename MBGLValue> - typename std::enable_if_t<std::is_same<MBGLValue, mbgl::style::HeatmapColorPropertyValue>::value, + typename std::enable_if_t<std::is_same<MBGLValue, mbgl::style::ColorRampPropertyValue>::value, MBGLValue> toPropertyValue(NSExpression *expression) { if (!expression) { return {}; @@ -109,7 +109,7 @@ public: NSArray *jsonExpression = expression.mgl_jsonExpressionObject; mbgl::style::conversion::Error valueError; - auto value = mbgl::style::conversion::convert<mbgl::style::HeatmapColorPropertyValue>( + auto value = mbgl::style::conversion::convert<mbgl::style::ColorRampPropertyValue>( mbgl::style::conversion::makeConvertible(jsonExpression), valueError); if (!value) { [NSException raise:NSInvalidArgumentException diff --git a/platform/darwin/test/MGLBackgroundStyleLayerTests.mm b/platform/darwin/test/MGLBackgroundStyleLayerTests.mm index e7c2982413..6720dcd53e 100644 --- a/platform/darwin/test/MGLBackgroundStyleLayerTests.mm +++ b/platform/darwin/test/MGLBackgroundStyleLayerTests.mm @@ -50,13 +50,12 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getBackgroundColor(), propertyValue, @"Setting backgroundColor to a camera expression should update background-color."); XCTAssertEqualObjects(layer.backgroundColor, functionExpression, @"backgroundColor should round-trip camera expressions."); - layer.backgroundColor = nil; XCTAssertTrue(rawLayer->getBackgroundColor().isUndefined(), @@ -103,13 +102,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getBackgroundOpacity(), propertyValue, @"Setting backgroundOpacity to a camera expression should update background-opacity."); XCTAssertEqualObjects(layer.backgroundOpacity, functionExpression, @"backgroundOpacity should round-trip camera expressions."); - layer.backgroundOpacity = nil; XCTAssertTrue(rawLayer->getBackgroundOpacity().isUndefined(), @@ -156,13 +154,12 @@ { 18, "Background Pattern" }, }}; propertyValue = mbgl::style::CameraFunction<std::string> { intervalStops }; - + XCTAssertEqual(rawLayer->getBackgroundPattern(), propertyValue, @"Setting backgroundPattern to a camera expression should update background-pattern."); XCTAssertEqualObjects(layer.backgroundPattern, functionExpression, @"backgroundPattern should round-trip camera expressions."); - layer.backgroundPattern = nil; XCTAssertTrue(rawLayer->getBackgroundPattern().isUndefined(), diff --git a/platform/darwin/test/MGLCircleStyleLayerTests.mm b/platform/darwin/test/MGLCircleStyleLayerTests.mm index 7677344580..44031f63e6 100644 --- a/platform/darwin/test/MGLCircleStyleLayerTests.mm +++ b/platform/darwin/test/MGLCircleStyleLayerTests.mm @@ -71,7 +71,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getCircleBlur(), propertyValue, @"Setting circleBlur to a camera expression should update circle-blur."); XCTAssertEqualObjects(layer.circleBlur, functionExpression, @@ -100,7 +100,6 @@ @"Setting circleBlur to a camera-data expression should update circle-blur."); XCTAssertEqualObjects(layer.circleBlur, functionExpression, @"circleBlur should round-trip camera-data expressions."); - layer.circleBlur = nil; XCTAssertTrue(rawLayer->getCircleBlur().isUndefined(), @@ -141,7 +140,7 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getCircleColor(), propertyValue, @"Setting circleColor to a camera expression should update circle-color."); XCTAssertEqualObjects(layer.circleColor, functionExpression, @@ -170,7 +169,6 @@ @"Setting circleColor to a camera-data expression should update circle-color."); XCTAssertEqualObjects(layer.circleColor, functionExpression, @"circleColor should round-trip camera-data expressions."); - layer.circleColor = nil; XCTAssertTrue(rawLayer->getCircleColor().isUndefined(), @@ -211,7 +209,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getCircleOpacity(), propertyValue, @"Setting circleOpacity to a camera expression should update circle-opacity."); XCTAssertEqualObjects(layer.circleOpacity, functionExpression, @@ -240,7 +238,6 @@ @"Setting circleOpacity to a camera-data expression should update circle-opacity."); XCTAssertEqualObjects(layer.circleOpacity, functionExpression, @"circleOpacity should round-trip camera-data expressions."); - layer.circleOpacity = nil; XCTAssertTrue(rawLayer->getCircleOpacity().isUndefined(), @@ -281,13 +278,12 @@ { 18, mbgl::style::AlignmentType::Viewport }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::AlignmentType> { intervalStops }; - + XCTAssertEqual(rawLayer->getCirclePitchAlignment(), propertyValue, @"Setting circlePitchAlignment to a camera expression should update circle-pitch-alignment."); XCTAssertEqualObjects(layer.circlePitchAlignment, functionExpression, @"circlePitchAlignment should round-trip camera expressions."); - layer.circlePitchAlignment = nil; XCTAssertTrue(rawLayer->getCirclePitchAlignment().isUndefined(), @@ -325,7 +321,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getCircleRadius(), propertyValue, @"Setting circleRadius to a camera expression should update circle-radius."); XCTAssertEqualObjects(layer.circleRadius, functionExpression, @@ -354,7 +350,6 @@ @"Setting circleRadius to a camera-data expression should update circle-radius."); XCTAssertEqualObjects(layer.circleRadius, functionExpression, @"circleRadius should round-trip camera-data expressions."); - layer.circleRadius = nil; XCTAssertTrue(rawLayer->getCircleRadius().isUndefined(), @@ -395,13 +390,12 @@ { 18, mbgl::style::CirclePitchScaleType::Viewport }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::CirclePitchScaleType> { intervalStops }; - + XCTAssertEqual(rawLayer->getCirclePitchScale(), propertyValue, @"Setting circleScaleAlignment to a camera expression should update circle-pitch-scale."); XCTAssertEqualObjects(layer.circleScaleAlignment, functionExpression, @"circleScaleAlignment should round-trip camera expressions."); - layer.circleScaleAlignment = nil; XCTAssertTrue(rawLayer->getCirclePitchScale().isUndefined(), @@ -439,7 +433,7 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getCircleStrokeColor(), propertyValue, @"Setting circleStrokeColor to a camera expression should update circle-stroke-color."); XCTAssertEqualObjects(layer.circleStrokeColor, functionExpression, @@ -468,7 +462,6 @@ @"Setting circleStrokeColor to a camera-data expression should update circle-stroke-color."); XCTAssertEqualObjects(layer.circleStrokeColor, functionExpression, @"circleStrokeColor should round-trip camera-data expressions."); - layer.circleStrokeColor = nil; XCTAssertTrue(rawLayer->getCircleStrokeColor().isUndefined(), @@ -509,7 +502,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getCircleStrokeOpacity(), propertyValue, @"Setting circleStrokeOpacity to a camera expression should update circle-stroke-opacity."); XCTAssertEqualObjects(layer.circleStrokeOpacity, functionExpression, @@ -538,7 +531,6 @@ @"Setting circleStrokeOpacity to a camera-data expression should update circle-stroke-opacity."); XCTAssertEqualObjects(layer.circleStrokeOpacity, functionExpression, @"circleStrokeOpacity should round-trip camera-data expressions."); - layer.circleStrokeOpacity = nil; XCTAssertTrue(rawLayer->getCircleStrokeOpacity().isUndefined(), @@ -579,7 +571,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getCircleStrokeWidth(), propertyValue, @"Setting circleStrokeWidth to a camera expression should update circle-stroke-width."); XCTAssertEqualObjects(layer.circleStrokeWidth, functionExpression, @@ -608,7 +600,6 @@ @"Setting circleStrokeWidth to a camera-data expression should update circle-stroke-width."); XCTAssertEqualObjects(layer.circleStrokeWidth, functionExpression, @"circleStrokeWidth should round-trip camera-data expressions."); - layer.circleStrokeWidth = nil; XCTAssertTrue(rawLayer->getCircleStrokeWidth().isUndefined(), @@ -655,13 +646,12 @@ { 18, { 1, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<std::array<float, 2>> { intervalStops }; - + XCTAssertEqual(rawLayer->getCircleTranslate(), propertyValue, @"Setting circleTranslation to a camera expression should update circle-translate."); XCTAssertEqualObjects(layer.circleTranslation, functionExpression, @"circleTranslation should round-trip camera expressions."); - layer.circleTranslation = nil; XCTAssertTrue(rawLayer->getCircleTranslate().isUndefined(), @@ -699,13 +689,12 @@ { 18, mbgl::style::TranslateAnchorType::Viewport }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::TranslateAnchorType> { intervalStops }; - + XCTAssertEqual(rawLayer->getCircleTranslateAnchor(), propertyValue, @"Setting circleTranslationAnchor to a camera expression should update circle-translate-anchor."); XCTAssertEqualObjects(layer.circleTranslationAnchor, functionExpression, @"circleTranslationAnchor should round-trip camera expressions."); - layer.circleTranslationAnchor = nil; XCTAssertTrue(rawLayer->getCircleTranslateAnchor().isUndefined(), diff --git a/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm b/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm index f5e26381d6..f6647565d8 100644 --- a/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm +++ b/platform/darwin/test/MGLFillExtrusionStyleLayerTests.mm @@ -71,7 +71,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillExtrusionBase(), propertyValue, @"Setting fillExtrusionBase to a camera expression should update fill-extrusion-base."); XCTAssertEqualObjects(layer.fillExtrusionBase, functionExpression, @@ -100,7 +100,6 @@ @"Setting fillExtrusionBase to a camera-data expression should update fill-extrusion-base."); XCTAssertEqualObjects(layer.fillExtrusionBase, functionExpression, @"fillExtrusionBase should round-trip camera-data expressions."); - layer.fillExtrusionBase = nil; XCTAssertTrue(rawLayer->getFillExtrusionBase().isUndefined(), @@ -141,7 +140,7 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillExtrusionColor(), propertyValue, @"Setting fillExtrusionColor to a camera expression should update fill-extrusion-color."); XCTAssertEqualObjects(layer.fillExtrusionColor, functionExpression, @@ -170,7 +169,6 @@ @"Setting fillExtrusionColor to a camera-data expression should update fill-extrusion-color."); XCTAssertEqualObjects(layer.fillExtrusionColor, functionExpression, @"fillExtrusionColor should round-trip camera-data expressions."); - layer.fillExtrusionColor = nil; XCTAssertTrue(rawLayer->getFillExtrusionColor().isUndefined(), @@ -211,7 +209,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillExtrusionHeight(), propertyValue, @"Setting fillExtrusionHeight to a camera expression should update fill-extrusion-height."); XCTAssertEqualObjects(layer.fillExtrusionHeight, functionExpression, @@ -240,7 +238,6 @@ @"Setting fillExtrusionHeight to a camera-data expression should update fill-extrusion-height."); XCTAssertEqualObjects(layer.fillExtrusionHeight, functionExpression, @"fillExtrusionHeight should round-trip camera-data expressions."); - layer.fillExtrusionHeight = nil; XCTAssertTrue(rawLayer->getFillExtrusionHeight().isUndefined(), @@ -281,13 +278,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillExtrusionOpacity(), propertyValue, @"Setting fillExtrusionOpacity to a camera expression should update fill-extrusion-opacity."); XCTAssertEqualObjects(layer.fillExtrusionOpacity, functionExpression, @"fillExtrusionOpacity should round-trip camera expressions."); - layer.fillExtrusionOpacity = nil; XCTAssertTrue(rawLayer->getFillExtrusionOpacity().isUndefined(), @@ -334,13 +330,12 @@ { 18, "Fill Extrusion Pattern" }, }}; propertyValue = mbgl::style::CameraFunction<std::string> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillExtrusionPattern(), propertyValue, @"Setting fillExtrusionPattern to a camera expression should update fill-extrusion-pattern."); XCTAssertEqualObjects(layer.fillExtrusionPattern, functionExpression, @"fillExtrusionPattern should round-trip camera expressions."); - layer.fillExtrusionPattern = nil; XCTAssertTrue(rawLayer->getFillExtrusionPattern().isUndefined(), @@ -393,13 +388,12 @@ { 18, { 1, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<std::array<float, 2>> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillExtrusionTranslate(), propertyValue, @"Setting fillExtrusionTranslation to a camera expression should update fill-extrusion-translate."); XCTAssertEqualObjects(layer.fillExtrusionTranslation, functionExpression, @"fillExtrusionTranslation should round-trip camera expressions."); - layer.fillExtrusionTranslation = nil; XCTAssertTrue(rawLayer->getFillExtrusionTranslate().isUndefined(), @@ -437,13 +431,12 @@ { 18, mbgl::style::TranslateAnchorType::Viewport }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::TranslateAnchorType> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillExtrusionTranslateAnchor(), propertyValue, @"Setting fillExtrusionTranslationAnchor to a camera expression should update fill-extrusion-translate-anchor."); XCTAssertEqualObjects(layer.fillExtrusionTranslationAnchor, functionExpression, @"fillExtrusionTranslationAnchor should round-trip camera expressions."); - layer.fillExtrusionTranslationAnchor = nil; XCTAssertTrue(rawLayer->getFillExtrusionTranslateAnchor().isUndefined(), diff --git a/platform/darwin/test/MGLFillStyleLayerTests.mm b/platform/darwin/test/MGLFillStyleLayerTests.mm index 25521f3ede..5878de7863 100644 --- a/platform/darwin/test/MGLFillStyleLayerTests.mm +++ b/platform/darwin/test/MGLFillStyleLayerTests.mm @@ -71,13 +71,12 @@ { 18, false }, }}; propertyValue = mbgl::style::CameraFunction<bool> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillAntialias(), propertyValue, @"Setting fillAntialiased to a camera expression should update fill-antialias."); XCTAssertEqualObjects(layer.fillAntialiased, functionExpression, @"fillAntialiased should round-trip camera expressions."); - layer.fillAntialiased = nil; XCTAssertTrue(rawLayer->getFillAntialias().isUndefined(), @@ -115,7 +114,7 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillColor(), propertyValue, @"Setting fillColor to a camera expression should update fill-color."); XCTAssertEqualObjects(layer.fillColor, functionExpression, @@ -144,7 +143,6 @@ @"Setting fillColor to a camera-data expression should update fill-color."); XCTAssertEqualObjects(layer.fillColor, functionExpression, @"fillColor should round-trip camera-data expressions."); - layer.fillColor = nil; XCTAssertTrue(rawLayer->getFillColor().isUndefined(), @@ -185,7 +183,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillOpacity(), propertyValue, @"Setting fillOpacity to a camera expression should update fill-opacity."); XCTAssertEqualObjects(layer.fillOpacity, functionExpression, @@ -214,7 +212,6 @@ @"Setting fillOpacity to a camera-data expression should update fill-opacity."); XCTAssertEqualObjects(layer.fillOpacity, functionExpression, @"fillOpacity should round-trip camera-data expressions."); - layer.fillOpacity = nil; XCTAssertTrue(rawLayer->getFillOpacity().isUndefined(), @@ -255,7 +252,7 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillOutlineColor(), propertyValue, @"Setting fillOutlineColor to a camera expression should update fill-outline-color."); XCTAssertEqualObjects(layer.fillOutlineColor, functionExpression, @@ -284,7 +281,6 @@ @"Setting fillOutlineColor to a camera-data expression should update fill-outline-color."); XCTAssertEqualObjects(layer.fillOutlineColor, functionExpression, @"fillOutlineColor should round-trip camera-data expressions."); - layer.fillOutlineColor = nil; XCTAssertTrue(rawLayer->getFillOutlineColor().isUndefined(), @@ -325,13 +321,12 @@ { 18, "Fill Pattern" }, }}; propertyValue = mbgl::style::CameraFunction<std::string> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillPattern(), propertyValue, @"Setting fillPattern to a camera expression should update fill-pattern."); XCTAssertEqualObjects(layer.fillPattern, functionExpression, @"fillPattern should round-trip camera expressions."); - layer.fillPattern = nil; XCTAssertTrue(rawLayer->getFillPattern().isUndefined(), @@ -384,13 +379,12 @@ { 18, { 1, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<std::array<float, 2>> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillTranslate(), propertyValue, @"Setting fillTranslation to a camera expression should update fill-translate."); XCTAssertEqualObjects(layer.fillTranslation, functionExpression, @"fillTranslation should round-trip camera expressions."); - layer.fillTranslation = nil; XCTAssertTrue(rawLayer->getFillTranslate().isUndefined(), @@ -428,13 +422,12 @@ { 18, mbgl::style::TranslateAnchorType::Viewport }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::TranslateAnchorType> { intervalStops }; - + XCTAssertEqual(rawLayer->getFillTranslateAnchor(), propertyValue, @"Setting fillTranslationAnchor to a camera expression should update fill-translate-anchor."); XCTAssertEqualObjects(layer.fillTranslationAnchor, functionExpression, @"fillTranslationAnchor should round-trip camera expressions."); - layer.fillTranslationAnchor = nil; XCTAssertTrue(rawLayer->getFillTranslateAnchor().isUndefined(), diff --git a/platform/darwin/test/MGLHeatmapStyleLayerTests.mm b/platform/darwin/test/MGLHeatmapStyleLayerTests.mm index 74121affd8..f4b9cd5db2 100644 --- a/platform/darwin/test/MGLHeatmapStyleLayerTests.mm +++ b/platform/darwin/test/MGLHeatmapStyleLayerTests.mm @@ -71,13 +71,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getHeatmapIntensity(), propertyValue, @"Setting heatmapIntensity to a camera expression should update heatmap-intensity."); XCTAssertEqualObjects(layer.heatmapIntensity, functionExpression, @"heatmapIntensity should round-trip camera expressions."); - layer.heatmapIntensity = nil; XCTAssertTrue(rawLayer->getHeatmapIntensity().isUndefined(), @@ -124,13 +123,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getHeatmapOpacity(), propertyValue, @"Setting heatmapOpacity to a camera expression should update heatmap-opacity."); XCTAssertEqualObjects(layer.heatmapOpacity, functionExpression, @"heatmapOpacity should round-trip camera expressions."); - layer.heatmapOpacity = nil; XCTAssertTrue(rawLayer->getHeatmapOpacity().isUndefined(), @@ -177,7 +175,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getHeatmapRadius(), propertyValue, @"Setting heatmapRadius to a camera expression should update heatmap-radius."); XCTAssertEqualObjects(layer.heatmapRadius, functionExpression, @@ -206,7 +204,6 @@ @"Setting heatmapRadius to a camera-data expression should update heatmap-radius."); XCTAssertEqualObjects(layer.heatmapRadius, functionExpression, @"heatmapRadius should round-trip camera-data expressions."); - layer.heatmapRadius = nil; XCTAssertTrue(rawLayer->getHeatmapRadius().isUndefined(), @@ -247,7 +244,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getHeatmapWeight(), propertyValue, @"Setting heatmapWeight to a camera expression should update heatmap-weight."); XCTAssertEqualObjects(layer.heatmapWeight, functionExpression, @@ -276,7 +273,6 @@ @"Setting heatmapWeight to a camera-data expression should update heatmap-weight."); XCTAssertEqualObjects(layer.heatmapWeight, functionExpression, @"heatmapWeight should round-trip camera-data expressions."); - layer.heatmapWeight = nil; XCTAssertTrue(rawLayer->getHeatmapWeight().isUndefined(), diff --git a/platform/darwin/test/MGLHillshadeStyleLayerTests.mm b/platform/darwin/test/MGLHillshadeStyleLayerTests.mm index b0b7ddd5ee..568ebffb8f 100644 --- a/platform/darwin/test/MGLHillshadeStyleLayerTests.mm +++ b/platform/darwin/test/MGLHillshadeStyleLayerTests.mm @@ -53,13 +53,12 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getHillshadeAccentColor(), propertyValue, @"Setting hillshadeAccentColor to a camera expression should update hillshade-accent-color."); XCTAssertEqualObjects(layer.hillshadeAccentColor, functionExpression, @"hillshadeAccentColor should round-trip camera expressions."); - layer.hillshadeAccentColor = nil; XCTAssertTrue(rawLayer->getHillshadeAccentColor().isUndefined(), @@ -106,13 +105,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getHillshadeExaggeration(), propertyValue, @"Setting hillshadeExaggeration to a camera expression should update hillshade-exaggeration."); XCTAssertEqualObjects(layer.hillshadeExaggeration, functionExpression, @"hillshadeExaggeration should round-trip camera expressions."); - layer.hillshadeExaggeration = nil; XCTAssertTrue(rawLayer->getHillshadeExaggeration().isUndefined(), @@ -159,13 +157,12 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getHillshadeHighlightColor(), propertyValue, @"Setting hillshadeHighlightColor to a camera expression should update hillshade-highlight-color."); XCTAssertEqualObjects(layer.hillshadeHighlightColor, functionExpression, @"hillshadeHighlightColor should round-trip camera expressions."); - layer.hillshadeHighlightColor = nil; XCTAssertTrue(rawLayer->getHillshadeHighlightColor().isUndefined(), @@ -212,13 +209,12 @@ { 18, mbgl::style::HillshadeIlluminationAnchorType::Viewport }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::HillshadeIlluminationAnchorType> { intervalStops }; - + XCTAssertEqual(rawLayer->getHillshadeIlluminationAnchor(), propertyValue, @"Setting hillshadeIlluminationAnchor to a camera expression should update hillshade-illumination-anchor."); XCTAssertEqualObjects(layer.hillshadeIlluminationAnchor, functionExpression, @"hillshadeIlluminationAnchor should round-trip camera expressions."); - layer.hillshadeIlluminationAnchor = nil; XCTAssertTrue(rawLayer->getHillshadeIlluminationAnchor().isUndefined(), @@ -256,13 +252,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getHillshadeIlluminationDirection(), propertyValue, @"Setting hillshadeIlluminationDirection to a camera expression should update hillshade-illumination-direction."); XCTAssertEqualObjects(layer.hillshadeIlluminationDirection, functionExpression, @"hillshadeIlluminationDirection should round-trip camera expressions."); - layer.hillshadeIlluminationDirection = nil; XCTAssertTrue(rawLayer->getHillshadeIlluminationDirection().isUndefined(), @@ -300,13 +295,12 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getHillshadeShadowColor(), propertyValue, @"Setting hillshadeShadowColor to a camera expression should update hillshade-shadow-color."); XCTAssertEqualObjects(layer.hillshadeShadowColor, functionExpression, @"hillshadeShadowColor should round-trip camera expressions."); - layer.hillshadeShadowColor = nil; XCTAssertTrue(rawLayer->getHillshadeShadowColor().isUndefined(), diff --git a/platform/darwin/test/MGLLineStyleLayerTests.mm b/platform/darwin/test/MGLLineStyleLayerTests.mm index bf98e98320..d8b57178c5 100644 --- a/platform/darwin/test/MGLLineStyleLayerTests.mm +++ b/platform/darwin/test/MGLLineStyleLayerTests.mm @@ -71,13 +71,12 @@ { 18, mbgl::style::LineCapType::Square }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::LineCapType> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineCap(), propertyValue, @"Setting lineCap to a camera expression should update line-cap."); XCTAssertEqualObjects(layer.lineCap, functionExpression, @"lineCap should round-trip camera expressions."); - layer.lineCap = nil; XCTAssertTrue(rawLayer->getLineCap().isUndefined(), @@ -115,13 +114,12 @@ { 18, mbgl::style::LineJoinType::Miter }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::LineJoinType> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineJoin(), propertyValue, @"Setting lineJoin to a camera expression should update line-join."); XCTAssertEqualObjects(layer.lineJoin, functionExpression, @"lineJoin should round-trip camera expressions."); - layer.lineJoin = nil; XCTAssertTrue(rawLayer->getLineJoin().isUndefined(), @@ -153,13 +151,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineMiterLimit(), propertyValue, @"Setting lineMiterLimit to a camera expression should update line-miter-limit."); XCTAssertEqualObjects(layer.lineMiterLimit, functionExpression, @"lineMiterLimit should round-trip camera expressions."); - layer.lineMiterLimit = nil; XCTAssertTrue(rawLayer->getLineMiterLimit().isUndefined(), @@ -197,13 +194,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineRoundLimit(), propertyValue, @"Setting lineRoundLimit to a camera expression should update line-round-limit."); XCTAssertEqualObjects(layer.lineRoundLimit, functionExpression, @"lineRoundLimit should round-trip camera expressions."); - layer.lineRoundLimit = nil; XCTAssertTrue(rawLayer->getLineRoundLimit().isUndefined(), @@ -241,7 +237,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineBlur(), propertyValue, @"Setting lineBlur to a camera expression should update line-blur."); XCTAssertEqualObjects(layer.lineBlur, functionExpression, @@ -270,7 +266,6 @@ @"Setting lineBlur to a camera-data expression should update line-blur."); XCTAssertEqualObjects(layer.lineBlur, functionExpression, @"lineBlur should round-trip camera-data expressions."); - layer.lineBlur = nil; XCTAssertTrue(rawLayer->getLineBlur().isUndefined(), @@ -311,7 +306,7 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineColor(), propertyValue, @"Setting lineColor to a camera expression should update line-color."); XCTAssertEqualObjects(layer.lineColor, functionExpression, @@ -340,7 +335,6 @@ @"Setting lineColor to a camera-data expression should update line-color."); XCTAssertEqualObjects(layer.lineColor, functionExpression, @"lineColor should round-trip camera-data expressions."); - layer.lineColor = nil; XCTAssertTrue(rawLayer->getLineColor().isUndefined(), @@ -381,13 +375,12 @@ { 18, {1, 2} }, }}; propertyValue = mbgl::style::CameraFunction<std::vector<float>> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineDasharray(), propertyValue, @"Setting lineDashPattern to a camera expression should update line-dasharray."); XCTAssertEqualObjects(layer.lineDashPattern, functionExpression, @"lineDashPattern should round-trip camera expressions."); - layer.lineDashPattern = nil; XCTAssertTrue(rawLayer->getLineDasharray().isUndefined(), @@ -425,7 +418,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineGapWidth(), propertyValue, @"Setting lineGapWidth to a camera expression should update line-gap-width."); XCTAssertEqualObjects(layer.lineGapWidth, functionExpression, @@ -454,7 +447,6 @@ @"Setting lineGapWidth to a camera-data expression should update line-gap-width."); XCTAssertEqualObjects(layer.lineGapWidth, functionExpression, @"lineGapWidth should round-trip camera-data expressions."); - layer.lineGapWidth = nil; XCTAssertTrue(rawLayer->getLineGapWidth().isUndefined(), @@ -495,7 +487,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineOffset(), propertyValue, @"Setting lineOffset to a camera expression should update line-offset."); XCTAssertEqualObjects(layer.lineOffset, functionExpression, @@ -524,7 +516,6 @@ @"Setting lineOffset to a camera-data expression should update line-offset."); XCTAssertEqualObjects(layer.lineOffset, functionExpression, @"lineOffset should round-trip camera-data expressions."); - layer.lineOffset = nil; XCTAssertTrue(rawLayer->getLineOffset().isUndefined(), @@ -565,7 +556,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineOpacity(), propertyValue, @"Setting lineOpacity to a camera expression should update line-opacity."); XCTAssertEqualObjects(layer.lineOpacity, functionExpression, @@ -594,7 +585,6 @@ @"Setting lineOpacity to a camera-data expression should update line-opacity."); XCTAssertEqualObjects(layer.lineOpacity, functionExpression, @"lineOpacity should round-trip camera-data expressions."); - layer.lineOpacity = nil; XCTAssertTrue(rawLayer->getLineOpacity().isUndefined(), @@ -635,13 +625,12 @@ { 18, "Line Pattern" }, }}; propertyValue = mbgl::style::CameraFunction<std::string> { intervalStops }; - + XCTAssertEqual(rawLayer->getLinePattern(), propertyValue, @"Setting linePattern to a camera expression should update line-pattern."); XCTAssertEqualObjects(layer.linePattern, functionExpression, @"linePattern should round-trip camera expressions."); - layer.linePattern = nil; XCTAssertTrue(rawLayer->getLinePattern().isUndefined(), @@ -694,13 +683,12 @@ { 18, { 1, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<std::array<float, 2>> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineTranslate(), propertyValue, @"Setting lineTranslation to a camera expression should update line-translate."); XCTAssertEqualObjects(layer.lineTranslation, functionExpression, @"lineTranslation should round-trip camera expressions."); - layer.lineTranslation = nil; XCTAssertTrue(rawLayer->getLineTranslate().isUndefined(), @@ -738,13 +726,12 @@ { 18, mbgl::style::TranslateAnchorType::Viewport }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::TranslateAnchorType> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineTranslateAnchor(), propertyValue, @"Setting lineTranslationAnchor to a camera expression should update line-translate-anchor."); XCTAssertEqualObjects(layer.lineTranslationAnchor, functionExpression, @"lineTranslationAnchor should round-trip camera expressions."); - layer.lineTranslationAnchor = nil; XCTAssertTrue(rawLayer->getLineTranslateAnchor().isUndefined(), @@ -782,7 +769,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getLineWidth(), propertyValue, @"Setting lineWidth to a camera expression should update line-width."); XCTAssertEqualObjects(layer.lineWidth, functionExpression, @@ -811,7 +798,6 @@ @"Setting lineWidth to a camera-data expression should update line-width."); XCTAssertEqualObjects(layer.lineWidth, functionExpression, @"lineWidth should round-trip camera-data expressions."); - layer.lineWidth = nil; XCTAssertTrue(rawLayer->getLineWidth().isUndefined(), diff --git a/platform/darwin/test/MGLRasterStyleLayerTests.mm b/platform/darwin/test/MGLRasterStyleLayerTests.mm index 5ded23ee3c..22e8d8d40a 100644 --- a/platform/darwin/test/MGLRasterStyleLayerTests.mm +++ b/platform/darwin/test/MGLRasterStyleLayerTests.mm @@ -53,13 +53,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getRasterBrightnessMax(), propertyValue, @"Setting maximumRasterBrightness to a camera expression should update raster-brightness-max."); XCTAssertEqualObjects(layer.maximumRasterBrightness, functionExpression, @"maximumRasterBrightness should round-trip camera expressions."); - layer.maximumRasterBrightness = nil; XCTAssertTrue(rawLayer->getRasterBrightnessMax().isUndefined(), @@ -97,13 +96,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getRasterBrightnessMin(), propertyValue, @"Setting minimumRasterBrightness to a camera expression should update raster-brightness-min."); XCTAssertEqualObjects(layer.minimumRasterBrightness, functionExpression, @"minimumRasterBrightness should round-trip camera expressions."); - layer.minimumRasterBrightness = nil; XCTAssertTrue(rawLayer->getRasterBrightnessMin().isUndefined(), @@ -141,13 +139,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getRasterContrast(), propertyValue, @"Setting rasterContrast to a camera expression should update raster-contrast."); XCTAssertEqualObjects(layer.rasterContrast, functionExpression, @"rasterContrast should round-trip camera expressions."); - layer.rasterContrast = nil; XCTAssertTrue(rawLayer->getRasterContrast().isUndefined(), @@ -194,13 +191,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getRasterFadeDuration(), propertyValue, @"Setting rasterFadeDuration to a camera expression should update raster-fade-duration."); XCTAssertEqualObjects(layer.rasterFadeDuration, functionExpression, @"rasterFadeDuration should round-trip camera expressions."); - layer.rasterFadeDuration = nil; XCTAssertTrue(rawLayer->getRasterFadeDuration().isUndefined(), @@ -238,13 +234,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getRasterHueRotate(), propertyValue, @"Setting rasterHueRotation to a camera expression should update raster-hue-rotate."); XCTAssertEqualObjects(layer.rasterHueRotation, functionExpression, @"rasterHueRotation should round-trip camera expressions."); - layer.rasterHueRotation = nil; XCTAssertTrue(rawLayer->getRasterHueRotate().isUndefined(), @@ -282,13 +277,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getRasterOpacity(), propertyValue, @"Setting rasterOpacity to a camera expression should update raster-opacity."); XCTAssertEqualObjects(layer.rasterOpacity, functionExpression, @"rasterOpacity should round-trip camera expressions."); - layer.rasterOpacity = nil; XCTAssertTrue(rawLayer->getRasterOpacity().isUndefined(), @@ -335,13 +329,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getRasterSaturation(), propertyValue, @"Setting rasterSaturation to a camera expression should update raster-saturation."); XCTAssertEqualObjects(layer.rasterSaturation, functionExpression, @"rasterSaturation should round-trip camera expressions."); - layer.rasterSaturation = nil; XCTAssertTrue(rawLayer->getRasterSaturation().isUndefined(), diff --git a/platform/darwin/test/MGLStyleLayerTests.mm.ejs b/platform/darwin/test/MGLStyleLayerTests.mm.ejs index e17501ed18..4345ed186b 100644 --- a/platform/darwin/test/MGLStyleLayerTests.mm.ejs +++ b/platform/darwin/test/MGLStyleLayerTests.mm.ejs @@ -59,7 +59,7 @@ MGLTransition transitionTest = MGLTransitionMake(5, 4); <% for (const property of properties) { -%> -<% if (property.name === 'heatmap-color') continue; -%> +<% if (property.name === 'heatmap-color' || property.name === 'line-gradient') continue; -%> // <%- originalPropertyName(property) %> { @@ -88,7 +88,7 @@ { 18, <%- mbglTestValue(property, type) %> }, }}; propertyValue = mbgl::style::CameraFunction<<%- mbglType(property) %>> { intervalStops }; - + XCTAssertEqual(rawLayer->get<%- camelize(originalPropertyName(property)) %>(), propertyValue, @"Setting <%- objCName(property) %> to a camera expression should update <%- originalPropertyName(property) %>."); XCTAssertEqualObjects(layer.<%- objCName(property) %>, functionExpression, @@ -118,7 +118,7 @@ @"Setting <%- objCName(property) %> to a camera-data expression should update <%- originalPropertyName(property) %>."); XCTAssertEqualObjects(layer.<%- objCName(property) %>, functionExpression, @"<%- objCName(property) %> should round-trip camera-data expressions."); -<% } -%> +<% } -%> <% if (!property.required) { -%> layer.<%- objCName(property) %> = nil; @@ -152,7 +152,7 @@ - (void)testPropertyNames { <% for (const property of properties) { -%> -<% if (property.name === 'heatmap-color') continue; -%> +<% if (property.name === 'heatmap-color' || property.name === 'line-gradient') continue; -%> [self testPropertyName:@"<%- property.getter || property.name %>" isBoolean:<%- property.type === 'boolean' ? 'YES' : 'NO' %>]; <% } -%> } diff --git a/platform/darwin/test/MGLSymbolStyleLayerTests.mm b/platform/darwin/test/MGLSymbolStyleLayerTests.mm index 05e091b5c8..49db2d2ada 100644 --- a/platform/darwin/test/MGLSymbolStyleLayerTests.mm +++ b/platform/darwin/test/MGLSymbolStyleLayerTests.mm @@ -71,13 +71,12 @@ { 18, true }, }}; propertyValue = mbgl::style::CameraFunction<bool> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconAllowOverlap(), propertyValue, @"Setting iconAllowsOverlap to a camera expression should update icon-allow-overlap."); XCTAssertEqualObjects(layer.iconAllowsOverlap, functionExpression, @"iconAllowsOverlap should round-trip camera expressions."); - layer.iconAllowsOverlap = nil; XCTAssertTrue(rawLayer->getIconAllowOverlap().isUndefined(), @@ -115,13 +114,12 @@ { 18, mbgl::style::SymbolAnchorType::BottomRight }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::SymbolAnchorType> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconAnchor(), propertyValue, @"Setting iconAnchor to a camera expression should update icon-anchor."); XCTAssertEqualObjects(layer.iconAnchor, functionExpression, @"iconAnchor should round-trip camera expressions."); - layer.iconAnchor = nil; XCTAssertTrue(rawLayer->getIconAnchor().isUndefined(), @@ -153,13 +151,12 @@ { 18, true }, }}; propertyValue = mbgl::style::CameraFunction<bool> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconIgnorePlacement(), propertyValue, @"Setting iconIgnoresPlacement to a camera expression should update icon-ignore-placement."); XCTAssertEqualObjects(layer.iconIgnoresPlacement, functionExpression, @"iconIgnoresPlacement should round-trip camera expressions."); - layer.iconIgnoresPlacement = nil; XCTAssertTrue(rawLayer->getIconIgnorePlacement().isUndefined(), @@ -197,13 +194,12 @@ { 18, "Icon Image" }, }}; propertyValue = mbgl::style::CameraFunction<std::string> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconImage(), propertyValue, @"Setting iconImageName to a camera expression should update icon-image."); XCTAssertEqualObjects(layer.iconImageName, functionExpression, @"iconImageName should round-trip camera expressions."); - layer.iconImageName = nil; XCTAssertTrue(rawLayer->getIconImage().isUndefined(), @@ -241,7 +237,7 @@ { 18, { 1, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<std::array<float, 2>> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconOffset(), propertyValue, @"Setting iconOffset to a camera expression should update icon-offset."); XCTAssertEqualObjects(layer.iconOffset, functionExpression, @@ -270,7 +266,6 @@ @"Setting iconOffset to a camera-data expression should update icon-offset."); XCTAssertEqualObjects(layer.iconOffset, functionExpression, @"iconOffset should round-trip camera-data expressions."); - layer.iconOffset = nil; XCTAssertTrue(rawLayer->getIconOffset().isUndefined(), @@ -302,13 +297,12 @@ { 18, true }, }}; propertyValue = mbgl::style::CameraFunction<bool> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconOptional(), propertyValue, @"Setting iconOptional to a camera expression should update icon-optional."); XCTAssertEqualObjects(layer.iconOptional, functionExpression, @"iconOptional should round-trip camera expressions."); - layer.iconOptional = nil; XCTAssertTrue(rawLayer->getIconOptional().isUndefined(), @@ -346,13 +340,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconPadding(), propertyValue, @"Setting iconPadding to a camera expression should update icon-padding."); XCTAssertEqualObjects(layer.iconPadding, functionExpression, @"iconPadding should round-trip camera expressions."); - layer.iconPadding = nil; XCTAssertTrue(rawLayer->getIconPadding().isUndefined(), @@ -390,13 +383,12 @@ { 18, mbgl::style::AlignmentType::Auto }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::AlignmentType> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconPitchAlignment(), propertyValue, @"Setting iconPitchAlignment to a camera expression should update icon-pitch-alignment."); XCTAssertEqualObjects(layer.iconPitchAlignment, functionExpression, @"iconPitchAlignment should round-trip camera expressions."); - layer.iconPitchAlignment = nil; XCTAssertTrue(rawLayer->getIconPitchAlignment().isUndefined(), @@ -434,7 +426,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconRotate(), propertyValue, @"Setting iconRotation to a camera expression should update icon-rotate."); XCTAssertEqualObjects(layer.iconRotation, functionExpression, @@ -463,7 +455,6 @@ @"Setting iconRotation to a camera-data expression should update icon-rotate."); XCTAssertEqualObjects(layer.iconRotation, functionExpression, @"iconRotation should round-trip camera-data expressions."); - layer.iconRotation = nil; XCTAssertTrue(rawLayer->getIconRotate().isUndefined(), @@ -495,13 +486,12 @@ { 18, mbgl::style::AlignmentType::Auto }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::AlignmentType> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconRotationAlignment(), propertyValue, @"Setting iconRotationAlignment to a camera expression should update icon-rotation-alignment."); XCTAssertEqualObjects(layer.iconRotationAlignment, functionExpression, @"iconRotationAlignment should round-trip camera expressions."); - layer.iconRotationAlignment = nil; XCTAssertTrue(rawLayer->getIconRotationAlignment().isUndefined(), @@ -539,7 +529,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconSize(), propertyValue, @"Setting iconScale to a camera expression should update icon-size."); XCTAssertEqualObjects(layer.iconScale, functionExpression, @@ -568,7 +558,6 @@ @"Setting iconScale to a camera-data expression should update icon-size."); XCTAssertEqualObjects(layer.iconScale, functionExpression, @"iconScale should round-trip camera-data expressions."); - layer.iconScale = nil; XCTAssertTrue(rawLayer->getIconSize().isUndefined(), @@ -600,13 +589,12 @@ { 18, mbgl::style::IconTextFitType::Both }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::IconTextFitType> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconTextFit(), propertyValue, @"Setting iconTextFit to a camera expression should update icon-text-fit."); XCTAssertEqualObjects(layer.iconTextFit, functionExpression, @"iconTextFit should round-trip camera expressions."); - layer.iconTextFit = nil; XCTAssertTrue(rawLayer->getIconTextFit().isUndefined(), @@ -650,13 +638,12 @@ { 18, { 1, 1, 1, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<std::array<float, 4>> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconTextFitPadding(), propertyValue, @"Setting iconTextFitPadding to a camera expression should update icon-text-fit-padding."); XCTAssertEqualObjects(layer.iconTextFitPadding, functionExpression, @"iconTextFitPadding should round-trip camera expressions."); - layer.iconTextFitPadding = nil; XCTAssertTrue(rawLayer->getIconTextFitPadding().isUndefined(), @@ -694,13 +681,12 @@ { 18, true }, }}; propertyValue = mbgl::style::CameraFunction<bool> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconKeepUpright(), propertyValue, @"Setting keepsIconUpright to a camera expression should update icon-keep-upright."); XCTAssertEqualObjects(layer.keepsIconUpright, functionExpression, @"keepsIconUpright should round-trip camera expressions."); - layer.keepsIconUpright = nil; XCTAssertTrue(rawLayer->getIconKeepUpright().isUndefined(), @@ -738,13 +724,12 @@ { 18, false }, }}; propertyValue = mbgl::style::CameraFunction<bool> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextKeepUpright(), propertyValue, @"Setting keepsTextUpright to a camera expression should update text-keep-upright."); XCTAssertEqualObjects(layer.keepsTextUpright, functionExpression, @"keepsTextUpright should round-trip camera expressions."); - layer.keepsTextUpright = nil; XCTAssertTrue(rawLayer->getTextKeepUpright().isUndefined(), @@ -782,13 +767,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextMaxAngle(), propertyValue, @"Setting maximumTextAngle to a camera expression should update text-max-angle."); XCTAssertEqualObjects(layer.maximumTextAngle, functionExpression, @"maximumTextAngle should round-trip camera expressions."); - layer.maximumTextAngle = nil; XCTAssertTrue(rawLayer->getTextMaxAngle().isUndefined(), @@ -826,7 +810,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextMaxWidth(), propertyValue, @"Setting maximumTextWidth to a camera expression should update text-max-width."); XCTAssertEqualObjects(layer.maximumTextWidth, functionExpression, @@ -855,7 +839,6 @@ @"Setting maximumTextWidth to a camera-data expression should update text-max-width."); XCTAssertEqualObjects(layer.maximumTextWidth, functionExpression, @"maximumTextWidth should round-trip camera-data expressions."); - layer.maximumTextWidth = nil; XCTAssertTrue(rawLayer->getTextMaxWidth().isUndefined(), @@ -887,13 +870,12 @@ { 18, true }, }}; propertyValue = mbgl::style::CameraFunction<bool> { intervalStops }; - + XCTAssertEqual(rawLayer->getSymbolAvoidEdges(), propertyValue, @"Setting symbolAvoidsEdges to a camera expression should update symbol-avoid-edges."); XCTAssertEqualObjects(layer.symbolAvoidsEdges, functionExpression, @"symbolAvoidsEdges should round-trip camera expressions."); - layer.symbolAvoidsEdges = nil; XCTAssertTrue(rawLayer->getSymbolAvoidEdges().isUndefined(), @@ -931,13 +913,12 @@ { 18, mbgl::style::SymbolPlacementType::Line }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::SymbolPlacementType> { intervalStops }; - + XCTAssertEqual(rawLayer->getSymbolPlacement(), propertyValue, @"Setting symbolPlacement to a camera expression should update symbol-placement."); XCTAssertEqualObjects(layer.symbolPlacement, functionExpression, @"symbolPlacement should round-trip camera expressions."); - layer.symbolPlacement = nil; XCTAssertTrue(rawLayer->getSymbolPlacement().isUndefined(), @@ -975,13 +956,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getSymbolSpacing(), propertyValue, @"Setting symbolSpacing to a camera expression should update symbol-spacing."); XCTAssertEqualObjects(layer.symbolSpacing, functionExpression, @"symbolSpacing should round-trip camera expressions."); - layer.symbolSpacing = nil; XCTAssertTrue(rawLayer->getSymbolSpacing().isUndefined(), @@ -1019,13 +999,12 @@ { 18, "Text Field" }, }}; propertyValue = mbgl::style::CameraFunction<std::string> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextField(), propertyValue, @"Setting text to a camera expression should update text-field."); XCTAssertEqualObjects(layer.text, functionExpression, @"text should round-trip camera expressions."); - layer.text = nil; XCTAssertTrue(rawLayer->getTextField().isUndefined(), @@ -1057,13 +1036,12 @@ { 18, true }, }}; propertyValue = mbgl::style::CameraFunction<bool> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextAllowOverlap(), propertyValue, @"Setting textAllowsOverlap to a camera expression should update text-allow-overlap."); XCTAssertEqualObjects(layer.textAllowsOverlap, functionExpression, @"textAllowsOverlap should round-trip camera expressions."); - layer.textAllowsOverlap = nil; XCTAssertTrue(rawLayer->getTextAllowOverlap().isUndefined(), @@ -1101,13 +1079,12 @@ { 18, mbgl::style::SymbolAnchorType::BottomRight }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::SymbolAnchorType> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextAnchor(), propertyValue, @"Setting textAnchor to a camera expression should update text-anchor."); XCTAssertEqualObjects(layer.textAnchor, functionExpression, @"textAnchor should round-trip camera expressions."); - layer.textAnchor = nil; XCTAssertTrue(rawLayer->getTextAnchor().isUndefined(), @@ -1139,13 +1116,12 @@ { 18, { "Text Font", "Tnof Txet" } }, }}; propertyValue = mbgl::style::CameraFunction<std::vector<std::string>> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextFont(), propertyValue, @"Setting textFontNames to a camera expression should update text-font."); XCTAssertEqualObjects(layer.textFontNames, functionExpression, @"textFontNames should round-trip camera expressions."); - layer.textFontNames = nil; XCTAssertTrue(rawLayer->getTextFont().isUndefined(), @@ -1177,7 +1153,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextSize(), propertyValue, @"Setting textFontSize to a camera expression should update text-size."); XCTAssertEqualObjects(layer.textFontSize, functionExpression, @@ -1206,7 +1182,6 @@ @"Setting textFontSize to a camera-data expression should update text-size."); XCTAssertEqualObjects(layer.textFontSize, functionExpression, @"textFontSize should round-trip camera-data expressions."); - layer.textFontSize = nil; XCTAssertTrue(rawLayer->getTextSize().isUndefined(), @@ -1238,13 +1213,12 @@ { 18, true }, }}; propertyValue = mbgl::style::CameraFunction<bool> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextIgnorePlacement(), propertyValue, @"Setting textIgnoresPlacement to a camera expression should update text-ignore-placement."); XCTAssertEqualObjects(layer.textIgnoresPlacement, functionExpression, @"textIgnoresPlacement should round-trip camera expressions."); - layer.textIgnoresPlacement = nil; XCTAssertTrue(rawLayer->getTextIgnorePlacement().isUndefined(), @@ -1282,13 +1256,12 @@ { 18, mbgl::style::TextJustifyType::Right }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::TextJustifyType> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextJustify(), propertyValue, @"Setting textJustification to a camera expression should update text-justify."); XCTAssertEqualObjects(layer.textJustification, functionExpression, @"textJustification should round-trip camera expressions."); - layer.textJustification = nil; XCTAssertTrue(rawLayer->getTextJustify().isUndefined(), @@ -1320,7 +1293,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextLetterSpacing(), propertyValue, @"Setting textLetterSpacing to a camera expression should update text-letter-spacing."); XCTAssertEqualObjects(layer.textLetterSpacing, functionExpression, @@ -1349,7 +1322,6 @@ @"Setting textLetterSpacing to a camera-data expression should update text-letter-spacing."); XCTAssertEqualObjects(layer.textLetterSpacing, functionExpression, @"textLetterSpacing should round-trip camera-data expressions."); - layer.textLetterSpacing = nil; XCTAssertTrue(rawLayer->getTextLetterSpacing().isUndefined(), @@ -1381,13 +1353,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextLineHeight(), propertyValue, @"Setting textLineHeight to a camera expression should update text-line-height."); XCTAssertEqualObjects(layer.textLineHeight, functionExpression, @"textLineHeight should round-trip camera expressions."); - layer.textLineHeight = nil; XCTAssertTrue(rawLayer->getTextLineHeight().isUndefined(), @@ -1431,7 +1402,7 @@ { 18, { 1, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<std::array<float, 2>> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextOffset(), propertyValue, @"Setting textOffset to a camera expression should update text-offset."); XCTAssertEqualObjects(layer.textOffset, functionExpression, @@ -1460,7 +1431,6 @@ @"Setting textOffset to a camera-data expression should update text-offset."); XCTAssertEqualObjects(layer.textOffset, functionExpression, @"textOffset should round-trip camera-data expressions."); - layer.textOffset = nil; XCTAssertTrue(rawLayer->getTextOffset().isUndefined(), @@ -1492,13 +1462,12 @@ { 18, true }, }}; propertyValue = mbgl::style::CameraFunction<bool> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextOptional(), propertyValue, @"Setting textOptional to a camera expression should update text-optional."); XCTAssertEqualObjects(layer.textOptional, functionExpression, @"textOptional should round-trip camera expressions."); - layer.textOptional = nil; XCTAssertTrue(rawLayer->getTextOptional().isUndefined(), @@ -1536,13 +1505,12 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextPadding(), propertyValue, @"Setting textPadding to a camera expression should update text-padding."); XCTAssertEqualObjects(layer.textPadding, functionExpression, @"textPadding should round-trip camera expressions."); - layer.textPadding = nil; XCTAssertTrue(rawLayer->getTextPadding().isUndefined(), @@ -1580,13 +1548,12 @@ { 18, mbgl::style::AlignmentType::Auto }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::AlignmentType> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextPitchAlignment(), propertyValue, @"Setting textPitchAlignment to a camera expression should update text-pitch-alignment."); XCTAssertEqualObjects(layer.textPitchAlignment, functionExpression, @"textPitchAlignment should round-trip camera expressions."); - layer.textPitchAlignment = nil; XCTAssertTrue(rawLayer->getTextPitchAlignment().isUndefined(), @@ -1624,7 +1591,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextRotate(), propertyValue, @"Setting textRotation to a camera expression should update text-rotate."); XCTAssertEqualObjects(layer.textRotation, functionExpression, @@ -1653,7 +1620,6 @@ @"Setting textRotation to a camera-data expression should update text-rotate."); XCTAssertEqualObjects(layer.textRotation, functionExpression, @"textRotation should round-trip camera-data expressions."); - layer.textRotation = nil; XCTAssertTrue(rawLayer->getTextRotate().isUndefined(), @@ -1685,13 +1651,12 @@ { 18, mbgl::style::AlignmentType::Auto }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::AlignmentType> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextRotationAlignment(), propertyValue, @"Setting textRotationAlignment to a camera expression should update text-rotation-alignment."); XCTAssertEqualObjects(layer.textRotationAlignment, functionExpression, @"textRotationAlignment should round-trip camera expressions."); - layer.textRotationAlignment = nil; XCTAssertTrue(rawLayer->getTextRotationAlignment().isUndefined(), @@ -1729,13 +1694,12 @@ { 18, mbgl::style::TextTransformType::Lowercase }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::TextTransformType> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextTransform(), propertyValue, @"Setting textTransform to a camera expression should update text-transform."); XCTAssertEqualObjects(layer.textTransform, functionExpression, @"textTransform should round-trip camera expressions."); - layer.textTransform = nil; XCTAssertTrue(rawLayer->getTextTransform().isUndefined(), @@ -1767,7 +1731,7 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconColor(), propertyValue, @"Setting iconColor to a camera expression should update icon-color."); XCTAssertEqualObjects(layer.iconColor, functionExpression, @@ -1796,7 +1760,6 @@ @"Setting iconColor to a camera-data expression should update icon-color."); XCTAssertEqualObjects(layer.iconColor, functionExpression, @"iconColor should round-trip camera-data expressions."); - layer.iconColor = nil; XCTAssertTrue(rawLayer->getIconColor().isUndefined(), @@ -1837,7 +1800,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconHaloBlur(), propertyValue, @"Setting iconHaloBlur to a camera expression should update icon-halo-blur."); XCTAssertEqualObjects(layer.iconHaloBlur, functionExpression, @@ -1866,7 +1829,6 @@ @"Setting iconHaloBlur to a camera-data expression should update icon-halo-blur."); XCTAssertEqualObjects(layer.iconHaloBlur, functionExpression, @"iconHaloBlur should round-trip camera-data expressions."); - layer.iconHaloBlur = nil; XCTAssertTrue(rawLayer->getIconHaloBlur().isUndefined(), @@ -1907,7 +1869,7 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconHaloColor(), propertyValue, @"Setting iconHaloColor to a camera expression should update icon-halo-color."); XCTAssertEqualObjects(layer.iconHaloColor, functionExpression, @@ -1936,7 +1898,6 @@ @"Setting iconHaloColor to a camera-data expression should update icon-halo-color."); XCTAssertEqualObjects(layer.iconHaloColor, functionExpression, @"iconHaloColor should round-trip camera-data expressions."); - layer.iconHaloColor = nil; XCTAssertTrue(rawLayer->getIconHaloColor().isUndefined(), @@ -1977,7 +1938,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconHaloWidth(), propertyValue, @"Setting iconHaloWidth to a camera expression should update icon-halo-width."); XCTAssertEqualObjects(layer.iconHaloWidth, functionExpression, @@ -2006,7 +1967,6 @@ @"Setting iconHaloWidth to a camera-data expression should update icon-halo-width."); XCTAssertEqualObjects(layer.iconHaloWidth, functionExpression, @"iconHaloWidth should round-trip camera-data expressions."); - layer.iconHaloWidth = nil; XCTAssertTrue(rawLayer->getIconHaloWidth().isUndefined(), @@ -2047,7 +2007,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconOpacity(), propertyValue, @"Setting iconOpacity to a camera expression should update icon-opacity."); XCTAssertEqualObjects(layer.iconOpacity, functionExpression, @@ -2076,7 +2036,6 @@ @"Setting iconOpacity to a camera-data expression should update icon-opacity."); XCTAssertEqualObjects(layer.iconOpacity, functionExpression, @"iconOpacity should round-trip camera-data expressions."); - layer.iconOpacity = nil; XCTAssertTrue(rawLayer->getIconOpacity().isUndefined(), @@ -2123,13 +2082,12 @@ { 18, { 1, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<std::array<float, 2>> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconTranslate(), propertyValue, @"Setting iconTranslation to a camera expression should update icon-translate."); XCTAssertEqualObjects(layer.iconTranslation, functionExpression, @"iconTranslation should round-trip camera expressions."); - layer.iconTranslation = nil; XCTAssertTrue(rawLayer->getIconTranslate().isUndefined(), @@ -2167,13 +2125,12 @@ { 18, mbgl::style::TranslateAnchorType::Viewport }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::TranslateAnchorType> { intervalStops }; - + XCTAssertEqual(rawLayer->getIconTranslateAnchor(), propertyValue, @"Setting iconTranslationAnchor to a camera expression should update icon-translate-anchor."); XCTAssertEqualObjects(layer.iconTranslationAnchor, functionExpression, @"iconTranslationAnchor should round-trip camera expressions."); - layer.iconTranslationAnchor = nil; XCTAssertTrue(rawLayer->getIconTranslateAnchor().isUndefined(), @@ -2211,7 +2168,7 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextColor(), propertyValue, @"Setting textColor to a camera expression should update text-color."); XCTAssertEqualObjects(layer.textColor, functionExpression, @@ -2240,7 +2197,6 @@ @"Setting textColor to a camera-data expression should update text-color."); XCTAssertEqualObjects(layer.textColor, functionExpression, @"textColor should round-trip camera-data expressions."); - layer.textColor = nil; XCTAssertTrue(rawLayer->getTextColor().isUndefined(), @@ -2281,7 +2237,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextHaloBlur(), propertyValue, @"Setting textHaloBlur to a camera expression should update text-halo-blur."); XCTAssertEqualObjects(layer.textHaloBlur, functionExpression, @@ -2310,7 +2266,6 @@ @"Setting textHaloBlur to a camera-data expression should update text-halo-blur."); XCTAssertEqualObjects(layer.textHaloBlur, functionExpression, @"textHaloBlur should round-trip camera-data expressions."); - layer.textHaloBlur = nil; XCTAssertTrue(rawLayer->getTextHaloBlur().isUndefined(), @@ -2351,7 +2306,7 @@ { 18, { 1, 0, 0, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextHaloColor(), propertyValue, @"Setting textHaloColor to a camera expression should update text-halo-color."); XCTAssertEqualObjects(layer.textHaloColor, functionExpression, @@ -2380,7 +2335,6 @@ @"Setting textHaloColor to a camera-data expression should update text-halo-color."); XCTAssertEqualObjects(layer.textHaloColor, functionExpression, @"textHaloColor should round-trip camera-data expressions."); - layer.textHaloColor = nil; XCTAssertTrue(rawLayer->getTextHaloColor().isUndefined(), @@ -2421,7 +2375,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextHaloWidth(), propertyValue, @"Setting textHaloWidth to a camera expression should update text-halo-width."); XCTAssertEqualObjects(layer.textHaloWidth, functionExpression, @@ -2450,7 +2404,6 @@ @"Setting textHaloWidth to a camera-data expression should update text-halo-width."); XCTAssertEqualObjects(layer.textHaloWidth, functionExpression, @"textHaloWidth should round-trip camera-data expressions."); - layer.textHaloWidth = nil; XCTAssertTrue(rawLayer->getTextHaloWidth().isUndefined(), @@ -2491,7 +2444,7 @@ { 18, 0xff }, }}; propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextOpacity(), propertyValue, @"Setting textOpacity to a camera expression should update text-opacity."); XCTAssertEqualObjects(layer.textOpacity, functionExpression, @@ -2520,7 +2473,6 @@ @"Setting textOpacity to a camera-data expression should update text-opacity."); XCTAssertEqualObjects(layer.textOpacity, functionExpression, @"textOpacity should round-trip camera-data expressions."); - layer.textOpacity = nil; XCTAssertTrue(rawLayer->getTextOpacity().isUndefined(), @@ -2567,13 +2519,12 @@ { 18, { 1, 1 } }, }}; propertyValue = mbgl::style::CameraFunction<std::array<float, 2>> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextTranslate(), propertyValue, @"Setting textTranslation to a camera expression should update text-translate."); XCTAssertEqualObjects(layer.textTranslation, functionExpression, @"textTranslation should round-trip camera expressions."); - layer.textTranslation = nil; XCTAssertTrue(rawLayer->getTextTranslate().isUndefined(), @@ -2611,13 +2562,12 @@ { 18, mbgl::style::TranslateAnchorType::Viewport }, }}; propertyValue = mbgl::style::CameraFunction<mbgl::style::TranslateAnchorType> { intervalStops }; - + XCTAssertEqual(rawLayer->getTextTranslateAnchor(), propertyValue, @"Setting textTranslationAnchor to a camera expression should update text-translate-anchor."); XCTAssertEqualObjects(layer.textTranslationAnchor, functionExpression, @"textTranslationAnchor should round-trip camera expressions."); - layer.textTranslationAnchor = nil; XCTAssertTrue(rawLayer->getTextTranslateAnchor().isUndefined(), diff --git a/scripts/generate-style-code.js b/scripts/generate-style-code.js index 6ddb787f19..82b5a138b7 100755 --- a/scripts/generate-style-code.js +++ b/scripts/generate-style-code.js @@ -97,8 +97,8 @@ global.paintPropertyType = function (property, type) { global.propertyValueType = function (property) { if (isDataDriven(property)) { return `DataDrivenPropertyValue<${evaluatedType(property)}>`; - } else if (property.name === 'heatmap-color') { - return `HeatmapColorPropertyValue`; + } else if (property.name === 'heatmap-color' || property.name === 'line-gradient') { + return `ColorRampPropertyValue`; } else { return `PropertyValue<${evaluatedType(property)}>`; } @@ -114,7 +114,7 @@ global.defaultValue = function (property) { return '{}'; } - if (property.name === 'heatmap-color') { + if (property.name === 'heatmap-color' || property.name === 'line-gradient') { return '{}'; } diff --git a/src/mbgl/programs/line_program.cpp b/src/mbgl/programs/line_program.cpp index faf57ef19b..3c4124e9f4 100644 --- a/src/mbgl/programs/line_program.cpp +++ b/src/mbgl/programs/line_program.cpp @@ -44,6 +44,20 @@ LineProgram::uniformValues(const RenderLinePaintProperties::PossiblyEvaluated& p ); } +LineGradientProgram::UniformValues +LineGradientProgram::uniformValues(const RenderLinePaintProperties::PossiblyEvaluated& properties, + const RenderTile& tile, + const TransformState& state, + const std::array<float, 2>& pixelsToGLUnits) { + return makeValues<LineGradientProgram::UniformValues>( + properties, + tile, + state, + pixelsToGLUnits, + uniforms::u_image::Value{ 0 } + ); +} + LineSDFProgram::UniformValues LineSDFProgram::uniformValues(const RenderLinePaintProperties::PossiblyEvaluated& properties, float pixelRatio, diff --git a/src/mbgl/programs/line_program.hpp b/src/mbgl/programs/line_program.hpp index da9964e623..c07176fa44 100644 --- a/src/mbgl/programs/line_program.hpp +++ b/src/mbgl/programs/line_program.hpp @@ -4,6 +4,7 @@ #include <mbgl/programs/attributes.hpp> #include <mbgl/programs/uniforms.hpp> #include <mbgl/shaders/line.hpp> +#include <mbgl/shaders/line_gradient.hpp> #include <mbgl/shaders/line_pattern.hpp> #include <mbgl/shaders/line_sdf.hpp> #include <mbgl/util/geometry.hpp> @@ -98,6 +99,26 @@ public: const std::array<float, 2>& pixelsToGLUnits); }; +class LineGradientProgram : public Program< + shaders::line_gradient, + gl::Triangle, + LineLayoutAttributes, + gl::Uniforms< + uniforms::u_matrix, + uniforms::u_ratio, + uniforms::u_gl_units_to_pixels, + uniforms::u_image>, + RenderLinePaintProperties> +{ +public: + using Program::Program; + + static UniformValues uniformValues(const RenderLinePaintProperties::PossiblyEvaluated&, + const RenderTile&, + const TransformState&, + const std::array<float, 2>& pixelsToGLUnits); +}; + class LinePatternProgram : public Program< shaders::line_pattern, gl::Triangle, diff --git a/src/mbgl/programs/programs.hpp b/src/mbgl/programs/programs.hpp index 4bb23455e8..6c9802ab4b 100644 --- a/src/mbgl/programs/programs.hpp +++ b/src/mbgl/programs/programs.hpp @@ -37,6 +37,7 @@ public: hillshade(context, programParameters), hillshadePrepare(context, programParameters), line(context, programParameters), + lineGradient(context, programParameters), lineSDF(context, programParameters), linePattern(context, programParameters), raster(context, programParameters), @@ -64,6 +65,7 @@ public: HillshadeProgram hillshade; HillshadePrepareProgram hillshadePrepare; ProgramMap<LineProgram> line; + ProgramMap<LineGradientProgram> lineGradient; ProgramMap<LineSDFProgram> lineSDF; ProgramMap<LinePatternProgram> linePattern; RasterProgram raster; diff --git a/src/mbgl/renderer/buckets/line_bucket.cpp b/src/mbgl/renderer/buckets/line_bucket.cpp index a96518df38..248e0a235d 100644 --- a/src/mbgl/renderer/buckets/line_bucket.cpp +++ b/src/mbgl/renderer/buckets/line_bucket.cpp @@ -88,6 +88,16 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome return; } + const auto &props = feature.getProperties(); + optional<double> totalDistance; + optional<double> startDistance; + auto total_it = props.find("$distance_total"); + auto start_it = props.find("$distance_start"); + if (total_it != props.end() && start_it != props.end()) { + totalDistance = numericValue<double>(total_it->second); + startDistance = numericValue<double>(start_it->second); + } + const LineJoinType joinType = layout.evaluate<LineJoin>(zoom, feature); const float miterLimit = joinType == LineJoinType::Bevel ? 1.05f : float(layout.get<LineMiterLimit>()); @@ -190,7 +200,8 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome if (prevSegmentLength > 2.0 * sharpCornerOffset) { GeometryCoordinate newPrevVertex = *currentCoordinate - convertPoint<int16_t>(util::round(convertPoint<double>(*currentCoordinate - *prevCoordinate) * (sharpCornerOffset / prevSegmentLength))); distance += util::dist<double>(newPrevVertex, *prevCoordinate); - addCurrentVertex(newPrevVertex, distance, *prevNormal, 0, 0, false, startVertex, triangleStore); + addCurrentVertex(newPrevVertex, distance, *prevNormal, 0, 0, false, startVertex, + triangleStore, totalDistance, startDistance); prevCoordinate = newPrevVertex; } } @@ -235,7 +246,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome if (middleVertex && currentJoin == LineJoinType::Miter) { joinNormal = joinNormal * miterLength; addCurrentVertex(*currentCoordinate, distance, joinNormal, 0, 0, false, startVertex, - triangleStore); + triangleStore, totalDistance, startDistance); } else if (middleVertex && currentJoin == LineJoinType::FlipBevel) { // miter is too big, flip the direction to make a beveled join @@ -251,10 +262,10 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome } addCurrentVertex(*currentCoordinate, distance, joinNormal, 0, 0, false, startVertex, - triangleStore); + triangleStore, totalDistance, startDistance); addCurrentVertex(*currentCoordinate, distance, joinNormal * -1.0, 0, 0, false, startVertex, - triangleStore); + triangleStore, totalDistance, startDistance); } else if (middleVertex && (currentJoin == LineJoinType::Bevel || currentJoin == LineJoinType::FakeRound)) { const bool lineTurnsLeft = (prevNormal->x * nextNormal->y - prevNormal->y * nextNormal->x) > 0; const float offset = -std::sqrt(miterLength * miterLength - 1); @@ -272,7 +283,7 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome // Close previous segement with bevel if (!startOfLine) { addCurrentVertex(*currentCoordinate, distance, *prevNormal, offsetA, offsetB, false, - startVertex, triangleStore); + startVertex, triangleStore, totalDistance, startDistance); } if (currentJoin == LineJoinType::FakeRound) { @@ -287,41 +298,44 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome for (int m = 0; m < n; m++) { auto approxFractionalJoinNormal = util::unit(*nextNormal * ((m + 1.0) / (n + 1.0)) + *prevNormal); - addPieSliceVertex(*currentCoordinate, distance, approxFractionalJoinNormal, lineTurnsLeft, startVertex, triangleStore); + addPieSliceVertex(*currentCoordinate, distance, approxFractionalJoinNormal, lineTurnsLeft, + startVertex, triangleStore, totalDistance, startDistance); } - addPieSliceVertex(*currentCoordinate, distance, joinNormal, lineTurnsLeft, startVertex, triangleStore); + addPieSliceVertex(*currentCoordinate, distance, joinNormal, lineTurnsLeft, startVertex, + triangleStore, totalDistance, startDistance); for (int k = n - 1; k >= 0; k--) { auto approxFractionalJoinNormal = util::unit(*prevNormal * ((k + 1.0) / (n + 1.0)) + *nextNormal); - addPieSliceVertex(*currentCoordinate, distance, approxFractionalJoinNormal, lineTurnsLeft, startVertex, triangleStore); + addPieSliceVertex(*currentCoordinate, distance, approxFractionalJoinNormal, lineTurnsLeft, + startVertex, triangleStore, totalDistance, startDistance); } } // Start next segment if (nextCoordinate) { addCurrentVertex(*currentCoordinate, distance, *nextNormal, -offsetA, -offsetB, - false, startVertex, triangleStore); + false, startVertex, triangleStore, totalDistance, startDistance); } } else if (!middleVertex && currentCap == LineCapType::Butt) { if (!startOfLine) { // Close previous segment with a butt addCurrentVertex(*currentCoordinate, distance, *prevNormal, 0, 0, false, - startVertex, triangleStore); + startVertex, triangleStore, totalDistance, startDistance); } // Start next segment with a butt if (nextCoordinate) { addCurrentVertex(*currentCoordinate, distance, *nextNormal, 0, 0, false, - startVertex, triangleStore); + startVertex, triangleStore, totalDistance, startDistance); } } else if (!middleVertex && currentCap == LineCapType::Square) { if (!startOfLine) { // Close previous segment with a square cap addCurrentVertex(*currentCoordinate, distance, *prevNormal, 1, 1, false, - startVertex, triangleStore); + startVertex, triangleStore, totalDistance, startDistance); // The segment is done. Unset vertices to disconnect segments. e1 = e2 = -1; @@ -330,18 +344,18 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome // Start next segment if (nextCoordinate) { addCurrentVertex(*currentCoordinate, distance, *nextNormal, -1, -1, false, - startVertex, triangleStore); + startVertex, triangleStore, totalDistance, startDistance); } } else if (middleVertex ? currentJoin == LineJoinType::Round : currentCap == LineCapType::Round) { if (!startOfLine) { // Close previous segment with a butt addCurrentVertex(*currentCoordinate, distance, *prevNormal, 0, 0, false, - startVertex, triangleStore); + startVertex, triangleStore, totalDistance, startDistance); // Add round cap or linejoin at end of segment addCurrentVertex(*currentCoordinate, distance, *prevNormal, 1, 1, true, startVertex, - triangleStore); + triangleStore, totalDistance, startDistance); // The segment is done. Unset vertices to disconnect segments. e1 = e2 = -1; @@ -351,10 +365,10 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome if (nextCoordinate) { // Add round cap before first segment addCurrentVertex(*currentCoordinate, distance, *nextNormal, -1, -1, true, - startVertex, triangleStore); + startVertex, triangleStore, totalDistance, startDistance); addCurrentVertex(*currentCoordinate, distance, *nextNormal, 0, 0, false, - startVertex, triangleStore); + startVertex, triangleStore, totalDistance, startDistance); } } @@ -363,7 +377,8 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome if (nextSegmentLength > 2 * sharpCornerOffset) { GeometryCoordinate newCurrentVertex = *currentCoordinate + convertPoint<int16_t>(util::round(convertPoint<double>(*nextCoordinate - *currentCoordinate) * (sharpCornerOffset / nextSegmentLength))); distance += util::dist<double>(newCurrentVertex, *currentCoordinate); - addCurrentVertex(newCurrentVertex, distance, *nextNormal, 0, 0, false, startVertex, triangleStore); + addCurrentVertex(newCurrentVertex, distance, *nextNormal, 0, 0, false, startVertex, + triangleStore, totalDistance, startDistance); currentCoordinate = newCurrentVertex; } } @@ -391,14 +406,27 @@ void LineBucket::addGeometry(const GeometryCoordinates& coordinates, const Geome } void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate, - double &distance, + double distance, const Point<double>& normal, double endLeft, double endRight, bool round, std::size_t startVertex, - std::vector<TriangleElement>& triangleStore) { + std::vector<TriangleElement>& triangleStore, + optional<double> totalDistance, + optional<double> startDistance) { Point<double> extrude = normal; + if (totalDistance && startDistance) { + // First scale line from tile units to [0, 2^15) + distance = scaleDistance(distance, *totalDistance, *startDistance); + // Check to see if this vertex is going to be drawn across an edge, + // and if so, don't add square/round caps: + if (shouldClipAtEdge(currentCoordinate, distance)) { + endLeft = 0.; + endRight = 0.; + round = false; + } + } if (endLeft) extrude = extrude - (util::perp(normal) * endLeft); vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, round, false, endLeft, distance * LINE_DISTANCE_SCALE)); @@ -424,9 +452,10 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate, // When we get close to the distance, reset it to zero and add the vertex again with // a distance of zero. The max distance is determined by the number of bits we allocate // to `linesofar`. - if (distance > MAX_LINE_DISTANCE / 2.0f) { + if (distance > MAX_LINE_DISTANCE / 2.0f && !totalDistance && !startDistance) { distance = 0; - addCurrentVertex(currentCoordinate, distance, normal, endLeft, endRight, round, startVertex, triangleStore); + addCurrentVertex(currentCoordinate, distance, normal, endLeft, endRight, round, startVertex, + triangleStore, totalDistance, startDistance); } } @@ -435,8 +464,13 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex, const Point<double>& extrude, bool lineTurnsLeft, std::size_t startVertex, - std::vector<TriangleElement>& triangleStore) { + std::vector<TriangleElement>& triangleStore, + optional<double> totalDistance, + optional<double> startDistance) { Point<double> flippedExtrude = extrude * (lineTurnsLeft ? -1.0 : 1.0); + if (totalDistance && startDistance) { + distance = scaleDistance(distance, *totalDistance, *startDistance); + } vertices.emplace_back(LineProgram::layoutVertex(currentVertex, flippedExtrude, false, lineTurnsLeft, 0, distance * LINE_DISTANCE_SCALE)); e3 = vertices.vertexSize() - 1 - startVertex; if (e1 >= 0 && e2 >= 0) { @@ -465,6 +499,19 @@ bool LineBucket::hasData() const { return !segments.empty(); } +double LineBucket::scaleDistance(double tileDistance, double totalDistance, double startDistance) const { + return (startDistance + tileDistance) * ((MAX_LINE_DISTANCE - 1) / totalDistance); +} + +bool LineBucket::shouldClipAtEdge(const GeometryCoordinate& vertex, double vertexDistance) const { + // We detect non-start/end tile edge vertices for gradient lines because + // we turn clipping off when there's no tile buffer (which we do in + // order to calcuate line distances correctly), and turn these into butt + // ends so they won't overlap with semitransparent neighbors. + if (vertexDistance == 0 || vertexDistance == MAX_LINE_DISTANCE - 1) return false; + return vertex.x == 0 || vertex.x == util::EXTENT || vertex.y == 0 || vertex.y == util::EXTENT; +} + template <class Property> static float get(const RenderLineLayer& layer, const std::map<std::string, LineProgram::PaintPropertyBinders>& paintPropertyBinders) { auto it = paintPropertyBinders.find(layer.getID()); diff --git a/src/mbgl/renderer/buckets/line_bucket.hpp b/src/mbgl/renderer/buckets/line_bucket.hpp index 4fb77c377e..6f1b3b20c4 100644 --- a/src/mbgl/renderer/buckets/line_bucket.hpp +++ b/src/mbgl/renderer/buckets/line_bucket.hpp @@ -47,12 +47,17 @@ private: TriangleElement(uint16_t a_, uint16_t b_, uint16_t c_) : a(a_), b(b_), c(c_) {} uint16_t a, b, c; }; - void addCurrentVertex(const GeometryCoordinate& currentVertex, double& distance, + void addCurrentVertex(const GeometryCoordinate& currentVertex, double distance, const Point<double>& normal, double endLeft, double endRight, bool round, - std::size_t startVertex, std::vector<LineBucket::TriangleElement>& triangleStore); + std::size_t startVertex, std::vector<LineBucket::TriangleElement>& triangleStore, + optional<double> totalDistance, optional<double> startDistance); void addPieSliceVertex(const GeometryCoordinate& currentVertex, double distance, const Point<double>& extrude, bool lineTurnsLeft, std::size_t startVertex, - std::vector<TriangleElement>& triangleStore); + std::vector<TriangleElement>& triangleStore, + optional<double> totalDistance, optional<double> startDistance); + + double scaleDistance(double, double, double) const; + bool shouldClipAtEdge(const GeometryCoordinate&, double) const; std::ptrdiff_t e1; std::ptrdiff_t e2; diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index 1b4a1c0ff7..04d300dd1f 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -18,7 +18,7 @@ using namespace style; RenderLineLayer::RenderLineLayer(Immutable<style::LineLayer::Impl> _impl) : RenderLayer(style::LayerType::Line, _impl), - unevaluated(impl().paint.untransitioned()) { + unevaluated(impl().paint.untransitioned()), colorRamp({256, 1}) { } const style::LineLayer::Impl& RenderLineLayer::impl() const { @@ -61,12 +61,12 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { assert(dynamic_cast<LineBucket*>(tile.tile.getBucket(*baseImpl))); LineBucket& bucket = *reinterpret_cast<LineBucket*>(tile.tile.getBucket(*baseImpl)); - auto draw = [&] (auto& program, auto&& uniformValues) { + auto draw = [&] (auto& program, const auto& stencilMode, auto&& uniformValues) { program.get(evaluated).draw( parameters.context, gl::Triangles(), parameters.depthModeForSublayer(0, gl::DepthMode::ReadOnly), - parameters.stencilModeForClipping(tile.clip), + stencilMode, parameters.colorModeForRenderPass(), std::move(uniformValues), *bucket.vertexBuffer, @@ -88,6 +88,7 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { parameters.lineAtlas.bind(parameters.context, 0); draw(parameters.programs.lineSDF, + parameters.stencilModeForClipping(tile.clip), LineSDFProgram::uniformValues( evaluated, parameters.pixelRatio, @@ -108,6 +109,7 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { parameters.imageManager.bind(parameters.context, 0); draw(parameters.programs.linePattern, + parameters.stencilModeForClipping(tile.clip), LinePatternProgram::uniformValues( evaluated, tile, @@ -117,8 +119,22 @@ void RenderLineLayer::render(PaintParameters& parameters, RenderSource*) { *posA, *posB)); + } else if (!unevaluated.get<LineGradient>().getValue().isUndefined()) { + if (!colorRampTexture) { + colorRampTexture = parameters.context.createTexture(colorRamp); + } + + draw(parameters.programs.lineGradient, + gl::StencilMode::disabled(), + LineGradientProgram::uniformValues( + evaluated, + tile, + parameters.state, + parameters.pixelsToGLUnits)); + } else { draw(parameters.programs.line, + parameters.stencilModeForClipping(tile.clip), LineProgram::uniformValues( evaluated, tile, @@ -158,6 +174,27 @@ optional<GeometryCollection> offsetLine(const GeometryCollection& rings, const d return newRings; } +void RenderLineLayer::updateColorRamp() { + auto colorValue = unevaluated.get<LineGradient>().getValue(); + if (colorValue.isUndefined()) { + return; + } + + const auto length = colorRamp.bytes(); + + for (uint32_t i = 0; i < length; i += 4) { + const auto color = colorValue.evaluate(static_cast<double>(i) / length); + colorRamp.data[i + 0] = std::floor(color.r * 255); + colorRamp.data[i + 1] = std::floor(color.g * 255); + colorRamp.data[i + 2] = std::floor(color.b * 255); + colorRamp.data[i + 3] = std::floor(color.a * 255); + } + + if (colorRampTexture) { + colorRampTexture = nullopt; + } +} + bool RenderLineLayer::queryIntersectsFeature( const GeometryCoordinates& queryGeometry, const GeometryTileFeature& feature, diff --git a/src/mbgl/renderer/layers/render_line_layer.hpp b/src/mbgl/renderer/layers/render_line_layer.hpp index 8bf7e2329d..59333f0404 100644 --- a/src/mbgl/renderer/layers/render_line_layer.hpp +++ b/src/mbgl/renderer/layers/render_line_layer.hpp @@ -4,6 +4,7 @@ #include <mbgl/style/layers/line_layer_impl.hpp> #include <mbgl/style/layers/line_layer_properties.hpp> #include <mbgl/programs/uniforms.hpp> +#include <mbgl/util/image.hpp> namespace mbgl { @@ -32,6 +33,8 @@ public: const float, const float) const override; + void updateColorRamp(); + std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; // Paint properties @@ -40,6 +43,9 @@ public: const style::LineLayer::Impl& impl() const; + PremultipliedImage colorRamp; + optional<gl::Texture> colorRampTexture; + private: float getLineWidth(const GeometryTileFeature&, const float) const; }; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 627a592d81..8f74e43f42 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -190,6 +190,10 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { if (layer.is<RenderHeatmapLayer>()) { layer.as<RenderHeatmapLayer>()->updateColorRamp(); } + + if (layer.is<RenderLineLayer>()) { + layer.as<RenderLineLayer>()->updateColorRamp(); + } } if (layerAdded || layerChanged || zoomChanged || layer.hasTransition()) { diff --git a/src/mbgl/shaders/collision_circle.cpp b/src/mbgl/shaders/collision_circle.cpp index 82ebbf05a0..f220586245 100644 --- a/src/mbgl/shaders/collision_circle.cpp +++ b/src/mbgl/shaders/collision_circle.cpp @@ -26,10 +26,7 @@ varying vec2 v_extrude_scale; void main() { vec4 projectedPoint = u_matrix * vec4(a_anchor_pos, 0, 1); highp float camera_to_anchor_distance = projectedPoint.w; - highp float collision_perspective_ratio = clamp( - 0.5 + 0.5 * (u_camera_to_center_distance / camera_to_anchor_distance), - 0.0, // Prevents oversized near-field circles in pitched/overzoomed tiles - 4.0); + highp float collision_perspective_ratio = 0.5 + 0.5 * (u_camera_to_center_distance / camera_to_anchor_distance); gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0); @@ -46,7 +43,6 @@ void main() { )MBGL_SHADER"; const char* collision_circle::fragmentSource = R"MBGL_SHADER( -uniform float u_overscale_factor; varying float v_placed; varying float v_notUsed; @@ -72,7 +68,7 @@ void main() { float extrude_scale_length = length(v_extrude_scale); float extrude_length = length(v_extrude) * extrude_scale_length; - float stroke_width = 15.0 * extrude_scale_length / u_overscale_factor; + float stroke_width = 15.0 * extrude_scale_length; float radius = v_radius * extrude_scale_length; float distance_to_edge = abs(extrude_length - radius); diff --git a/src/mbgl/shaders/line.cpp b/src/mbgl/shaders/line.cpp index c700295a15..98ca2f4f1b 100644 --- a/src/mbgl/shaders/line.cpp +++ b/src/mbgl/shaders/line.cpp @@ -31,6 +31,7 @@ uniform vec2 u_gl_units_to_pixels; varying vec2 v_normal; varying vec2 v_width2; varying float v_gamma_scale; +varying float v_linesofar; #ifndef HAS_UNIFORM_u_color @@ -131,6 +132,8 @@ void main() { vec2 a_extrude = a_data.xy - 128.0; float a_direction = mod(a_data.z, 4.0) - 1.0; + v_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * 2.0; + vec2 pos = a_pos_normal.xy; // x is 1 if it's a round cap, 0 otherwise diff --git a/src/mbgl/shaders/line_gradient.cpp b/src/mbgl/shaders/line_gradient.cpp new file mode 100644 index 0000000000..08e59a0d96 --- /dev/null +++ b/src/mbgl/shaders/line_gradient.cpp @@ -0,0 +1,249 @@ +// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. + +#include <mbgl/shaders/line_gradient.hpp> + +namespace mbgl { +namespace shaders { + +const char* line_gradient::name = "line_gradient"; +const char* line_gradient::vertexSource = R"MBGL_SHADER( + + +// the distance over which the line edge fades out. +// Retina devices need a smaller distance to avoid aliasing. +#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0 + +// floor(127 / 2) == 63.0 +// the maximum allowed miter limit is 2.0 at the moment. the extrude normal is +// stored in a byte (-128..127). we scale regular normals up to length 63, but +// there are also "special" normals that have a bigger length (of up to 126 in +// this case). +// #define scale 63.0 +#define scale 0.015873016 + +attribute vec4 a_pos_normal; +attribute vec4 a_data; + +uniform mat4 u_matrix; +uniform mediump float u_ratio; +uniform vec2 u_gl_units_to_pixels; + +varying vec2 v_normal; +varying vec2 v_width2; +varying float v_gamma_scale; +varying float v_linesofar; + + +#ifndef HAS_UNIFORM_u_color +uniform lowp float a_color_t; +attribute highp vec4 a_color; +varying highp vec4 color; +#else +uniform highp vec4 u_color; +#endif + + +#ifndef HAS_UNIFORM_u_blur +uniform lowp float a_blur_t; +attribute lowp vec2 a_blur; +varying lowp float blur; +#else +uniform lowp float u_blur; +#endif + + +#ifndef HAS_UNIFORM_u_opacity +uniform lowp float a_opacity_t; +attribute lowp vec2 a_opacity; +varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif + + +#ifndef HAS_UNIFORM_u_gapwidth +uniform lowp float a_gapwidth_t; +attribute mediump vec2 a_gapwidth; +#else +uniform mediump float u_gapwidth; +#endif + + +#ifndef HAS_UNIFORM_u_offset +uniform lowp float a_offset_t; +attribute lowp vec2 a_offset; +#else +uniform lowp float u_offset; +#endif + + +#ifndef HAS_UNIFORM_u_width +uniform lowp float a_width_t; +attribute mediump vec2 a_width; +#else +uniform mediump float u_width; +#endif + + +void main() { + +#ifndef HAS_UNIFORM_u_color + color = unpack_mix_vec4(a_color, a_color_t); +#else + highp vec4 color = u_color; +#endif + + +#ifndef HAS_UNIFORM_u_blur + blur = unpack_mix_vec2(a_blur, a_blur_t); +#else + lowp float blur = u_blur; +#endif + + +#ifndef HAS_UNIFORM_u_opacity + opacity = unpack_mix_vec2(a_opacity, a_opacity_t); +#else + lowp float opacity = u_opacity; +#endif + + +#ifndef HAS_UNIFORM_u_gapwidth + mediump float gapwidth = unpack_mix_vec2(a_gapwidth, a_gapwidth_t); +#else + mediump float gapwidth = u_gapwidth; +#endif + + +#ifndef HAS_UNIFORM_u_offset + lowp float offset = unpack_mix_vec2(a_offset, a_offset_t); +#else + lowp float offset = u_offset; +#endif + + +#ifndef HAS_UNIFORM_u_width + mediump float width = unpack_mix_vec2(a_width, a_width_t); +#else + mediump float width = u_width; +#endif + + + vec2 a_extrude = a_data.xy - 128.0; + float a_direction = mod(a_data.z, 4.0) - 1.0; + + v_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * 2.0; + + vec2 pos = a_pos_normal.xy; + + // x is 1 if it's a round cap, 0 otherwise + // y is 1 if the normal points up, and -1 if it points down + mediump vec2 normal = a_pos_normal.zw; + v_normal = normal; + + // these transformations used to be applied in the JS and native code bases. + // moved them into the shader for clarity and simplicity. + gapwidth = gapwidth / 2.0; + float halfwidth = width / 2.0; + offset = -1.0 * offset; + + float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0); + float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING; + + // Scale the extrusion vector down to a normal and then up by the line width + // of this vertex. + mediump vec2 dist = outset * a_extrude * scale; + + // Calculate the offset when drawing a line that is to the side of the actual line. + // We do this by creating a vector that points towards the extrude, but rotate + // it when we're drawing round end points (a_direction = -1 or 1) since their + // extrude vector points in another direction. + mediump float u = 0.5 * a_direction; + mediump float t = 1.0 - abs(u); + mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t); + + vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); + gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; + + // calculate how much the perspective view squishes or stretches the extrude + float extrude_length_without_perspective = length(dist); + float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_gl_units_to_pixels); + v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective; + + v_width2 = vec2(outset, inset); +} + +)MBGL_SHADER"; +const char* line_gradient::fragmentSource = R"MBGL_SHADER( +#define MAX_LINE_DISTANCE 32767.0 + + +#ifndef HAS_UNIFORM_u_color +varying highp vec4 color; +#else +uniform highp vec4 u_color; +#endif + + +#ifndef HAS_UNIFORM_u_blur +varying lowp float blur; +#else +uniform lowp float u_blur; +#endif + + +#ifndef HAS_UNIFORM_u_opacity +varying lowp float opacity; +#else +uniform lowp float u_opacity; +#endif + + +uniform sampler2D u_image; + +varying vec2 v_width2; +varying vec2 v_normal; +varying float v_gamma_scale; +varying float v_linesofar; + +void main() { + +#ifdef HAS_UNIFORM_u_color + highp vec4 color = u_color; +#endif + + +#ifdef HAS_UNIFORM_u_blur + lowp float blur = u_blur; +#endif + + +#ifdef HAS_UNIFORM_u_opacity + lowp float opacity = u_opacity; +#endif + + + // Calculate the distance of the pixel from the line in pixels. + float dist = length(v_normal) * v_width2.s; + + // Calculate the antialiasing fade factor. This is either when fading in + // the line in case of an offset line (v_width2.t) or when fading out + // (v_width2.s) + float blur2 = (blur + 1.0 / DEVICE_PIXEL_RATIO) * v_gamma_scale; + float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0); + + // For gradient lines, v_linesofar is the ratio along the entire line, + // scaled to [0, 2^15), and the gradient ramp is stored in a texture. + color = texture2D(u_image, vec2(v_linesofar / MAX_LINE_DISTANCE, 0.5)); + + gl_FragColor = color * (alpha * opacity); + +#ifdef OVERDRAW_INSPECTOR + gl_FragColor = vec4(1.0); +#endif +} + +)MBGL_SHADER"; + +} // namespace shaders +} // namespace mbgl diff --git a/src/mbgl/shaders/line_gradient.hpp b/src/mbgl/shaders/line_gradient.hpp new file mode 100644 index 0000000000..87a9d6d38c --- /dev/null +++ b/src/mbgl/shaders/line_gradient.hpp @@ -0,0 +1,16 @@ +// NOTE: DO NOT CHANGE THIS FILE. IT IS AUTOMATICALLY GENERATED. + +#pragma once + +namespace mbgl { +namespace shaders { + +class line_gradient { +public: + static const char* name; + static const char* vertexSource; + static const char* fragmentSource; +}; + +} // namespace shaders +} // namespace mbgl diff --git a/src/mbgl/style/conversion/make_property_setters.hpp b/src/mbgl/style/conversion/make_property_setters.hpp index 25c8fdb1ca..c3e6da75aa 100644 --- a/src/mbgl/style/conversion/make_property_setters.hpp +++ b/src/mbgl/style/conversion/make_property_setters.hpp @@ -115,6 +115,8 @@ inline auto makePaintPropertySetters() { result["line-dasharray-transition"] = &setTransition<LineLayer, &LineLayer::setLineDasharrayTransition>; result["line-pattern"] = &setProperty<LineLayer, PropertyValue<std::string>, &LineLayer::setLinePattern>; result["line-pattern-transition"] = &setTransition<LineLayer, &LineLayer::setLinePatternTransition>; + result["line-gradient"] = &setProperty<LineLayer, ColorRampPropertyValue, &LineLayer::setLineGradient>; + result["line-gradient-transition"] = &setTransition<LineLayer, &LineLayer::setLineGradientTransition>; result["icon-opacity"] = &setProperty<SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconOpacity>; result["icon-opacity-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setIconOpacityTransition>; @@ -174,7 +176,7 @@ inline auto makePaintPropertySetters() { result["heatmap-weight-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapWeightTransition>; result["heatmap-intensity"] = &setProperty<HeatmapLayer, PropertyValue<float>, &HeatmapLayer::setHeatmapIntensity>; result["heatmap-intensity-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapIntensityTransition>; - result["heatmap-color"] = &setProperty<HeatmapLayer, HeatmapColorPropertyValue, &HeatmapLayer::setHeatmapColor>; + result["heatmap-color"] = &setProperty<HeatmapLayer, ColorRampPropertyValue, &HeatmapLayer::setHeatmapColor>; result["heatmap-color-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapColorTransition>; result["heatmap-opacity"] = &setProperty<HeatmapLayer, PropertyValue<float>, &HeatmapLayer::setHeatmapOpacity>; result["heatmap-opacity-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapOpacityTransition>; diff --git a/src/mbgl/style/conversion/property_setter.hpp b/src/mbgl/style/conversion/property_setter.hpp index e3716a18dc..ce2cd79b30 100644 --- a/src/mbgl/style/conversion/property_setter.hpp +++ b/src/mbgl/style/conversion/property_setter.hpp @@ -5,7 +5,7 @@ #include <mbgl/style/conversion/constant.hpp> #include <mbgl/style/conversion/property_value.hpp> #include <mbgl/style/conversion/data_driven_property_value.hpp> -#include <mbgl/style/conversion/heatmap_color_property_value.hpp> +#include <mbgl/style/conversion/color_ramp_property_value.hpp> #include <mbgl/style/conversion/transition_options.hpp> #include <string> diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp index 42cb655024..e346b49c2f 100644 --- a/src/mbgl/style/expression/compound_expression.cpp +++ b/src/mbgl/style/expression/compound_expression.cpp @@ -231,12 +231,21 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali }); define("heatmap-density", [](const EvaluationContext& params) -> Result<double> { - if (!params.heatmapDensity) { + if (!params.rampEvaluationParameter) { return EvaluationError { "The 'heatmap-density' expression is unavailable in the current evaluation context." }; } - return *(params.heatmapDensity); + return *(params.rampEvaluationParameter); + }); + + define("line-progress", [](const EvaluationContext& params) -> Result<double> { + if (!params.rampEvaluationParameter) { + return EvaluationError { + "The 'line-progress' expression is unavailable in the current evaluation context." + }; + } + return *(params.rampEvaluationParameter); }); define("has", [](const EvaluationContext& params, const std::string& key) -> Result<bool> { diff --git a/src/mbgl/style/expression/parsing_context.cpp b/src/mbgl/style/expression/parsing_context.cpp index 0215982209..1576c39164 100644 --- a/src/mbgl/style/expression/parsing_context.cpp +++ b/src/mbgl/style/expression/parsing_context.cpp @@ -52,7 +52,8 @@ bool isConstant(const Expression& expression) { } return isFeatureConstant(expression) && - isGlobalPropertyConstant(expression, std::array<std::string, 2>{{"zoom", "heatmap-density"}}); + isGlobalPropertyConstant(expression, std::array<std::string, 2>{{"zoom", "heatmap-density"}}) && + isGlobalPropertyConstant(expression, std::array<std::string, 2>{{"zoom", "line-progress"}}); } using namespace mbgl::style::conversion; diff --git a/src/mbgl/style/function/expression.cpp b/src/mbgl/style/function/expression.cpp index d9dbbfa1d3..0c3fb5304c 100644 --- a/src/mbgl/style/function/expression.cpp +++ b/src/mbgl/style/function/expression.cpp @@ -28,9 +28,9 @@ public: }; -EvaluationResult Expression::evaluate(optional<float> zoom, const Feature& feature, optional<double> heatmapDensity) const { +EvaluationResult Expression::evaluate(optional<float> zoom, const Feature& feature, optional<double> rampEvaluationParameter) const { GeoJSONFeature f(feature); - return this->evaluate(EvaluationContext(zoom, &f, heatmapDensity)); + return this->evaluate(EvaluationContext(zoom, &f, rampEvaluationParameter)); } } // namespace expression diff --git a/src/mbgl/style/layers/heatmap_layer.cpp b/src/mbgl/style/layers/heatmap_layer.cpp index 4989ff15f1..dcf85f2ed4 100644 --- a/src/mbgl/style/layers/heatmap_layer.cpp +++ b/src/mbgl/style/layers/heatmap_layer.cpp @@ -6,7 +6,7 @@ // for constructing default heatmap-color ramp expression from style JSON #include <mbgl/style/conversion.hpp> #include <mbgl/style/conversion/json.hpp> -#include <mbgl/style/conversion/heatmap_color_property_value.hpp> +#include <mbgl/style/conversion/color_ramp_property_value.hpp> namespace mbgl { namespace style { @@ -179,17 +179,17 @@ TransitionOptions HeatmapLayer::getHeatmapIntensityTransition() const { return impl().paint.template get<HeatmapIntensity>().options; } -HeatmapColorPropertyValue HeatmapLayer::getDefaultHeatmapColor() { +ColorRampPropertyValue HeatmapLayer::getDefaultHeatmapColor() { conversion::Error error; std::string rawValue = R"JSON(["interpolate",["linear"],["heatmap-density"],0,"rgba(0, 0, 255, 0)",0.1,"royalblue",0.3,"cyan",0.5,"lime",0.7,"yellow",1,"red"])JSON"; - return *conversion::convertJSON<HeatmapColorPropertyValue>(rawValue, error); + return *conversion::convertJSON<ColorRampPropertyValue>(rawValue, error); } -HeatmapColorPropertyValue HeatmapLayer::getHeatmapColor() const { +ColorRampPropertyValue HeatmapLayer::getHeatmapColor() const { return impl().paint.template get<HeatmapColor>().value; } -void HeatmapLayer::setHeatmapColor(HeatmapColorPropertyValue value) { +void HeatmapLayer::setHeatmapColor(ColorRampPropertyValue value) { if (value == getHeatmapColor()) return; auto impl_ = mutableImpl(); diff --git a/src/mbgl/style/layers/heatmap_layer_properties.hpp b/src/mbgl/style/layers/heatmap_layer_properties.hpp index f7afa5fbeb..70bc120184 100644 --- a/src/mbgl/style/layers/heatmap_layer_properties.hpp +++ b/src/mbgl/style/layers/heatmap_layer_properties.hpp @@ -24,6 +24,8 @@ struct HeatmapIntensity : PaintProperty<float> { static float defaultValue() { return 1; } }; +struct HeatmapColor : ColorRampProperty {}; + struct HeatmapOpacity : PaintProperty<float> { static float defaultValue() { return 1; } }; diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs index 657a7f5a8a..0d11b16a6d 100644 --- a/src/mbgl/style/layers/layer.cpp.ejs +++ b/src/mbgl/style/layers/layer.cpp.ejs @@ -12,7 +12,7 @@ // for constructing default heatmap-color ramp expression from style JSON #include <mbgl/style/conversion.hpp> #include <mbgl/style/conversion/json.hpp> -#include <mbgl/style/conversion/heatmap_color_property_value.hpp> +#include <mbgl/style/conversion/color_ramp_property_value.hpp> <% } -%> namespace mbgl { @@ -139,16 +139,18 @@ void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(<%- propertyV // Paint properties <% for (const property of paintProperties) { %> +<% if (property.name !== 'line-gradient') { -%> <%- propertyValueType(property) %> <%- camelize(type) %>Layer::getDefault<%- camelize(property.name) %>() { -<% if (property.name === 'heatmap-color') { -%> +<% if (property.name === 'heatmap-color') { -%> conversion::Error error; std::string rawValue = R"JSON(<%- JSON.stringify(property.default) %>)JSON"; return *conversion::convertJSON<<%- propertyValueType(property)%>>(rawValue, error); -<% } else { -%> +<% } else { -%> return { <%- defaultValue(property) %> }; -<% } -%> +<% } -%> } +<% } -%> <%- propertyValueType(property) %> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>() const { return impl().paint.template get<<%- camelize(property.name) %>>().value; } diff --git a/src/mbgl/style/layers/layer_properties.hpp.ejs b/src/mbgl/style/layers/layer_properties.hpp.ejs index 1bceb84960..58b0f6c569 100644 --- a/src/mbgl/style/layers/layer_properties.hpp.ejs +++ b/src/mbgl/style/layers/layer_properties.hpp.ejs @@ -25,10 +25,13 @@ struct <%- camelize(property.name) %> : <%- layoutPropertyType(property, type) % <% } -%> <% for (const property of paintProperties) { -%> -<% if (property.name === 'heatmap-color') continue; -%> +<% if (property.name === 'heatmap-color' || property.name === 'line-gradient') { -%> +struct <%- camelize(property.name) %> : ColorRampProperty {}; +<% } else { -%> struct <%- camelize(property.name) %> : <%- paintPropertyType(property, type) %> { static <%- evaluatedType(property) %> defaultValue() { return <%- defaultValue(property) %>; } }; +<% } -%> <% } -%> <% if (layoutProperties.length) { -%> diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp index 1c7f0d28ee..2d6bf5dd01 100644 --- a/src/mbgl/style/layers/line_layer.cpp +++ b/src/mbgl/style/layers/line_layer.cpp @@ -429,5 +429,28 @@ TransitionOptions LineLayer::getLinePatternTransition() const { return impl().paint.template get<LinePattern>().options; } +ColorRampPropertyValue LineLayer::getLineGradient() const { + return impl().paint.template get<LineGradient>().value; +} + +void LineLayer::setLineGradient(ColorRampPropertyValue value) { + if (value == getLineGradient()) + return; + auto impl_ = mutableImpl(); + impl_->paint.template get<LineGradient>().value = value; + baseImpl = std::move(impl_); + observer->onLayerChanged(*this); +} + +void LineLayer::setLineGradientTransition(const TransitionOptions& options) { + auto impl_ = mutableImpl(); + impl_->paint.template get<LineGradient>().options = options; + baseImpl = std::move(impl_); +} + +TransitionOptions LineLayer::getLineGradientTransition() const { + return impl().paint.template get<LineGradient>().options; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer_properties.hpp b/src/mbgl/style/layers/line_layer_properties.hpp index aeaf51698a..ee6789205c 100644 --- a/src/mbgl/style/layers/line_layer_properties.hpp +++ b/src/mbgl/style/layers/line_layer_properties.hpp @@ -72,6 +72,8 @@ struct LinePattern : CrossFadedPaintProperty<std::string> { static std::string defaultValue() { return ""; } }; +struct LineGradient : ColorRampProperty {}; + class LineLayoutProperties : public Properties< LineCap, LineJoin, @@ -89,7 +91,8 @@ class LinePaintProperties : public Properties< LineOffset, LineBlur, LineDasharray, - LinePattern + LinePattern, + LineGradient > {}; } // namespace style diff --git a/src/mbgl/style/paint_property.hpp b/src/mbgl/style/paint_property.hpp index 195eb645a9..15dbf9205c 100644 --- a/src/mbgl/style/paint_property.hpp +++ b/src/mbgl/style/paint_property.hpp @@ -2,7 +2,7 @@ #include <mbgl/style/properties.hpp> #include <mbgl/style/property_value.hpp> -#include <mbgl/style/heatmap_color_property_value.hpp> +#include <mbgl/style/color_ramp_property_value.hpp> #include <mbgl/style/data_driven_property_value.hpp> #include <mbgl/renderer/property_evaluator.hpp> #include <mbgl/renderer/cross_faded_property_evaluator.hpp> @@ -50,19 +50,19 @@ public: }; /* - * Special-case paint property traits for heatmap-color, needed because - * heatmap-color values do not fit into the + * Special-case paint property traits for heatmap-color and line-gradient, + * needed because these values do not fit into the * Undefined | Value | {Camera,Source,Composite}Function taxonomy that applies * to all other paint properties. * - * These traits are provided here--despite the fact that heatmap-color - * is not used like other paint properties--to allow the parameter-pack-based + * These traits are provided here--despite the fact that color ramps + * are not used like other paint properties--to allow the parameter-pack-based * batch evaluation of paint properties to compile properly. */ -class HeatmapColor { +class ColorRampProperty { public: - using TransitionableType = Transitionable<HeatmapColorPropertyValue>; - using UnevaluatedType = Transitioning<HeatmapColorPropertyValue>; + using TransitionableType = Transitionable<ColorRampPropertyValue>; + using UnevaluatedType = Transitioning<ColorRampPropertyValue>; using EvaluatorType = PropertyEvaluator<Color>; using PossiblyEvaluatedType = Color; using Type = Color; |