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

[core] Variable label placement #14184

Merged
merged 12 commits into from Mar 29, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 17 additions & 1 deletion platform/darwin/scripts/generate-style-code.js
Expand Up @@ -137,6 +137,8 @@ global.objCTestValue = function (property, layerType, arraysAsStructs, indent) {
}
return '@"{1, 1}"';
}
case 'anchor':
return `@"{'top','bottom'}"`;
default:
throw new Error(`unknown array type for ${property.name}`);
}
Expand Down Expand Up @@ -185,6 +187,8 @@ global.mbglTestValue = function (property, layerType) {
case 'offset':
case 'translate':
return '{ 1, 1 }';
case 'anchor':
return '{ mbgl::style::SymbolAnchorType::Top, mbgl::style::SymbolAnchorType::Bottom }';
default:
throw new Error(`unknown array type for ${property.name}`);
}
Expand All @@ -200,6 +204,13 @@ global.mbglExpressionTestValue = function (property, layerType) {
return `"${_.last(_.keys(property.values))}"`;
case 'color':
return 'mbgl::Color(1, 0, 0, 1)';
case 'array':
switch (arrayType(property)) {
case 'anchor':
return `{"top", "bottom"}`;
default:
break;
}
default:
return global.mbglTestValue(property, layerType);
}
Expand Down Expand Up @@ -539,11 +550,12 @@ global.propertyType = function (property) {
case 'font':
return 'NSArray<NSString *> *';
case 'padding':
return 'NSValue *';
case 'position':
case 'offset':
case 'translate':
return 'NSValue *';
case 'anchor':
return 'NSArray<NSValue *> *';
default:
throw new Error(`unknown array type for ${property.name}`);
}
Expand Down Expand Up @@ -588,6 +600,8 @@ global.valueTransformerArguments = function (property) {
case 'offset':
case 'translate':
return ['std::array<float, 2>', objCType];
case 'anchor':
return ['std::vector<mbgl::style::SymbolAnchorType>', objCType, 'mbgl::style::SymbolAnchorType', 'MGLTextAnchor'];
default:
throw new Error(`unknown array type for ${property.name}`);
}
Expand Down Expand Up @@ -637,6 +651,8 @@ global.mbglType = function(property) {
return 'std::array<float, 2>';
case 'position':
return 'mbgl::style::Position';
case 'anchor':
return 'std::vector<mbgl::style::SymbolAnchorType>';
default:
throw new Error(`unknown array type for ${property.name}`);
}
Expand Down
24 changes: 2 additions & 22 deletions platform/darwin/src/MGLStyleValue_Private.h
Expand Up @@ -307,10 +307,8 @@ class MGLStyleValueTransformer {

// Enumerations
template <typename MBGLEnum = MBGLType, typename MGLEnum = ObjCEnum>
static NSValue *toMGLRawStyleValue(const MBGLEnum &value) {
auto str = mbgl::Enum<MBGLEnum>::toString(value);
MGLEnum mglType = *mbgl::Enum<MGLEnum>::toEnum(str);
return [NSValue value:&mglType withObjCType:@encode(MGLEnum)];
static NSString *toMGLRawStyleValue(const MBGLEnum &value) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we changing NSValue to an NSString? Is there any MGLTextAnchor conversion error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previously existing method was never invoked - the currently removed

        template <typename MBGLEnum = MBGLType,
            class = typename std::enable_if<std::is_enum<MBGLEnum>::value>::type,
        typename MGLEnum = ObjCEnum,
            class = typename std::enable_if<std::is_enum<MGLEnum>::value>::type>
        NSExpression *operator()(const MBGLEnum &value) const {...}

was used instead. It worked fine for a single MGLTextAnchor instance, however std::vector< MGLTextAnchor> could not be handled.

return @(mbgl::Enum<MBGLEnum>::toString(value));
}

/// Converts all types of mbgl property values into an equivalent NSExpression.
Expand All @@ -320,15 +318,6 @@ class MGLStyleValueTransformer {
return nil;
}

/**
As hack to allow converting enum => string values, we accept a second, dummy parameter in
the toRawStyleSpecValue() methods for converting 'atomic' (non-style-function) values.
This allows us to use `std::enable_if` to test (at compile time) whether or not MBGLType is an Enum.
*/
template <typename MBGLEnum = MBGLType,
class = typename std::enable_if<!std::is_enum<MBGLEnum>::value>::type,
typename MGLEnum = ObjCEnum,
class = typename std::enable_if<!std::is_enum<MGLEnum>::value>::type>
NSExpression *operator()(const MBGLType &value) const {
id constantValue = toMGLRawStyleValue(value);
if ([constantValue isKindOfClass:[NSArray class]]) {
Expand All @@ -337,15 +326,6 @@ class MGLStyleValueTransformer {
return [NSExpression expressionForConstantValue:constantValue];
}

template <typename MBGLEnum = MBGLType,
class = typename std::enable_if<std::is_enum<MBGLEnum>::value>::type,
typename MGLEnum = ObjCEnum,
class = typename std::enable_if<std::is_enum<MGLEnum>::value>::type>
NSExpression *operator()(const MBGLEnum &value) const {
NSString *constantValue = @(mbgl::Enum<MBGLEnum>::toString(value));
return [NSExpression expressionForConstantValue:constantValue];
}

NSExpression *operator()(const mbgl::style::PropertyExpression<MBGLType> &mbglValue) const {
return [NSExpression expressionWithMGLJSONObject:MGLJSONObjectFromMBGLExpression(mbglValue.getExpression())];
}
Expand Down
60 changes: 56 additions & 4 deletions platform/darwin/src/MGLSymbolStyleLayer.h
Expand Up @@ -222,6 +222,10 @@ typedef NS_ENUM(NSUInteger, MGLTextAnchor) {
property.
*/
typedef NS_ENUM(NSUInteger, MGLTextJustification) {
/**
The text is aligned towards the anchor position.
*/
MGLTextJustificationAuto,
/**
The text is aligned to the left.
*/
Expand Down Expand Up @@ -1279,6 +1283,7 @@ MGL_EXPORT

* Constant `MGLTextJustification` values
* Any of the following constant string values:
* `auto`: The text is aligned towards the anchor position.
* `left`: The text is aligned to the left.
* `center`: The text is centered.
* `right`: The text is aligned to the right.
Expand Down Expand Up @@ -1349,8 +1354,8 @@ MGL_EXPORT
`NSValue` object containing a `CGVector` struct set to 0 ems rightward and 0
ems downward. Set this property to `nil` to reset it to the default value.

This property is only applied to the style if `text` is non-`nil`. Otherwise,
it is ignored.
This property is only applied to the style if `text` is non-`nil`, and
`textRadialOffset` is set to `nil`. Otherwise, it is ignored.

You can set this property to an expression containing any of the following:

Expand All @@ -1372,8 +1377,8 @@ MGL_EXPORT
`NSValue` object containing a `CGVector` struct set to 0 ems rightward and 0
ems upward. Set this property to `nil` to reset it to the default value.

This property is only applied to the style if `text` is non-`nil`. Otherwise,
it is ignored.
This property is only applied to the style if `text` is non-`nil`, and
`textRadialOffset` is set to `nil`. Otherwise, it is ignored.

You can set this property to an expression containing any of the following:

Expand Down Expand Up @@ -1463,6 +1468,27 @@ MGL_EXPORT
*/
@property (nonatomic, null_resettable) NSExpression *textPitchAlignment;

/**
Radial offset of text, in the direction of the symbol's anchor. Useful in
combination with `textVariableAnchor`, which doesn't support the
two-dimensional `textOffset`.

This property is measured in ems.
pozdnyakov marked this conversation as resolved.
Show resolved Hide resolved

This property is only applied to the style if `textOffset` is set to `nil`.
Otherwise, it is ignored.

You can set this property to an expression containing any of the following:

* Constant numeric values
* Predefined functions, including mathematical and string operators
* Conditional expressions
* Variable assignments and references to assigned variables
* Interpolation and step functions applied to the `$zoomLevel` variable and/or
feature attributes
*/
@property (nonatomic, null_resettable) NSExpression *textRadialOffset;

/**
Rotates the text clockwise.

Expand Down Expand Up @@ -1549,6 +1575,32 @@ MGL_EXPORT
*/
@property (nonatomic, null_resettable) NSExpression *textTransform;

/**
To increase the chance of placing high-priority labels on the map, you can
provide an array of `textAnchor` locations: the render will attempt to place
the label at each location, in order, before moving onto the next label. Use
`textJustify: auto` to choose justification based on anchor position. To apply
an offset, use the `textRadialOffset` instead of the two-dimensional
`textOffset`.

This property is only applied to the style if `textAnchor` is set to `nil`, and
`textOffset` is set to `nil`, and `symbolPlacement` is set to an expression
that evaluates to or `MGLSymbolPlacementPoint`. Otherwise, it is ignored.

You can set this property to an expression containing any of the following:

* Constant array values
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is accepts MGLTextAnchor values, the documentation should be similar to:

* Constant `MGLTextAnchor` values
* Any of the following constant string values:
* `center`: The center of the text is placed closest to the anchor.
* `left`: The left side of the text is placed closest to the anchor.
* `right`: The right side of the text is placed closest to the anchor.
* `top`: The top of the text is placed closest to the anchor.
* `bottom`: The bottom of the text is placed closest to the anchor.
* `top-left`: The top left corner of the text is placed closest to the
anchor.
* `top-right`: The top right corner of the text is placed closest to the
anchor.
* `bottom-left`: The bottom left corner of the text is placed closest to the
anchor.
* `bottom-right`: The bottom right corner of the text is placed closest to
the anchor.

* Predefined functions, including mathematical and string operators
* Conditional expressions
* Variable assignments and references to assigned variables
* Step functions applied to the `$zoomLevel` variable

This property does not support applying interpolation functions to the
`$zoomLevel` variable or applying interpolation or step functions to feature
attributes.
*/
@property (nonatomic, null_resettable) NSExpression *textVariableAnchor;

#pragma mark - Accessing the Paint Attributes

#if TARGET_OS_IPHONE
Expand Down
37 changes: 37 additions & 0 deletions platform/darwin/src/MGLSymbolStyleLayer.mm
Expand Up @@ -71,6 +71,7 @@
});

MBGL_DEFINE_ENUM(MGLTextJustification, {
{ MGLTextJustificationAuto, "auto" },
{ MGLTextJustificationLeft, "left" },
{ MGLTextJustificationCenter, "center" },
{ MGLTextJustificationRight, "right" },
Expand Down Expand Up @@ -906,6 +907,24 @@ - (NSExpression *)textPitchAlignment {
return MGLStyleValueTransformer<mbgl::style::AlignmentType, NSValue *, mbgl::style::AlignmentType, MGLTextPitchAlignment>().toExpression(propertyValue);
}

- (void)setTextRadialOffset:(NSExpression *)textRadialOffset {
MGLAssertStyleLayerIsValid();
MGLLogDebug(@"Setting textRadialOffset: %@", textRadialOffset);
alexshalamov marked this conversation as resolved.
Show resolved Hide resolved

auto mbglValue = MGLStyleValueTransformer<float, NSNumber *>().toPropertyValue<mbgl::style::PropertyValue<float>>(textRadialOffset, true);
self.rawLayer->setTextRadialOffset(mbglValue);
}

- (NSExpression *)textRadialOffset {
MGLAssertStyleLayerIsValid();

auto propertyValue = self.rawLayer->getTextRadialOffset();
if (propertyValue.isUndefined()) {
propertyValue = self.rawLayer->getDefaultTextRadialOffset();
}
return MGLStyleValueTransformer<float, NSNumber *>().toExpression(propertyValue);
}

- (void)setTextRotation:(NSExpression *)textRotation {
MGLAssertStyleLayerIsValid();
MGLLogDebug(@"Setting textRotation: %@", textRotation);
Expand Down Expand Up @@ -967,6 +986,24 @@ - (NSExpression *)textTransform {
return MGLStyleValueTransformer<mbgl::style::TextTransformType, NSValue *, mbgl::style::TextTransformType, MGLTextTransform>().toExpression(propertyValue);
}

- (void)setTextVariableAnchor:(NSExpression *)textVariableAnchor {
MGLAssertStyleLayerIsValid();
MGLLogDebug(@"Setting textVariableAnchor: %@", textVariableAnchor);
alexshalamov marked this conversation as resolved.
Show resolved Hide resolved

auto mbglValue = MGLStyleValueTransformer<std::vector<mbgl::style::SymbolAnchorType>, NSArray<NSValue *> *, mbgl::style::SymbolAnchorType, MGLTextAnchor>().toPropertyValue<mbgl::style::PropertyValue<std::vector<mbgl::style::SymbolAnchorType>>>(textVariableAnchor, false);
self.rawLayer->setTextVariableAnchor(mbglValue);
}

- (NSExpression *)textVariableAnchor {
MGLAssertStyleLayerIsValid();

auto propertyValue = self.rawLayer->getTextVariableAnchor();
if (propertyValue.isUndefined()) {
propertyValue = self.rawLayer->getDefaultTextVariableAnchor();
}
return MGLStyleValueTransformer<std::vector<mbgl::style::SymbolAnchorType>, NSArray<NSValue *> *, mbgl::style::SymbolAnchorType, MGLTextAnchor>().toExpression(propertyValue);
}

#pragma mark - Accessing the Paint Attributes

- (void)setIconColor:(NSExpression *)iconColor {
Expand Down