Skip to content

Commit

Permalink
Expose iconColorSaturation and experimental rasterElevation (#1999)
Browse files Browse the repository at this point in the history
* Expose SymbolLayer.iconColorSaturation and experimental RasterLayer.rasterElevation

* Bump gl-native snapshot
  • Loading branch information
aleksproger authored Jan 29, 2024
1 parent 98560c5 commit ed4a831
Show file tree
Hide file tree
Showing 11 changed files with 182 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Use them to configure respective map options after creating a map view.
* Expose `MapboxMap.reduceMemoryUse()` which can be used in situations when it is important to keep the memory footprint minimal.
* Expose `MapboxMap.isAnimationInProgress` and `MapboxMap.isGestureInProgress` to query current status of both built-in and custom camera animations and gestures.
* Expose experimental `CustomRasterSource` and non-experimental `CustomGeometrySource` as regular `Source`'s providing a better way to work with them and also allow for using them in Style DSL.
* Introduce `SymbolLayer.iconColorSaturation` API.
* Introduce experimental `RasterLayer.rasterElevation` API.

## 11.1.0 - 17 January, 2024

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,16 @@ public class PointAnnotationManager: AnnotationManagerInternal {
}
}

/// Controls saturation level of the symbol icon. With the default value of 1 the icon color is preserved while with a value of 0 it is fully desaturated and looks black and white.
public var iconColorSaturation: Double? {
get {
return layerProperties["icon-color-saturation"] as? Double
}
set {
layerProperties["icon-color-saturation"] = newValue
}
}

/// Distance that the icon's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up.
public var iconTranslate: [Double]? {
get {
Expand Down
18 changes: 18 additions & 0 deletions Sources/MapboxMaps/Style/Generated/Layers/RasterLayer.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions Sources/MapboxMaps/Style/Generated/Layers/SymbolLayer.swift

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ public struct PointAnnotationGroup<Data: RandomAccessCollection, ID: Hashable>:
assign(manager, \.textRotationAlignment, value: textRotationAlignment)
assign(manager, \.textVariableAnchor, value: textVariableAnchor)
assign(manager, \.textWritingMode, value: textWritingMode)
assign(manager, \.iconColorSaturation, value: iconColorSaturation)
assign(manager, \.iconTranslate, value: iconTranslate)
assign(manager, \.iconTranslateAnchor, value: iconTranslateAnchor)
assign(manager, \.textTranslate, value: textTranslate)
Expand Down Expand Up @@ -333,6 +334,15 @@ public struct PointAnnotationGroup<Data: RandomAccessCollection, ID: Hashable>:
with(self, setter(\.textWritingMode, newValue))
}

private var iconColorSaturation: Double?
/// Controls saturation level of the symbol icon. With the default value of 1 the icon color is preserved while with a value of 0 it is fully desaturated and looks black and white.
#if swift(>=5.8)
@_documentation(visibility: public)
#endif
public func iconColorSaturation(_ newValue: Double) -> Self {
with(self, setter(\.iconColorSaturation, newValue))
}

private var iconTranslate: [Double]?
/// Distance that the icon's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up.
#if swift(>=5.8)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,32 @@ final class PointAnnotationIntegrationTests: MapViewIntegrationTestCase {
XCTAssertEqual(layer.textWritingMode, .constant(StyleManager.layerPropertyDefaultValue(for: .symbol, property: "text-writing-mode").value as! [TextWritingMode]))
}

func testIconColorSaturation() throws {
// Test that the setter and getter work
let value = Double.random(in: 0...1)
manager.iconColorSaturation = value
XCTAssertEqual(manager.iconColorSaturation, value)

// Test that the value is synced to the layer
manager.syncSourceAndLayerIfNeeded()
var layer = try mapView.mapboxMap.layer(withId: self.manager.layerId, type: SymbolLayer.self)
if case .constant(let actualValue) = layer.iconColorSaturation {
XCTAssertEqual(actualValue, value, accuracy: 0.1)
} else {
XCTFail("Expected constant")
}

// Test that the property can be reset to nil
manager.iconColorSaturation = nil
XCTAssertNil(manager.iconColorSaturation)

// Verify that when the property is reset to nil,
// the layer is returned to the default value
manager.syncSourceAndLayerIfNeeded()
layer = try mapView.mapboxMap.layer(withId: self.manager.layerId, type: SymbolLayer.self)
XCTAssertEqual(layer.iconColorSaturation, .constant((StyleManager.layerPropertyDefaultValue(for: .symbol, property: "icon-color-saturation").value as! NSNumber).doubleValue))
}

