Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] Implement circle-pitch-alignment property
Browse files Browse the repository at this point in the history
Closes issue #9349.
  • Loading branch information
ChrisLoer committed Jul 6, 2017
1 parent 3800edb commit d5fbcb2
Show file tree
Hide file tree
Showing 18 changed files with 296 additions and 12 deletions.
2 changes: 2 additions & 0 deletions include/mbgl/style/conversion/make_property_setters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ auto makePaintPropertySetters() {
result["circle-translate-anchor-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCircleTranslateAnchorTransition>;
result["circle-pitch-scale"] = &setProperty<V, CircleLayer, PropertyValue<CirclePitchScaleType>, &CircleLayer::setCirclePitchScale>;
result["circle-pitch-scale-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCirclePitchScaleTransition>;
result["circle-pitch-alignment"] = &setProperty<V, CircleLayer, PropertyValue<AlignmentType>, &CircleLayer::setCirclePitchAlignment>;
result["circle-pitch-alignment-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCirclePitchAlignmentTransition>;
result["circle-stroke-width"] = &setProperty<V, CircleLayer, DataDrivenPropertyValue<float>, &CircleLayer::setCircleStrokeWidth>;
result["circle-stroke-width-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCircleStrokeWidthTransition>;
result["circle-stroke-color"] = &setProperty<V, CircleLayer, DataDrivenPropertyValue<Color>, &CircleLayer::setCircleStrokeColor>;
Expand Down
6 changes: 6 additions & 0 deletions include/mbgl/style/layers/circle_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ class CircleLayer : public Layer {
void setCirclePitchScaleTransition(const TransitionOptions&);
TransitionOptions getCirclePitchScaleTransition() const;

static PropertyValue<AlignmentType> getDefaultCirclePitchAlignment();
PropertyValue<AlignmentType> getCirclePitchAlignment() const;
void setCirclePitchAlignment(PropertyValue<AlignmentType>);
void setCirclePitchAlignmentTransition(const TransitionOptions&);
TransitionOptions getCirclePitchAlignmentTransition() const;

static DataDrivenPropertyValue<float> getDefaultCircleStrokeWidth();
DataDrivenPropertyValue<float> getCircleStrokeWidth() const;
void setCircleStrokeWidth(DataDrivenPropertyValue<float>);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,16 @@ public PropertyValue<String> getCirclePitchScale() {
return (PropertyValue<String>) new PropertyValue("circle-pitch-scale", nativeGetCirclePitchScale());
}

/**
* Get the CirclePitchAlignment property
*
* @return property wrapper value around String
*/
@SuppressWarnings("unchecked")
public PropertyValue<String> getCirclePitchAlignment() {
return (PropertyValue<String>) new PropertyValue("circle-pitch-alignment", nativeGetCirclePitchAlignment());
}

/**
* Get the CircleStrokeWidth property
*
Expand Down Expand Up @@ -411,6 +421,8 @@ public void setCircleStrokeOpacityTransition(TransitionOptions options) {

private native Object nativeGetCirclePitchScale();

private native Object nativeGetCirclePitchAlignment();

private native Object nativeGetCircleStrokeWidth();

private native TransitionOptions nativeGetCircleStrokeWidthTransition();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,27 @@ public final class Property {
@Retention(RetentionPolicy.SOURCE)
public @interface CIRCLE_PITCH_SCALE {}

// CIRCLE_PITCH_ALIGNMENT: Orientation of circle when map is pitched.

/**
* The circle is aligned to the plane of the map.
*/
public static final String CIRCLE_PITCH_ALIGNMENT_MAP = "map";
/**
* The circle is aligned to the plane of the viewport.
*/
public static final String CIRCLE_PITCH_ALIGNMENT_VIEWPORT = "viewport";

/**
* Orientation of circle when map is pitched.
*/
@StringDef({
CIRCLE_PITCH_ALIGNMENT_MAP,
CIRCLE_PITCH_ALIGNMENT_VIEWPORT,
})
@Retention(RetentionPolicy.SOURCE)
public @interface CIRCLE_PITCH_ALIGNMENT {}

// FILL_EXTRUSION_TRANSLATE_ANCHOR: Controls the translation reference point.

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,28 @@ public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> circle
return new PaintPropertyValue<>("circle-pitch-scale", function);
}

/**
* Orientation of circle when map is pitched.
*
* @param value a String value
* @return property wrapper around String
*/
public static PropertyValue<String> circlePitchAlignment(@Property.CIRCLE_PITCH_ALIGNMENT String value) {
return new PaintPropertyValue<>("circle-pitch-alignment", value);
}


/**
* Orientation of circle when map is pitched.
*
* @param <Z> the zoom parameter type
* @param function a wrapper {@link CameraFunction} for String
* @return property wrapper around a String function
*/
public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> circlePitchAlignment(CameraFunction<Z, String> function) {
return new PaintPropertyValue<>("circle-pitch-alignment", function);
}

/**
* The width of the circle's stroke. Strokes are placed outside of the {@link PropertyFactory#circleRadius}.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,44 @@ public void onInvokeAction(UiController uiController, MapboxMap mapboxMap) {
});
}

@Test
public void testCirclePitchAlignmentAsConstant() {
validateTestSetup();
setupLayer();
Timber.i("circle-pitch-alignment");
assertNotNull(layer);

// Set and Get
layer.setProperties(circlePitchAlignment(CIRCLE_PITCH_ALIGNMENT_MAP));
assertEquals((String) layer.getCirclePitchAlignment().getValue(), (String) CIRCLE_PITCH_ALIGNMENT_MAP);
}

@Test
public void testCirclePitchAlignmentAsCameraFunction() {
validateTestSetup();
setupLayer();
Timber.i("circle-pitch-alignment");
assertNotNull(layer);

// Set
layer.setProperties(
circlePitchAlignment(
zoom(
interval(
stop(2, circlePitchAlignment(CIRCLE_PITCH_ALIGNMENT_MAP))
)
)
)
);

// Verify
assertNotNull(layer.getCirclePitchAlignment());
assertNotNull(layer.getCirclePitchAlignment().getFunction());
assertEquals(CameraFunction.class, layer.getCirclePitchAlignment().getFunction().getClass());
assertEquals(IntervalStops.class, layer.getCirclePitchAlignment().getFunction().getStops().getClass());
assertEquals(1, ((IntervalStops) layer.getCirclePitchAlignment().getFunction().getStops()).size());
}

@Test
public void testCircleStrokeWidthTransition() {
validateTestSetup();
Expand Down
7 changes: 7 additions & 0 deletions platform/android/src/style/layers/circle_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ namespace android {
return jni::Object<jni::ObjectTag>(*converted);
}

jni::Object<jni::ObjectTag> CircleLayer::getCirclePitchAlignment(jni::JNIEnv& env) {
using namespace mbgl::android::conversion;
Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::CircleLayer>()->CircleLayer::getCirclePitchAlignment());
return jni::Object<jni::ObjectTag>(*converted);
}

jni::Object<jni::ObjectTag> CircleLayer::getCircleStrokeWidth(jni::JNIEnv& env) {
using namespace mbgl::android::conversion;
Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::CircleLayer>()->CircleLayer::getCircleStrokeWidth());
Expand Down Expand Up @@ -236,6 +242,7 @@ namespace android {
METHOD(&CircleLayer::getCircleTranslate, "nativeGetCircleTranslate"),
METHOD(&CircleLayer::getCircleTranslateAnchor, "nativeGetCircleTranslateAnchor"),
METHOD(&CircleLayer::getCirclePitchScale, "nativeGetCirclePitchScale"),
METHOD(&CircleLayer::getCirclePitchAlignment, "nativeGetCirclePitchAlignment"),
METHOD(&CircleLayer::getCircleStrokeWidthTransition, "nativeGetCircleStrokeWidthTransition"),
METHOD(&CircleLayer::setCircleStrokeWidthTransition, "nativeSetCircleStrokeWidthTransition"),
METHOD(&CircleLayer::getCircleStrokeWidth, "nativeGetCircleStrokeWidth"),
Expand Down
2 changes: 2 additions & 0 deletions platform/android/src/style/layers/circle_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class CircleLayer : public Layer {

jni::Object<jni::ObjectTag> getCirclePitchScale(jni::JNIEnv&);

jni::Object<jni::ObjectTag> getCirclePitchAlignment(jni::JNIEnv&);

jni::Object<jni::ObjectTag> getCircleStrokeWidth(jni::JNIEnv&);
void setCircleStrokeWidthTransition(jni::JNIEnv&, jlong duration, jlong delay);
jni::Object<TransitionOptions> getCircleStrokeWidthTransition(jni::JNIEnv&);
Expand Down
45 changes: 45 additions & 0 deletions platform/darwin/src/MGLCircleStyleLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,23 @@

NS_ASSUME_NONNULL_BEGIN

/**
Orientation of circle when map is pitched.
Values of this type are used in the `MGLCircleStyleLayer.circlePitchAlignment`
property.
*/
typedef NS_ENUM(NSUInteger, MGLCirclePitchAlignment) {
/**
The circle is aligned to the plane of the map.
*/
MGLCirclePitchAlignmentMap,
/**
The circle is aligned to the plane of the viewport.
*/
MGLCirclePitchAlignmentViewport,
};

/**
Controls the scaling behavior of the circle when the map is pitched.
Expand Down Expand Up @@ -220,6 +237,21 @@ MGL_EXPORT
*/
@property (nonatomic) MGLTransition circleOpacityTransition;

/**
Orientation of circle when map is pitched.
The default value of this property is an `MGLStyleValue` object containing an
`NSValue` object containing `MGLCirclePitchAlignmentViewport`. 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 *> *circlePitchAlignment;

/**
Circle radius.
Expand Down Expand Up @@ -490,6 +522,19 @@ MGL_EXPORT

#pragma mark Working with Circle Style Layer Attribute Values

/**
Creates a new value object containing the given `MGLCirclePitchAlignment` enumeration.
@param circlePitchAlignment The value for the new object.
@return A new value object that contains the enumeration value.
*/
+ (instancetype)valueWithMGLCirclePitchAlignment:(MGLCirclePitchAlignment)circlePitchAlignment;

/**
The `MGLCirclePitchAlignment` enumeration representation of the value.
*/
@property (readonly) MGLCirclePitchAlignment MGLCirclePitchAlignmentValue;

/**
Creates a new value object containing the given `MGLCircleScaleAlignment` enumeration.
Expand Down
32 changes: 32 additions & 0 deletions platform/darwin/src/MGLCircleStyleLayer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@

namespace mbgl {

MBGL_DEFINE_ENUM(MGLCirclePitchAlignment, {
{ MGLCirclePitchAlignmentMap, "map" },
{ MGLCirclePitchAlignmentViewport, "viewport" },
});

MBGL_DEFINE_ENUM(MGLCircleScaleAlignment, {
{ MGLCircleScaleAlignmentMap, "map" },
{ MGLCircleScaleAlignmentViewport, "viewport" },
Expand Down Expand Up @@ -187,6 +192,23 @@ - (MGLTransition)circleOpacityTransition {
return transition;
}

- (void)setCirclePitchAlignment:(MGLStyleValue<NSValue *> *)circlePitchAlignment {
MGLAssertStyleLayerIsValid();

auto mbglValue = MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLCirclePitchAlignment>().toEnumPropertyValue(circlePitchAlignment);
self.rawLayer->setCirclePitchAlignment(mbglValue);
}

- (MGLStyleValue<NSValue *> *)circlePitchAlignment {
MGLAssertStyleLayerIsValid();

auto propertyValue = self.rawLayer->getCirclePitchAlignment();
if (propertyValue.isUndefined()) {
return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLCirclePitchAlignment>().toEnumStyleValue(self.rawLayer->getDefaultCirclePitchAlignment());
}
return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLCirclePitchAlignment>().toEnumStyleValue(propertyValue);
}

- (void)setCircleRadius:(MGLStyleValue<NSNumber *> *)circleRadius {
MGLAssertStyleLayerIsValid();

Expand Down Expand Up @@ -421,6 +443,16 @@ - (void)setCircleTranslateAnchor:(MGLStyleValue<NSValue *> *)circleTranslateAnch

@implementation NSValue (MGLCircleStyleLayerAdditions)

+ (NSValue *)valueWithMGLCirclePitchAlignment:(MGLCirclePitchAlignment)circlePitchAlignment {
return [NSValue value:&circlePitchAlignment withObjCType:@encode(MGLCirclePitchAlignment)];
}

- (MGLCirclePitchAlignment)MGLCirclePitchAlignmentValue {
MGLCirclePitchAlignment circlePitchAlignment;
[self getValue:&circlePitchAlignment];
return circlePitchAlignment;
}

+ (NSValue *)valueWithMGLCircleScaleAlignment:(MGLCircleScaleAlignment)circleScaleAlignment {
return [NSValue value:&circleScaleAlignment withObjCType:@encode(MGLCircleScaleAlignment)];
}
Expand Down
42 changes: 42 additions & 0 deletions platform/darwin/test/MGLCircleStyleLayerTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,45 @@ - (void)testProperties {
XCTAssertEqual(circleOpacityTransition.duration, transitionTest.duration);
}

// circle-pitch-alignment
{
XCTAssertTrue(rawLayer->getCirclePitchAlignment().isUndefined(),
@"circle-pitch-alignment should be unset initially.");
MGLStyleValue<NSValue *> *defaultStyleValue = layer.circlePitchAlignment;

MGLStyleValue<NSValue *> *constantStyleValue = [MGLStyleValue<NSValue *> valueWithRawValue:[NSValue valueWithMGLCirclePitchAlignment:MGLCirclePitchAlignmentViewport]];
layer.circlePitchAlignment = constantStyleValue;
mbgl::style::PropertyValue<mbgl::style::AlignmentType> propertyValue = { mbgl::style::AlignmentType::Viewport };
XCTAssertEqual(rawLayer->getCirclePitchAlignment(), propertyValue,
@"Setting circlePitchAlignment to a constant value should update circle-pitch-alignment.");
XCTAssertEqualObjects(layer.circlePitchAlignment, constantStyleValue,
@"circlePitchAlignment should round-trip constant values.");

MGLStyleValue<NSValue *> * functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeInterval cameraStops:@{@18: constantStyleValue} options:nil];
layer.circlePitchAlignment = functionStyleValue;

mbgl::style::IntervalStops<mbgl::style::AlignmentType> intervalStops = { {{18, mbgl::style::AlignmentType::Viewport}} };
propertyValue = mbgl::style::CameraFunction<mbgl::style::AlignmentType> { intervalStops };

XCTAssertEqual(rawLayer->getCirclePitchAlignment(), propertyValue,
@"Setting circlePitchAlignment to a camera function should update circle-pitch-alignment.");
XCTAssertEqualObjects(layer.circlePitchAlignment, functionStyleValue,
@"circlePitchAlignment should round-trip camera functions.");



layer.circlePitchAlignment = nil;
XCTAssertTrue(rawLayer->getCirclePitchAlignment().isUndefined(),
@"Unsetting circlePitchAlignment should return circle-pitch-alignment to the default value.");
XCTAssertEqualObjects(layer.circlePitchAlignment, defaultStyleValue,
@"circlePitchAlignment should return the default value after being unset.");

functionStyleValue = [MGLStyleValue<NSValue *> valueWithInterpolationMode:MGLInterpolationModeIdentity sourceStops:nil attributeName:@"" options:nil];
XCTAssertThrowsSpecificNamed(layer.circlePitchAlignment = 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.circlePitchAlignment = functionStyleValue, NSException, NSInvalidArgumentException, @"MGLStyleValue should raise an exception if it is applied to a property that cannot support it");
}

// circle-radius
{
XCTAssertTrue(rawLayer->getCircleRadius().isUndefined(),
Expand Down Expand Up @@ -638,6 +677,7 @@ - (void)testPropertyNames {
[self testPropertyName:@"circle-blur" isBoolean:NO];
[self testPropertyName:@"circle-color" isBoolean:NO];
[self testPropertyName:@"circle-opacity" isBoolean:NO];
[self testPropertyName:@"circle-pitch-alignment" isBoolean:NO];
[self testPropertyName:@"circle-radius" isBoolean:NO];
[self testPropertyName:@"circle-scale-alignment" isBoolean:NO];
[self testPropertyName:@"circle-stroke-color" isBoolean:NO];
Expand All @@ -648,6 +688,8 @@ - (void)testPropertyNames {
}

- (void)testValueAdditions {
XCTAssertEqual([NSValue valueWithMGLCirclePitchAlignment:MGLCirclePitchAlignmentMap].MGLCirclePitchAlignmentValue, MGLCirclePitchAlignmentMap);
XCTAssertEqual([NSValue valueWithMGLCirclePitchAlignment:MGLCirclePitchAlignmentViewport].MGLCirclePitchAlignmentValue, MGLCirclePitchAlignmentViewport);
XCTAssertEqual([NSValue valueWithMGLCircleScaleAlignment:MGLCircleScaleAlignmentMap].MGLCircleScaleAlignmentValue, MGLCircleScaleAlignmentMap);
XCTAssertEqual([NSValue valueWithMGLCircleScaleAlignment:MGLCircleScaleAlignmentViewport].MGLCircleScaleAlignmentValue, MGLCircleScaleAlignmentViewport);
XCTAssertEqual([NSValue valueWithMGLCircleTranslationAnchor:MGLCircleTranslationAnchorMap].MGLCircleTranslationAnchorValue, MGLCircleTranslationAnchorMap);
Expand Down
4 changes: 3 additions & 1 deletion src/mbgl/programs/circle_program.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ class CircleProgram : public Program<
gl::Uniforms<
uniforms::u_matrix,
uniforms::u_scale_with_map,
uniforms::u_extrude_scale>,
uniforms::u_extrude_scale,
uniforms::u_camera_to_center_distance,
uniforms::u_pitch_with_map>,
style::CirclePaintProperties>
{
public:
Expand Down
1 change: 0 additions & 1 deletion src/mbgl/programs/symbol_program.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ class TransformState;

namespace uniforms {
MBGL_DEFINE_UNIFORM_SCALAR(bool, u_rotate_with_map);
MBGL_DEFINE_UNIFORM_SCALAR(bool, u_pitch_with_map);
MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_texture);
MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_fadetexture);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_aspect_ratio);
Expand Down
2 changes: 2 additions & 0 deletions src/mbgl/programs/uniforms.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ MBGL_DEFINE_UNIFORM_SCALAR(float, u_gapwidth);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_offset);
MBGL_DEFINE_UNIFORM_SCALAR(Size, u_world);
MBGL_DEFINE_UNIFORM_SCALAR(Size, u_texsize);
MBGL_DEFINE_UNIFORM_SCALAR(bool, u_pitch_with_map);
MBGL_DEFINE_UNIFORM_SCALAR(float, u_camera_to_center_distance);

MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_extrude_scale);

Expand Down
Loading

0 comments on commit d5fbcb2

Please sign in to comment.