diff options
Diffstat (limited to 'platform/darwin')
-rw-r--r-- | platform/darwin/src/MGLHillshadeStyleLayer.h | 276 | ||||
-rw-r--r-- | platform/darwin/src/MGLHillshadeStyleLayer.mm | 286 | ||||
-rw-r--r-- | platform/darwin/test/MGLHillshadeStyleLayerTests.mm | 345 |
3 files changed, 907 insertions, 0 deletions
diff --git a/platform/darwin/src/MGLHillshadeStyleLayer.h b/platform/darwin/src/MGLHillshadeStyleLayer.h new file mode 100644 index 0000000000..0fe49d510d --- /dev/null +++ b/platform/darwin/src/MGLHillshadeStyleLayer.h @@ -0,0 +1,276 @@ +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. + +#import "MGLFoundation.h" +#import "MGLStyleValue.h" +#import "MGLVectorStyleLayer.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + Direction of light source when map is rotated. + + Values of this type are used in the `MGLHillshadeStyleLayer.hillshadeIlluminationAnchor` + property. + */ +typedef NS_ENUM(NSUInteger, MGLHillshadeIlluminationAnchor) { + /** + The hillshade illumination is relative to the north direction. + */ + MGLHillshadeIlluminationAnchorMap, + /** + The hillshade illumination is relative to the top of the viewport. + */ + MGLHillshadeIlluminationAnchorViewport, +}; + +/** + Client-side hillshading visualization based on DEM data. Currently, the + implementation only supports Mapbox Terrain RGB tiles + + You can access an existing hillshade style layer using the + `-[MGLStyle layerWithIdentifier:]` method if you know its identifier; + otherwise, find it using the `MGLStyle.layers` property. You can also create a + new hillshade style layer and add it to the style using a method such as + `-[MGLStyle addLayer:]`. + + ### Example + + ```swift + ``` + */ +MGL_EXPORT +@interface MGLHillshadeStyleLayer : MGLVectorStyleLayer + +/** + Returns a hillshade style layer initialized with an identifier and source. + + After initializing and configuring the style layer, add it to a map view’s + style using the `-[MGLStyle addLayer:]` or + `-[MGLStyle insertLayer:belowLayer:]` method. + + @param identifier A string that uniquely identifies the source in the style to + which it is added. + @param source The source from which to obtain the data to style. If the source + has not yet been added to the current style, the behavior is undefined. + @return An initialized foreground style layer. + */ +- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source; + +#pragma mark - Accessing the Paint Attributes + +#if TARGET_OS_IPHONE +/** + The shading color used to accentuate rugged terrain like sharp cliffs and + gorges. + + The default value of this property is an `MGLStyleValue` object containing + `UIColor.blackColor`. Set this property to `nil` to reset it to the default + value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<UIColor *> *hillshadeAccentColor; +#else +/** + The shading color used to accentuate rugged terrain like sharp cliffs and + gorges. + + The default value of this property is an `MGLStyleValue` object containing + `NSColor.blackColor`. Set this property to `nil` to reset it to the default + value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<NSColor *> *hillshadeAccentColor; +#endif + +/** + The transition affecting any changes to this layer’s `hillshadeAccentColor` property. + + This property corresponds to the `hillshade-accent-color-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition hillshadeAccentColorTransition; + +/** + Intensity of the hillshade + + The default value of this property is an `MGLStyleValue` object containing an + `NSNumber` object containing the float `0.5`. Set this property to `nil` to + reset it to the default value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *hillshadeExaggeration; + +/** + The transition affecting any changes to this layer’s `hillshadeExaggeration` property. + + This property corresponds to the `hillshade-exaggeration-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition hillshadeExaggerationTransition; + +#if TARGET_OS_IPHONE +/** + The shading color of areas that faces towards the light source. + + The default value of this property is an `MGLStyleValue` object containing + `UIColor.whiteColor`. Set this property to `nil` to reset it to the default + value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<UIColor *> *hillshadeHighlightColor; +#else +/** + The shading color of areas that faces towards the light source. + + The default value of this property is an `MGLStyleValue` object containing + `NSColor.whiteColor`. Set this property to `nil` to reset it to the default + value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<NSColor *> *hillshadeHighlightColor; +#endif + +/** + The transition affecting any changes to this layer’s `hillshadeHighlightColor` property. + + This property corresponds to the `hillshade-highlight-color-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition hillshadeHighlightColorTransition; + +/** + Direction of light source when map is rotated. + + The default value of this property is an `MGLStyleValue` object containing an + `NSValue` object containing `MGLHillshadeIlluminationAnchorViewport`. Set this + property to `nil` to reset it to the default value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of + `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<NSValue *> *hillshadeIlluminationAnchor; + +/** + The direction of the light source used to generate the hillshading with 0 as + the top of the viewport if `hillshadeIlluminationAnchor` is set to + `MGLHillshadeIlluminationAnchorViewport` and due north if + `hillshadeIlluminationAnchor` is set to `MGLHillshadeIlluminationAnchorMap`. + + The default value of this property is an `MGLStyleValue` object containing an + `NSNumber` object containing the float `335`. Set this property to `nil` to + reset it to the default value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<NSNumber *> *hillshadeIlluminationDirection; + +/** + The transition affecting any changes to this layer’s `hillshadeIlluminationDirection` property. + + This property corresponds to the `hillshade-illumination-direction-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition hillshadeIlluminationDirectionTransition; + +#if TARGET_OS_IPHONE +/** + The shading color of areas that face away from the light source. + + The default value of this property is an `MGLStyleValue` object containing + `UIColor.blackColor`. Set this property to `nil` to reset it to the default + value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<UIColor *> *hillshadeShadowColor; +#else +/** + The shading color of areas that face away from the light source. + + The default value of this property is an `MGLStyleValue` object containing + `NSColor.blackColor`. Set this property to `nil` to reset it to the default + value. + + You can set this property to an instance of: + + * `MGLConstantStyleValue` + * `MGLCameraStyleFunction` with an interpolation mode of: + * `MGLInterpolationModeExponential` + * `MGLInterpolationModeInterval` + */ +@property (nonatomic, null_resettable) MGLStyleValue<NSColor *> *hillshadeShadowColor; +#endif + +/** + The transition affecting any changes to this layer’s `hillshadeShadowColor` property. + + This property corresponds to the `hillshade-shadow-color-transition` property in the style JSON file format. +*/ +@property (nonatomic) MGLTransition hillshadeShadowColorTransition; + +@end + +/** + Methods for wrapping an enumeration value for a style layer attribute in an + `MGLHillshadeStyleLayer` object and unwrapping its raw value. + */ +@interface NSValue (MGLHillshadeStyleLayerAdditions) + +#pragma mark Working with Hillshade Style Layer Attribute Values + +/** + Creates a new value object containing the given `MGLHillshadeIlluminationAnchor` enumeration. + + @param hillshadeIlluminationAnchor The value for the new object. + @return A new value object that contains the enumeration value. + */ ++ (instancetype)valueWithMGLHillshadeIlluminationAnchor:(MGLHillshadeIlluminationAnchor)hillshadeIlluminationAnchor; + +/** + The `MGLHillshadeIlluminationAnchor` enumeration representation of the value. + */ +@property (readonly) MGLHillshadeIlluminationAnchor MGLHillshadeIlluminationAnchorValue; + +@end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLHillshadeStyleLayer.mm b/platform/darwin/src/MGLHillshadeStyleLayer.mm new file mode 100644 index 0000000000..3225feb587 --- /dev/null +++ b/platform/darwin/src/MGLHillshadeStyleLayer.mm @@ -0,0 +1,286 @@ +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. + +#import "MGLSource.h" +#import "NSPredicate+MGLAdditions.h" +#import "NSDate+MGLAdditions.h" +#import "MGLStyleLayer_Private.h" +#import "MGLStyleValue_Private.h" +#import "MGLHillshadeStyleLayer.h" + +#include <mbgl/style/transition_options.hpp> +#include <mbgl/style/layers/hillshade_layer.hpp> + +namespace mbgl { + + MBGL_DEFINE_ENUM(MGLHillshadeIlluminationAnchor, { + { MGLHillshadeIlluminationAnchorMap, "map" }, + { MGLHillshadeIlluminationAnchorViewport, "viewport" }, + }); + +} + +@interface MGLHillshadeStyleLayer () + +@property (nonatomic, readonly) mbgl::style::HillshadeLayer *rawLayer; + +@end + +@implementation MGLHillshadeStyleLayer + +- (instancetype)initWithIdentifier:(NSString *)identifier source:(MGLSource *)source +{ + auto layer = std::make_unique<mbgl::style::HillshadeLayer>(identifier.UTF8String, source.identifier.UTF8String); + return self = [super initWithPendingLayer:std::move(layer)]; +} + +- (mbgl::style::HillshadeLayer *)rawLayer +{ + return (mbgl::style::HillshadeLayer *)super.rawLayer; +} + +- (NSString *)sourceIdentifier +{ + MGLAssertStyleLayerIsValid(); + + return @(self.rawLayer->getSourceID().c_str()); +} + +- (NSString *)sourceLayerIdentifier +{ + MGLAssertStyleLayerIsValid(); + + auto layerID = self.rawLayer->getSourceLayer(); + return layerID.empty() ? nil : @(layerID.c_str()); +} + +- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier +{ + MGLAssertStyleLayerIsValid(); + + self.rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: ""); +} + +- (void)setPredicate:(NSPredicate *)predicate +{ + MGLAssertStyleLayerIsValid(); + + self.rawLayer->setFilter(predicate ? predicate.mgl_filter : mbgl::style::NullFilter()); +} + +- (NSPredicate *)predicate +{ + MGLAssertStyleLayerIsValid(); + + return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()]; +} + +#pragma mark - Accessing the Paint Attributes + +- (void)setHillshadeAccentColor:(MGLStyleValue<MGLColor *> *)hillshadeAccentColor { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toInterpolatablePropertyValue(hillshadeAccentColor); + self.rawLayer->setHillshadeAccentColor(mbglValue); +} + +- (MGLStyleValue<MGLColor *> *)hillshadeAccentColor { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getHillshadeAccentColor(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(self.rawLayer->getDefaultHillshadeAccentColor()); + } + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue); +} + +- (void)setHillshadeAccentColorTransition:(MGLTransition )transition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; + self.rawLayer->setHillshadeAccentColorTransition(options); +} + +- (MGLTransition)hillshadeAccentColorTransition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeAccentColorTransition(); + MGLTransition transition; + transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero())); + transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero())); + + return transition; +} + +- (void)setHillshadeExaggeration:(MGLStyleValue<NSNumber *> *)hillshadeExaggeration { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toInterpolatablePropertyValue(hillshadeExaggeration); + self.rawLayer->setHillshadeExaggeration(mbglValue); +} + +- (MGLStyleValue<NSNumber *> *)hillshadeExaggeration { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getHillshadeExaggeration(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(self.rawLayer->getDefaultHillshadeExaggeration()); + } + return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue); +} + +- (void)setHillshadeExaggerationTransition:(MGLTransition )transition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; + self.rawLayer->setHillshadeExaggerationTransition(options); +} + +- (MGLTransition)hillshadeExaggerationTransition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeExaggerationTransition(); + MGLTransition transition; + transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero())); + transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero())); + + return transition; +} + +- (void)setHillshadeHighlightColor:(MGLStyleValue<MGLColor *> *)hillshadeHighlightColor { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toInterpolatablePropertyValue(hillshadeHighlightColor); + self.rawLayer->setHillshadeHighlightColor(mbglValue); +} + +- (MGLStyleValue<MGLColor *> *)hillshadeHighlightColor { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getHillshadeHighlightColor(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(self.rawLayer->getDefaultHillshadeHighlightColor()); + } + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue); +} + +- (void)setHillshadeHighlightColorTransition:(MGLTransition )transition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; + self.rawLayer->setHillshadeHighlightColorTransition(options); +} + +- (MGLTransition)hillshadeHighlightColorTransition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeHighlightColorTransition(); + MGLTransition transition; + transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero())); + transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero())); + + return transition; +} + +- (void)setHillshadeIlluminationAnchor:(MGLStyleValue<NSValue *> *)hillshadeIlluminationAnchor { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<mbgl::style::HillshadeIlluminationAnchorType, NSValue *, mbgl::style::HillshadeIlluminationAnchorType, MGLHillshadeIlluminationAnchor>().toEnumPropertyValue(hillshadeIlluminationAnchor); + self.rawLayer->setHillshadeIlluminationAnchor(mbglValue); +} + +- (MGLStyleValue<NSValue *> *)hillshadeIlluminationAnchor { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getHillshadeIlluminationAnchor(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer<mbgl::style::HillshadeIlluminationAnchorType, NSValue *, mbgl::style::HillshadeIlluminationAnchorType, MGLHillshadeIlluminationAnchor>().toEnumStyleValue(self.rawLayer->getDefaultHillshadeIlluminationAnchor()); + } + return MGLStyleValueTransformer<mbgl::style::HillshadeIlluminationAnchorType, NSValue *, mbgl::style::HillshadeIlluminationAnchorType, MGLHillshadeIlluminationAnchor>().toEnumStyleValue(propertyValue); +} + +- (void)setHillshadeIlluminationDirection:(MGLStyleValue<NSNumber *> *)hillshadeIlluminationDirection { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toInterpolatablePropertyValue(hillshadeIlluminationDirection); + self.rawLayer->setHillshadeIlluminationDirection(mbglValue); +} + +- (MGLStyleValue<NSNumber *> *)hillshadeIlluminationDirection { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getHillshadeIlluminationDirection(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(self.rawLayer->getDefaultHillshadeIlluminationDirection()); + } + return MGLStyleValueTransformer<float, NSNumber *>().toStyleValue(propertyValue); +} + +- (void)setHillshadeIlluminationDirectionTransition:(MGLTransition )transition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; + self.rawLayer->setHillshadeIlluminationDirectionTransition(options); +} + +- (MGLTransition)hillshadeIlluminationDirectionTransition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeIlluminationDirectionTransition(); + MGLTransition transition; + transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero())); + transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero())); + + return transition; +} + +- (void)setHillshadeShadowColor:(MGLStyleValue<MGLColor *> *)hillshadeShadowColor { + MGLAssertStyleLayerIsValid(); + + auto mbglValue = MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toInterpolatablePropertyValue(hillshadeShadowColor); + self.rawLayer->setHillshadeShadowColor(mbglValue); +} + +- (MGLStyleValue<MGLColor *> *)hillshadeShadowColor { + MGLAssertStyleLayerIsValid(); + + auto propertyValue = self.rawLayer->getHillshadeShadowColor(); + if (propertyValue.isUndefined()) { + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(self.rawLayer->getDefaultHillshadeShadowColor()); + } + return MGLStyleValueTransformer<mbgl::Color, MGLColor *>().toStyleValue(propertyValue); +} + +- (void)setHillshadeShadowColorTransition:(MGLTransition )transition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions options { { MGLDurationFromTimeInterval(transition.duration) }, { MGLDurationFromTimeInterval(transition.delay) } }; + self.rawLayer->setHillshadeShadowColorTransition(options); +} + +- (MGLTransition)hillshadeShadowColorTransition { + MGLAssertStyleLayerIsValid(); + + mbgl::style::TransitionOptions transitionOptions = self.rawLayer->getHillshadeShadowColorTransition(); + MGLTransition transition; + transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero())); + transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero())); + + return transition; +} + +@end + +@implementation NSValue (MGLHillshadeStyleLayerAdditions) + ++ (NSValue *)valueWithMGLHillshadeIlluminationAnchor:(MGLHillshadeIlluminationAnchor)hillshadeIlluminationAnchor { + return [NSValue value:&hillshadeIlluminationAnchor withObjCType:@encode(MGLHillshadeIlluminationAnchor)]; +} + +- (MGLHillshadeIlluminationAnchor)MGLHillshadeIlluminationAnchorValue { + MGLHillshadeIlluminationAnchor hillshadeIlluminationAnchor; + [self getValue:&hillshadeIlluminationAnchor]; + return hillshadeIlluminationAnchor; +} + +@end diff --git a/platform/darwin/test/MGLHillshadeStyleLayerTests.mm b/platform/darwin/test/MGLHillshadeStyleLayerTests.mm new file mode 100644 index 0000000000..283830ccb5 --- /dev/null +++ b/platform/darwin/test/MGLHillshadeStyleLayerTests.mm @@ -0,0 +1,345 @@ +// This file is generated. +// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`. + +#import "MGLStyleLayerTests.h" +#import "../../darwin/src/NSDate+MGLAdditions.h" + +#import "MGLStyleLayer_Private.h" + +#include <mbgl/style/layers/hillshade_layer.hpp> +#include <mbgl/style/transition_options.hpp> + +@interface MGLHillshadeLayerTests : MGLStyleLayerTests +@end + +@implementation MGLHillshadeLayerTests + ++ (NSString *)layerType { + return @"hillshade"; +} + +- (void)testPredicates { + MGLPointFeature *feature = [[MGLPointFeature alloc] init]; + MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"sourceID" shape:feature options:nil]; + MGLHillshadeStyleLayer *layer = [[MGLHillshadeStyleLayer alloc] initWithIdentifier:@"layerID" source:source]; + + XCTAssertNil(layer.sourceLayerIdentifier); + layer.sourceLayerIdentifier = @"layerID"; + XCTAssertEqualObjects(layer.sourceLayerIdentifier, @"layerID"); + layer.sourceLayerIdentifier = nil; + XCTAssertNil(layer.sourceLayerIdentifier); + + XCTAssertNil(layer.predicate); + layer.predicate = [NSPredicate predicateWithValue:NO]; + XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithValue:NO]); + layer.predicate = nil; + XCTAssertNil(layer.predicate); +} + +- (void)testProperties { + MGLPointFeature *feature = [[MGLPointFeature alloc] init]; + MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"sourceID" shape:feature options:nil]; + + MGLHillshadeStyleLayer *layer = [[MGLHillshadeStyleLayer alloc] initWithIdentifier:@"layerID" source:source]; + XCTAssertNotEqual(layer.rawLayer, nullptr); + XCTAssertTrue(layer.rawLayer->is<mbgl::style::HillshadeLayer>()); + auto rawLayer = layer.rawLayer->as<mbgl::style::HillshadeLayer>(); + + MGLTransition transitionTest = MGLTransitionMake(5, 4); + + + // hillshade-accent-color + { + XCTAssertTrue(rawLayer->getHillshadeAccentColor().isUndefined(), + @"hillshade-accent-color should be unset initially."); + MGLStyleValue<MGLColor *> *defaultStyleValue = layer.hillshadeAccentColor; + + MGLStyleValue<MGLColor *> *constantStyleValue = [MGLStyleValue<MGLColor *> valueWithRawValue:[MGLColor redColor]]; + layer.hillshadeAccentColor = constantStyleValue; + mbgl::style::PropertyValue<mbgl::Color> propertyValue = { { 1, 0, 0, 1 } }; + XCTAssertEqual(rawLayer->getHillshadeAccentColor(), propertyValue, + @"Setting hillshadeAccentColor to a constant value should update hillshade-accent-color."); + XCTAssertEqualObjects(layer.hillshadeAccentColor, constantStyleValue, + @"hillshadeAccentColor should round-trip constant values."); + + MGLStyleValue<MGLColor *> * functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.hillshadeAccentColor = functionStyleValue; + + mbgl::style::IntervalStops<mbgl::Color> intervalStops = { {{18, { 1, 0, 0, 1 }}} }; + propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; + + XCTAssertEqual(rawLayer->getHillshadeAccentColor(), propertyValue, + @"Setting hillshadeAccentColor to a camera function should update hillshade-accent-color."); + XCTAssertEqualObjects(layer.hillshadeAccentColor, functionStyleValue, + @"hillshadeAccentColor should round-trip camera functions."); + + + + layer.hillshadeAccentColor = nil; + XCTAssertTrue(rawLayer->getHillshadeAccentColor().isUndefined(), + @"Unsetting hillshadeAccentColor should return hillshade-accent-color to the default value."); + XCTAssertEqualObjects(layer.hillshadeAccentColor, defaultStyleValue, + @"hillshadeAccentColor should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeAccentColor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeAccentColor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + // Transition property test + layer.hillshadeAccentColorTransition = transitionTest; + auto toptions = rawLayer->getHillshadeAccentColorTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition hillshadeAccentColorTransition = layer.hillshadeAccentColorTransition; + XCTAssertEqual(hillshadeAccentColorTransition.delay, transitionTest.delay); + XCTAssertEqual(hillshadeAccentColorTransition.duration, transitionTest.duration); + } + + // hillshade-exaggeration + { + XCTAssertTrue(rawLayer->getHillshadeExaggeration().isUndefined(), + @"hillshade-exaggeration should be unset initially."); + MGLStyleValue<NSNumber *> *defaultStyleValue = layer.hillshadeExaggeration; + + MGLStyleValue<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; + layer.hillshadeExaggeration = constantStyleValue; + mbgl::style::PropertyValue<float> propertyValue = { 0xff }; + XCTAssertEqual(rawLayer->getHillshadeExaggeration(), propertyValue, + @"Setting hillshadeExaggeration to a constant value should update hillshade-exaggeration."); + XCTAssertEqualObjects(layer.hillshadeExaggeration, constantStyleValue, + @"hillshadeExaggeration should round-trip constant values."); + + MGLStyleValue<NSNumber *> * functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.hillshadeExaggeration = functionStyleValue; + + mbgl::style::IntervalStops<float> intervalStops = { {{18, 0xff}} }; + propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; + + XCTAssertEqual(rawLayer->getHillshadeExaggeration(), propertyValue, + @"Setting hillshadeExaggeration to a camera function should update hillshade-exaggeration."); + XCTAssertEqualObjects(layer.hillshadeExaggeration, functionStyleValue, + @"hillshadeExaggeration should round-trip camera functions."); + + + + layer.hillshadeExaggeration = nil; + XCTAssertTrue(rawLayer->getHillshadeExaggeration().isUndefined(), + @"Unsetting hillshadeExaggeration should return hillshade-exaggeration to the default value."); + XCTAssertEqualObjects(layer.hillshadeExaggeration, defaultStyleValue, + @"hillshadeExaggeration should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeExaggeration = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeExaggeration = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + // Transition property test + layer.hillshadeExaggerationTransition = transitionTest; + auto toptions = rawLayer->getHillshadeExaggerationTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition hillshadeExaggerationTransition = layer.hillshadeExaggerationTransition; + XCTAssertEqual(hillshadeExaggerationTransition.delay, transitionTest.delay); + XCTAssertEqual(hillshadeExaggerationTransition.duration, transitionTest.duration); + } + + // hillshade-highlight-color + { + XCTAssertTrue(rawLayer->getHillshadeHighlightColor().isUndefined(), + @"hillshade-highlight-color should be unset initially."); + MGLStyleValue<MGLColor *> *defaultStyleValue = layer.hillshadeHighlightColor; + + MGLStyleValue<MGLColor *> *constantStyleValue = [MGLStyleValue<MGLColor *> valueWithRawValue:[MGLColor redColor]]; + layer.hillshadeHighlightColor = constantStyleValue; + mbgl::style::PropertyValue<mbgl::Color> propertyValue = { { 1, 0, 0, 1 } }; + XCTAssertEqual(rawLayer->getHillshadeHighlightColor(), propertyValue, + @"Setting hillshadeHighlightColor to a constant value should update hillshade-highlight-color."); + XCTAssertEqualObjects(layer.hillshadeHighlightColor, constantStyleValue, + @"hillshadeHighlightColor should round-trip constant values."); + + MGLStyleValue<MGLColor *> * functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.hillshadeHighlightColor = functionStyleValue; + + mbgl::style::IntervalStops<mbgl::Color> intervalStops = { {{18, { 1, 0, 0, 1 }}} }; + propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; + + XCTAssertEqual(rawLayer->getHillshadeHighlightColor(), propertyValue, + @"Setting hillshadeHighlightColor to a camera function should update hillshade-highlight-color."); + XCTAssertEqualObjects(layer.hillshadeHighlightColor, functionStyleValue, + @"hillshadeHighlightColor should round-trip camera functions."); + + + + layer.hillshadeHighlightColor = nil; + XCTAssertTrue(rawLayer->getHillshadeHighlightColor().isUndefined(), + @"Unsetting hillshadeHighlightColor should return hillshade-highlight-color to the default value."); + XCTAssertEqualObjects(layer.hillshadeHighlightColor, defaultStyleValue, + @"hillshadeHighlightColor should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeHighlightColor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeHighlightColor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + // Transition property test + layer.hillshadeHighlightColorTransition = transitionTest; + auto toptions = rawLayer->getHillshadeHighlightColorTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition hillshadeHighlightColorTransition = layer.hillshadeHighlightColorTransition; + XCTAssertEqual(hillshadeHighlightColorTransition.delay, transitionTest.delay); + XCTAssertEqual(hillshadeHighlightColorTransition.duration, transitionTest.duration); + } + + // hillshade-illumination-anchor + { + XCTAssertTrue(rawLayer->getHillshadeIlluminationAnchor().isUndefined(), + @"hillshade-illumination-anchor should be unset initially."); + MGLStyleValue<NSValue *> *defaultStyleValue = layer.hillshadeIlluminationAnchor; + + MGLStyleValue<NSValue *> *constantStyleValue = [MGLStyleValue<NSValue *> valueWithRawValue:[NSValue valueWithMGLHillshadeIlluminationAnchor:MGLHillshadeIlluminationAnchorViewport]]; + layer.hillshadeIlluminationAnchor = constantStyleValue; + mbgl::style::PropertyValue<mbgl::style::HillshadeIlluminationAnchorType> propertyValue = { mbgl::style::HillshadeIlluminationAnchorType::Viewport }; + XCTAssertEqual(rawLayer->getHillshadeIlluminationAnchor(), propertyValue, + @"Setting hillshadeIlluminationAnchor to a constant value should update hillshade-illumination-anchor."); + XCTAssertEqualObjects(layer.hillshadeIlluminationAnchor, constantStyleValue, + @"hillshadeIlluminationAnchor should round-trip constant values."); + + MGLStyleValue<NSValue *> * functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.hillshadeIlluminationAnchor = functionStyleValue; + + mbgl::style::IntervalStops<mbgl::style::HillshadeIlluminationAnchorType> intervalStops = { {{18, mbgl::style::HillshadeIlluminationAnchorType::Viewport}} }; + propertyValue = mbgl::style::CameraFunction<mbgl::style::HillshadeIlluminationAnchorType> { intervalStops }; + + XCTAssertEqual(rawLayer->getHillshadeIlluminationAnchor(), propertyValue, + @"Setting hillshadeIlluminationAnchor to a camera function should update hillshade-illumination-anchor."); + XCTAssertEqualObjects(layer.hillshadeIlluminationAnchor, functionStyleValue, + @"hillshadeIlluminationAnchor should round-trip camera functions."); + + + + layer.hillshadeIlluminationAnchor = nil; + XCTAssertTrue(rawLayer->getHillshadeIlluminationAnchor().isUndefined(), + @"Unsetting hillshadeIlluminationAnchor should return hillshade-illumination-anchor to the default value."); + XCTAssertEqualObjects(layer.hillshadeIlluminationAnchor, defaultStyleValue, + @"hillshadeIlluminationAnchor should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeIlluminationAnchor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeIlluminationAnchor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + } + + // hillshade-illumination-direction + { + XCTAssertTrue(rawLayer->getHillshadeIlluminationDirection().isUndefined(), + @"hillshade-illumination-direction should be unset initially."); + MGLStyleValue<NSNumber *> *defaultStyleValue = layer.hillshadeIlluminationDirection; + + MGLStyleValue<NSNumber *> *constantStyleValue = [MGLStyleValue<NSNumber *> valueWithRawValue:@0xff]; + layer.hillshadeIlluminationDirection = constantStyleValue; + mbgl::style::PropertyValue<float> propertyValue = { 0xff }; + XCTAssertEqual(rawLayer->getHillshadeIlluminationDirection(), propertyValue, + @"Setting hillshadeIlluminationDirection to a constant value should update hillshade-illumination-direction."); + XCTAssertEqualObjects(layer.hillshadeIlluminationDirection, constantStyleValue, + @"hillshadeIlluminationDirection should round-trip constant values."); + + MGLStyleValue<NSNumber *> * functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.hillshadeIlluminationDirection = functionStyleValue; + + mbgl::style::IntervalStops<float> intervalStops = { {{18, 0xff}} }; + propertyValue = mbgl::style::CameraFunction<float> { intervalStops }; + + XCTAssertEqual(rawLayer->getHillshadeIlluminationDirection(), propertyValue, + @"Setting hillshadeIlluminationDirection to a camera function should update hillshade-illumination-direction."); + XCTAssertEqualObjects(layer.hillshadeIlluminationDirection, functionStyleValue, + @"hillshadeIlluminationDirection should round-trip camera functions."); + + + + layer.hillshadeIlluminationDirection = nil; + XCTAssertTrue(rawLayer->getHillshadeIlluminationDirection().isUndefined(), + @"Unsetting hillshadeIlluminationDirection should return hillshade-illumination-direction to the default value."); + XCTAssertEqualObjects(layer.hillshadeIlluminationDirection, defaultStyleValue, + @"hillshadeIlluminationDirection should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeIlluminationDirection = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<NSNumber *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeIlluminationDirection = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + // Transition property test + layer.hillshadeIlluminationDirectionTransition = transitionTest; + auto toptions = rawLayer->getHillshadeIlluminationDirectionTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition hillshadeIlluminationDirectionTransition = layer.hillshadeIlluminationDirectionTransition; + XCTAssertEqual(hillshadeIlluminationDirectionTransition.delay, transitionTest.delay); + XCTAssertEqual(hillshadeIlluminationDirectionTransition.duration, transitionTest.duration); + } + + // hillshade-shadow-color + { + XCTAssertTrue(rawLayer->getHillshadeShadowColor().isUndefined(), + @"hillshade-shadow-color should be unset initially."); + MGLStyleValue<MGLColor *> *defaultStyleValue = layer.hillshadeShadowColor; + + MGLStyleValue<MGLColor *> *constantStyleValue = [MGLStyleValue<MGLColor *> valueWithRawValue:[MGLColor redColor]]; + layer.hillshadeShadowColor = constantStyleValue; + mbgl::style::PropertyValue<mbgl::Color> propertyValue = { { 1, 0, 0, 1 } }; + XCTAssertEqual(rawLayer->getHillshadeShadowColor(), propertyValue, + @"Setting hillshadeShadowColor to a constant value should update hillshade-shadow-color."); + XCTAssertEqualObjects(layer.hillshadeShadowColor, constantStyleValue, + @"hillshadeShadowColor should round-trip constant values."); + + MGLStyleValue<MGLColor *> * functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil]; + layer.hillshadeShadowColor = functionStyleValue; + + mbgl::style::IntervalStops<mbgl::Color> intervalStops = { {{18, { 1, 0, 0, 1 }}} }; + propertyValue = mbgl::style::CameraFunction<mbgl::Color> { intervalStops }; + + XCTAssertEqual(rawLayer->getHillshadeShadowColor(), propertyValue, + @"Setting hillshadeShadowColor to a camera function should update hillshade-shadow-color."); + XCTAssertEqualObjects(layer.hillshadeShadowColor, functionStyleValue, + @"hillshadeShadowColor should round-trip camera functions."); + + + + layer.hillshadeShadowColor = nil; + XCTAssertTrue(rawLayer->getHillshadeShadowColor().isUndefined(), + @"Unsetting hillshadeShadowColor should return hillshade-shadow-color to the default value."); + XCTAssertEqualObjects(layer.hillshadeShadowColor, defaultStyleValue, + @"hillshadeShadowColor should return the default value after being unset."); + + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeShadowColor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + functionStyleValue = [MGLStyleValue<MGLColor *> valueWithInterpolationMode:MGLInterpolationModeInterval compositeStops:@{@18: constantStyleValue} attributeName:@"" options:nil]; + XCTAssertThrowsSpecificNamed(layer.hillshadeShadowColor = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it"); + // Transition property test + layer.hillshadeShadowColorTransition = transitionTest; + auto toptions = rawLayer->getHillshadeShadowColorTransition(); + XCTAssert(toptions.delay && MGLTimeIntervalFromDuration(*toptions.delay) == transitionTest.delay); + XCTAssert(toptions.duration && MGLTimeIntervalFromDuration(*toptions.duration) == transitionTest.duration); + + MGLTransition hillshadeShadowColorTransition = layer.hillshadeShadowColorTransition; + XCTAssertEqual(hillshadeShadowColorTransition.delay, transitionTest.delay); + XCTAssertEqual(hillshadeShadowColorTransition.duration, transitionTest.duration); + } +} + +- (void)testPropertyNames { + [self testPropertyName:@"hillshade-accent-color" isBoolean:NO]; + [self testPropertyName:@"hillshade-exaggeration" isBoolean:NO]; + [self testPropertyName:@"hillshade-highlight-color" isBoolean:NO]; + [self testPropertyName:@"hillshade-illumination-anchor" isBoolean:NO]; + [self testPropertyName:@"hillshade-illumination-direction" isBoolean:NO]; + [self testPropertyName:@"hillshade-shadow-color" isBoolean:NO]; +} + +- (void)testValueAdditions { + XCTAssertEqual([NSValue valueWithMGLHillshadeIlluminationAnchor:MGLHillshadeIlluminationAnchorMap].MGLHillshadeIlluminationAnchorValue, MGLHillshadeIlluminationAnchorMap); + XCTAssertEqual([NSValue valueWithMGLHillshadeIlluminationAnchor:MGLHillshadeIlluminationAnchorViewport].MGLHillshadeIlluminationAnchorValue, MGLHillshadeIlluminationAnchorViewport); +} + +@end |