func testIconTranslate() throws {
// Test that the setter and getter work
let value = [Double.random(in: -100000...100000), Double.random(in: -100000...100000)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2409,6 +2409,100 @@ final class PointAnnotationManagerTests: XCTestCase, AnnotationInteractionDelega
XCTAssertEqual(style.setLayerPropertiesStub.invocations.last?.parameters.properties["text-writing-mode"] as! [TextWritingMode], defaultValue)
}

func testInitialIconColorSaturation() {
let initialValue = manager.iconColorSaturation
XCTAssertNil(initialValue)
}

func testSetIconColorSaturation() {
let value = Double.random(in: 0...1)
manager.iconColorSaturation = value
XCTAssertEqual(manager.iconColorSaturation, value)

// test layer and source synced and properties added
$displayLink.send()
XCTAssertEqual(style.setLayerPropertiesStub.invocations.count, 1)
XCTAssertEqual(style.setLayerPropertiesStub.invocations.last?.parameters.layerId, manager.id)
XCTAssertEqual(style.setLayerPropertiesStub.invocations.last?.parameters.properties["icon-color-saturation"] as! Double, value)
}

func testIconColorSaturationAnnotationPropertiesAddedWithoutDuplicate() {
let newIconColorSaturationProperty = Double.random(in: 0...1)
let secondIconColorSaturationProperty = Double.random(in: 0...1)

manager.iconColorSaturation = newIconColorSaturationProperty
$displayLink.send()
manager.iconColorSaturation = secondIconColorSaturationProperty
$displayLink.send()

XCTAssertEqual(style.setLayerPropertiesStub.invocations.last?.parameters.layerId, manager.id)
XCTAssertEqual(style.setLayerPropertiesStub.invocations.count, 2)
XCTAssertEqual(style.setLayerPropertiesStub.invocations.last?.parameters.properties["icon-color-saturation"] as! Double, secondIconColorSaturationProperty)
}

func testNewIconColorSaturationPropertyMergedWithAnnotationProperties() {
var annotations = [PointAnnotation]()
for _ in 0...5 {
var annotation = PointAnnotation(point: .init(.init(latitude: 0, longitude: 0)), isSelected: false, isDraggable: false)
annotation.iconAnchor = IconAnchor.random()
annotation.iconImage = String.randomASCII(withLength: .random(in: 0...100))
annotation.iconOffset = [Double.random(in: -100000...100000), Double.random(in: -100000...100000)]
annotation.iconRotate = Double.random(in: -100000...100000)
annotation.iconSize = Double.random(in: 0...100000)
annotation.iconTextFit = IconTextFit.random()
annotation.iconTextFitPadding = [Double.random(in: -100000...100000), Double.random(in: -100000...100000), Double.random(in: -100000...100000), Double.random(in: -100000...100000)]
annotation.symbolSortKey = Double.random(in: -100000...100000)
annotation.textAnchor = TextAnchor.random()
annotation.textField = String.randomASCII(withLength: .random(in: 0...100))
annotation.textJustify = TextJustify.random()
annotation.textLetterSpacing = Double.random(in: -100000...100000)
annotation.textLineHeight = Double.random(in: -100000...100000)
annotation.textMaxWidth = Double.random(in: 0...100000)
annotation.textOffset = [Double.random(in: -100000...100000), Double.random(in: -100000...100000)]
annotation.textRadialOffset = Double.random(in: -100000...100000)
annotation.textRotate = Double.random(in: -100000...100000)
annotation.textSize = Double.random(in: 0...100000)
annotation.textTransform = TextTransform.random()
annotation.iconColor = StyleColor.random()
annotation.iconEmissiveStrength = Double.random(in: 0...100000)
annotation.iconHaloBlur = Double.random(in: 0...100000)
annotation.iconHaloColor = StyleColor.random()
annotation.iconHaloWidth = Double.random(in: 0...100000)
annotation.iconImageCrossFade = Double.random(in: 0...1)
annotation.iconOpacity = Double.random(in: 0...1)
annotation.textColor = StyleColor.random()
annotation.textEmissiveStrength = Double.random(in: 0...100000)
annotation.textHaloBlur = Double.random(in: 0...100000)
annotation.textHaloColor = StyleColor.random()
annotation.textHaloWidth = Double.random(in: 0...100000)
annotation.textOpacity = Double.random(in: 0...1)
annotations.append(annotation)
}
let newIconColorSaturationProperty = Double.random(in: 0...1)

manager.annotations = annotations
manager.iconColorSaturation = newIconColorSaturationProperty
$displayLink.send()

XCTAssertEqual(style.setLayerPropertiesStub.invocations.count, 1)
XCTAssertEqual(style.setLayerPropertiesStub.invocations.last?.parameters.properties.count, annotations[0].layerProperties.count+1)
XCTAssertNotNil(style.setLayerPropertiesStub.invocations.last?.parameters.properties["icon-color-saturation"])
}

func testSetToNilIconColorSaturation() {
let newIconColorSaturationProperty = Double.random(in: 0...1)
let defaultValue = StyleManager.layerPropertyDefaultValue(for: .symbol, property: "icon-color-saturation").value as! Double
manager.iconColorSaturation = newIconColorSaturationProperty
$displayLink.send()
XCTAssertNotNil(style.setLayerPropertiesStub.invocations.last?.parameters.properties["icon-color-saturation"])

manager.iconColorSaturation = nil
$displayLink.send()
XCTAssertNil(manager.iconColorSaturation)

XCTAssertEqual(style.setLayerPropertiesStub.invocations.last?.parameters.properties["icon-color-saturation"] as! Double, defaultValue)
}

func testInitialIconTranslate() {
let initialValue = manager.iconTranslate
XCTAssertNil(initialValue)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ final class RasterLayerIntegrationTests: MapViewIntegrationTestCase {
layer.rasterColorRangeTransition = StyleTransition(duration: 10.0, delay: 10.0)
layer.rasterContrast = Value<Double>.testConstantValue()
layer.rasterContrastTransition = StyleTransition(duration: 10.0, delay: 10.0)
layer.rasterElevation = Value<Double>.testConstantValue()
layer.rasterElevationTransition = StyleTransition(duration: 10.0, delay: 10.0)
layer.rasterEmissiveStrength = Value<Double>.testConstantValue()
layer.rasterEmissiveStrengthTransition = StyleTransition(duration: 10.0, delay: 10.0)
layer.rasterFadeDuration = Value<Double>.testConstantValue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ final class SymbolLayerIntegrationTests: MapViewIntegrationTestCase {

layer.iconColor = Value<StyleColor>.testConstantValue()
layer.iconColorTransition = StyleTransition(duration: 10.0, delay: 10.0)
layer.iconColorSaturation = Value<Double>.testConstantValue()
layer.iconColorSaturationTransition = StyleTransition(duration: 10.0, delay: 10.0)
layer.iconEmissiveStrength = Value<Double>.testConstantValue()
layer.iconEmissiveStrengthTransition = StyleTransition(duration: 10.0, delay: 10.0)
layer.iconHaloBlur = Value<Double>.testConstantValue()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ final class RasterLayerTests: XCTestCase {
layer.rasterColorRangeTransition = StyleTransition(duration: 10.0, delay: 10.0)
layer.rasterContrast = Value<Double>.testConstantValue()
layer.rasterContrastTransition = StyleTransition(duration: 10.0, delay: 10.0)
layer.rasterElevation = Value<Double>.testConstantValue()
layer.rasterElevationTransition = StyleTransition(duration: 10.0, delay: 10.0)
layer.rasterEmissiveStrength = Value<Double>.testConstantValue()
layer.rasterEmissiveStrengthTransition = StyleTransition(duration: 10.0, delay: 10.0)
layer.rasterFadeDuration = Value<Double>.testConstantValue()
Expand Down Expand Up @@ -116,6 +118,7 @@ final class RasterLayerTests: XCTestCase {
XCTAssertEqual(layer.rasterColorMix, Value<[Double]>.testConstantValue())
XCTAssertEqual(layer.rasterColorRange, Value<[Double]>.testConstantValue())
XCTAssertEqual(layer.rasterContrast, Value<Double>.testConstantValue())
XCTAssertEqual(layer.rasterElevation, Value<Double>.testConstantValue())
XCTAssertEqual(layer.rasterEmissiveStrength, Value<Double>.testConstantValue())
XCTAssertEqual(layer.rasterFadeDuration, Value<Double>.testConstantValue())
XCTAssertEqual(layer.rasterHueRotate, Value<Double>.testConstantValue())
Expand Down
Loading

0 comments on commit ed4a831

Please sign in to comment.