[ios, macos] Add format expression convenience methods support. (#14094)

Added the ios/macos format expression bindings.

The equivalent is mgl_attributed: or mgl_attributed({}) when making an expression using the expressionForFormat selector.

A new constructor called mgl_expressionForAttributedExpressions:(NSArray<NSExpression*>*)attributedExpressions was added to NSExpression+MGLAdditions category.

Updated the symbol style layer text test to use the bindings.

Updated the Predicates and Expressions.md and For Style Authors.md.ejs template with the bindings.
This commit is contained in:
Fabian Guerra Soto
2019-03-15 16:10:27 -07:00
committed by GitHub
parent c8cfdb1ced
commit 7939ff213a
20 changed files with 329 additions and 22 deletions

View File

@@ -403,6 +403,7 @@ In style specification | Method, function, or predicate type | Format string syn
`zoom` | `NSExpression.zoomLevelVariableExpression` | `$zoomLevel`
`heatmap-density` | `NSExpression.heatmapDensityVariableExpression` | `$heatmapDensity`
`line-progress` | `NSExpression.lineProgressVariableExpression` | `$lineProgress`
`format` | `+[NSExpression mgl_expressionForAttributedExpressions:]` or `mgl_attributed:` | `mgl_attributed({x, y, z})`
For operators that have no corresponding `NSExpression` symbol, use the
`MGL_FUNCTION()` format string syntax.

View File

@@ -534,6 +534,22 @@ This function corresponds to the
[`coalesce`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-coalesce)
operator in the Mapbox Style Specification.
### `mgl_attributed:`
<dl>
<dt>Selector:</dt>
<dd><code>mgl_attributed:</code></dd>
<dt>Format string syntax:</dt>
<dd><code>mgl_attributed({x, y, z})</code></dd>
</dl>
Concatenates and returns the array of `MGLAttributedExpression` objects, for use
with the `MGLSymbolStyleLayer.text` property.
This function corresponds to the
[`format`](https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-types-format)
operator in the Mapbox Style Specification.
### `MGL_LET`
<dl>

View File

@@ -107,7 +107,7 @@ global.objCTestValue = function (property, layerType, arraysAsStructs, indent) {
// converts Formatted back to string.
return layerType === 'string' ?
`@"'${_.startCase(propertyName)}'"` :
`@"MGL_FUNCTION('format', '${_.startCase(propertyName)}', %@)", @{}`;
`@"${_.startCase(propertyName)}"`;
case 'string':
return `@"'${_.startCase(propertyName)}'"`;
case 'enum':

View File

@@ -0,0 +1,44 @@
#import "MGLFoundation.h"
NS_ASSUME_NONNULL_BEGIN
typedef NSString * MGLAttributedExpressionKey NS_EXTENSIBLE_STRING_ENUM;
FOUNDATION_EXTERN MGL_EXPORT MGLAttributedExpressionKey const MGLFontNamesAttribute;
FOUNDATION_EXTERN MGL_EXPORT MGLAttributedExpressionKey const MGLFontSizeAttribute;
/**
An `MGLAttributedExpression` object associates text formatting attibutes (such as font size or
font names) to an `NSExpression`.
*/
MGL_EXPORT
@interface MGLAttributedExpression : NSObject
/**
The expression content of the receiver as `NSExpression`.
*/
@property (strong, nonatomic) NSExpression *expression;
/**
The formatting attributes.
*/
@property (strong, nonatomic, readonly) NSDictionary<MGLAttributedExpressionKey, id> *attributes;
/**
Returns an `MGLAttributedExpression` object initialized with an expression and no attribute information.
*/
- (instancetype)initWithExpression:(NSExpression *)expression;
/**
Returns an `MGLAttributedExpression` object initialized with an expression and text format attributes.
*/
- (instancetype)initWithExpression:(NSExpression *)expression attributes:(nullable NSDictionary <MGLAttributedExpressionKey, id> *)attrs;
/**
Creates an `MGLAttributedExpression` object initialized with an expression and the format attributes for font names and font size.
*/
+ (instancetype)attributedExpression:(NSExpression *)expression fontNames:(nullable NSArray<NSString*> *)fontNames fontSize:(nullable NSNumber *)fontSize;
@end
NS_ASSUME_NONNULL_END

View File

@@ -0,0 +1,59 @@
#import "MGLAttributedExpression.h"
#import "MGLLoggingConfiguration_Private.h"
const MGLAttributedExpressionKey MGLFontNamesAttribute = @"text-font";
const MGLAttributedExpressionKey MGLFontSizeAttribute = @"font-scale";
@implementation MGLAttributedExpression
- (instancetype)initWithExpression:(NSExpression *)expression {
self = [self initWithExpression:expression attributes:nil];
return self;
}
+ (instancetype)attributedExpression:(NSExpression *)expression fontNames:(nullable NSArray<NSString *> *)fontNames fontSize:(nullable NSNumber *)fontSize {
MGLAttributedExpression *attributedExpression;
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
if (fontNames && fontNames.count > 0) {
attrs[MGLFontNamesAttribute] = fontNames;
}
if (fontSize) {
attrs[MGLFontSizeAttribute] = fontSize;
}
attributedExpression = [[self alloc] initWithExpression:expression attributes:attrs];
return attributedExpression;
}
- (instancetype)initWithExpression:(NSExpression *)expression attributes:(NSDictionary<MGLAttributedExpressionKey,id> *)attrs {
if (self = [super init])
{
MGLLogInfo(@"Starting %@ initialization.", NSStringFromClass([self class]));
_expression = expression;
_attributes = attrs;
MGLLogInfo(@"Finalizing %@ initialization.", NSStringFromClass([self class]));
}
return self;
}
- (BOOL)isEqual:(id)object {
BOOL result = NO;
if ([object isKindOfClass:[self class]]) {
MGLAttributedExpression *otherObject = object;
result = [self.expression isEqual:otherObject.expression] &&
[_attributes isEqual:otherObject.attributes];
}
return result;
}
- (NSString *)description {
return [NSString stringWithFormat:@"MGLAttributedExpression<Expression: %@ Attributes: %@>", self.expression, self.attributes];
}
@end

View File

@@ -7,6 +7,8 @@
#import "MGLTypes.h"
@class MGLAttributedExpression;
NS_ASSUME_NONNULL_BEGIN
typedef NSString *MGLExpressionInterpolationMode NS_TYPED_ENUM;
@@ -150,6 +152,14 @@ FOUNDATION_EXTERN MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionI
*/
+ (instancetype)mgl_expressionForMatchingExpression:(nonnull NSExpression *)inputExpression inDictionary:(nonnull NSDictionary<NSExpression *, NSExpression *> *)matchedExpressions defaultExpression:(nonnull NSExpression *)defaultExpression NS_SWIFT_NAME(init(forMGLMatchingKey:in:default:));
/**
Returns an attributed function expression specifying an `MGLAttributedExpression` constant
expression array.
@param attributedExpressions The `MGLAttributedExpression` constant expression array.
*/
+ (instancetype)mgl_expressionForAttributedExpressions:(nonnull NSArray<NSExpression *> *)attributedExpressions NS_SWIFT_NAME(init(forAttributedExpressions:));
#pragma mark Concatenating String Expressions
/**

View File

@@ -11,6 +11,7 @@
#import "NSPredicate+MGLAdditions.h"
#import "NSValue+MGLStyleAttributeAdditions.h"
#import "MGLVectorTileSource_Private.h"
#import "MGLAttributedExpression.h"
#import <objc/runtime.h>
@@ -75,6 +76,7 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier =
INSTALL_METHOD(mgl_atan:);
INSTALL_METHOD(mgl_tan:);
INSTALL_METHOD(mgl_log2:);
INSTALL_METHOD(mgl_attributed:);
// Install functions that resemble control structures, taking arbitrary
// numbers of arguments. Vararg aftermarket functions need to be declared
@@ -96,6 +98,12 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier =
return [components componentsJoinedByString:@""];
}
- (NSString *)mgl_attributed:(NSArray<MGLAttributedExpression *> *)attributedExpressions {
[NSException raise:NSInvalidArgumentException
format:@"Text format expressions lack underlying Objective-C implementations."];
return nil;
}
/**
Rounds the given number to the nearest integer. If the number is halfway
between two integers, this method rounds it away from zero.
@@ -229,7 +237,6 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier =
return nil;
}
/**
A placeholder for a catch-all method that evaluates an arbitrary number of
arguments as an expression according to the Mapbox Style Specification’s
@@ -591,6 +598,10 @@ const MGLExpressionInterpolationMode MGLExpressionInterpolationModeCubicBezier =
arguments:optionsArray];
}
+ (instancetype)mgl_expressionForAttributedExpressions:(nonnull NSArray<NSExpression *> *)attributedExpressions {
return [NSExpression expressionForFunction:@"mgl_attributed:" arguments:attributedExpressions];
}
- (instancetype)mgl_expressionByAppendingExpression:(nonnull NSExpression *)expression {
NSExpression *subexpression = [NSExpression expressionForAggregate:@[self, expression]];
return [NSExpression expressionForFunction:@"mgl_join:" arguments:@[subexpression]];
@@ -860,6 +871,22 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
return [NSExpression expressionForFunction:@"MGL_MATCH"
arguments:optionsArray];
} else if ([op isEqualToString:@"format"]) {
NSMutableArray *attributedExpressions = [NSMutableArray array];
for (NSUInteger index = 0; index < argumentObjects.count; index+=2) {
NSExpression *expression = [NSExpression expressionWithMGLJSONObject:argumentObjects[index]];
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
if ((index + 1) < argumentObjects.count) {
attrs = argumentObjects[index + 1];
}
MGLAttributedExpression *attributedExpression = [[MGLAttributedExpression alloc] initWithExpression:expression attributes:attrs];
[attributedExpressions addObject:[NSExpression expressionForConstantValue:attributedExpression]];
}
return [NSExpression expressionForFunction:@"mgl_attributed:" arguments:attributedExpressions];
} else if ([op isEqualToString:@"coalesce"]) {
NSMutableArray *expressions = [NSMutableArray array];
for (id operand in argumentObjects) {
@@ -971,6 +998,23 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
return @[@"literal", @[@(mglValue[0]), @(mglValue[1]), @(mglValue[2]), @(mglValue[3])]];
}
}
if ([constantValue isKindOfClass:[MGLAttributedExpression class]]) {
MGLAttributedExpression *attributedExpression = (MGLAttributedExpression *)constantValue;
id jsonObject = attributedExpression.expression.mgl_jsonExpressionObject;
NSMutableArray *attributes = [NSMutableArray array];
if ([jsonObject isKindOfClass:[NSArray class]]) {
[attributes addObjectsFromArray:jsonObject];
} else {
[attributes addObject:jsonObject];
}
if (attributedExpression.attributes) {
[attributes addObject:attributedExpression.attributes];
} else {
[attributes addObject:@{}];
}
return attributes;
}
return self.constantValue;
}
@@ -1115,6 +1159,9 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
}
[NSException raise:NSInvalidArgumentException
format:@"Casting expression to %@ not yet implemented.", type];
} else if ([function isEqualToString:@"mgl_attributed:"]) {
return [self mgl_jsonFormatExpressionObject];
} else if ([function isEqualToString:@"MGL_FUNCTION"] ||
[function isEqualToString:@"MGL_FUNCTION:"]) {
NSExpression *firstOp = self.arguments.firstObject;
@@ -1363,6 +1410,25 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
return expressionObject;
}
- (id)mgl_jsonFormatExpressionObject {
NSArray<NSExpression *> *attributedExpressions;
NSExpression *formatArray = self.arguments.firstObject;
if ([formatArray respondsToSelector:@selector(constantValue)] && [formatArray.constantValue isKindOfClass:[NSArray class]]) {
attributedExpressions = (NSArray *)formatArray.constantValue;
} else {
attributedExpressions = self.arguments;
}
NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"format", nil];
for (NSUInteger index = 0; index < attributedExpressions.count; index++) {
[expressionObject addObjectsFromArray:attributedExpressions[index].mgl_jsonExpressionObject];
}
return expressionObject;
}
#pragma mark Localization
/**

View File

@@ -12,6 +12,7 @@
#else
#import "NSColor+MGLAdditions.h"
#endif
#import "MGLAttributedExpression.h"
#define MGLAssertEqualValues(actual, expected, ...) \
XCTAssertTrue(actual.is<__typeof__(expected)>()); \
@@ -990,6 +991,87 @@ using namespace std::string_literals;
}
}
- (void)testFormatExpressionObject {
{
MGLAttributedExpression *attribute1 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"foo"]
fontNames:nil
fontSize:@(1.2)];
MGLAttributedExpression *attribute2 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"biz"]
fontNames:nil
fontSize:@(1.0)];
MGLAttributedExpression *attribute3 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"bar"]
fontNames:nil
fontSize:@(0.8)];
MGLAttributedExpression *attribute4 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"\r"]
fontNames:@[]
fontSize:nil];
NSExpression *expression = [NSExpression expressionWithFormat:@"mgl_attributed:(%@, %@, %@, %@)",
MGLConstantExpression(attribute1),
MGLConstantExpression(attribute4),
MGLConstantExpression(attribute2),
MGLConstantExpression(attribute3)];
NSArray *jsonExpression = @[@"format", @"foo", @{@"font-scale": @1.2}, @"\r", @{}, @"biz", @{@"font-scale": @1.0}, @"bar", @{@"font-scale": @0.8}];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression);
}
{
MGLAttributedExpression *attribute1 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"foo"]
fontNames:nil
fontSize:@(1.2)];
MGLAttributedExpression *attribute2 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"biz"]
fontNames:nil
fontSize:@(1.0)];
MGLAttributedExpression *attribute3 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"bar"]
fontNames:nil
fontSize:@(0.8)];
MGLAttributedExpression *attribute4 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"\n"]
fontNames:@[]
fontSize:nil];
NSExpression *expression = [NSExpression expressionWithFormat:@"mgl_attributed:(%@, %@, %@, %@)",
MGLConstantExpression(attribute1),
MGLConstantExpression(attribute4),
MGLConstantExpression(attribute2),
MGLConstantExpression(attribute3)];
NSArray *jsonExpression = @[@"format", @"foo", @{@"font-scale": @1.2}, @"\n", @{}, @"biz", @{@"font-scale": @1.0}, @"bar", @{@"font-scale": @0.8}];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression);
}
{
MGLAttributedExpression *attribute1 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"foo"]
fontNames:nil
fontSize:@(1.2)];
NSExpression *expression = [NSExpression expressionWithFormat:@"mgl_attributed:(%@)", MGLConstantExpression(attribute1)];
NSExpression *compatibilityExpression = [NSExpression expressionForFunction:@"mgl_attributed:" arguments:@[MGLConstantExpression(attribute1)]];
NSArray *jsonExpression = @[@"format", @"foo", @{@"font-scale": @1.2}];
XCTAssertEqualObjects(compatibilityExpression.mgl_jsonExpressionObject, expression.mgl_jsonExpressionObject);
XCTAssertEqualObjects(compatibilityExpression, expression);
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression);
}
{
MGLAttributedExpression *attribute1 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"foo"]
fontNames:nil
fontSize:@(1.2)];
MGLAttributedExpression *attribute2 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"biz"]
fontNames:nil
fontSize:@(1.0)];
MGLAttributedExpression *attribute3 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"bar"]
fontNames:nil
fontSize:@(0.8)];
MGLAttributedExpression *attribute4 = [MGLAttributedExpression attributedExpression:[NSExpression expressionForConstantValue:@"\n"]
fontNames:@[]
fontSize:nil];
NSExpression *expression = [NSExpression mgl_expressionForAttributedExpressions:@[MGLConstantExpression(attribute1),
MGLConstantExpression(attribute4),
MGLConstantExpression(attribute2),
MGLConstantExpression(attribute3)]];
NSArray *jsonExpression = @[@"format", @"foo", @{@"font-scale": @1.2}, @"\n", @{}, @"biz", @{@"font-scale": @1.0}, @"bar", @{@"font-scale": @0.8}];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression);
}
}
- (void)testGenericExpressionObject {
{
NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('random', 1, 2, 3, 4, 5)"];
@@ -1001,23 +1083,6 @@ using namespace std::string_literals;
NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('random', 1, 2, 3, 4)"];
XCTAssertThrowsSpecificNamed([expression expressionValueWithObject:nil context:nil], NSException, NSInvalidArgumentException);
}
{
NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('format', 'foo', %@, '\r', %@, 'biz', %@, 'bar', %@)", @{@"font-scale": @1.2}, @{}, @{@"font-scale": @1.0}, @{@"font-scale": @0.8}];
NSArray *jsonExpression = @[@"format", @"foo", @{@"font-scale": @1.2}, @"\r", @{}, @"biz", @{@"font-scale": @1.0}, @"bar", @{@"font-scale": @0.8}];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
NSExpression *encodedExpression = [NSExpression expressionWithMGLJSONObject:jsonExpression];
// Expressions encoded from a json create a different constant abstract type
// thus even tho knowing that the constant values are the same, the base
// class is not. This compares the resulting array which is type agnostic encoding.
for (NSUInteger index = 0; index < jsonExpression.count; index++) {
NSExpression *left = encodedExpression.mgl_jsonExpressionObject[index];
NSExpression *right = expression.mgl_jsonExpressionObject[index];
XCTAssertEqualObjects(left.mgl_jsonExpressionObject, right.mgl_jsonExpressionObject);
}
}
{
NSArray *arguments = @[
MGLConstantExpression(@"one"), MGLConstantExpression(@1),

View File

@@ -8,6 +8,9 @@
#import "MGLStyleLayerTests.h"
#import "../../darwin/src/NSDate+MGLAdditions.h"
<% if (type === 'symbol') { -%>
#include "../../darwin/src/MGLAttributedExpression.h"
<% } -%>
#import "MGLStyleLayer_Private.h"
@@ -80,7 +83,13 @@
XCTAssertEqualObjects(layer.<%- objCName(property) %>, constantExpression,
@"<%- objCName(property) %> should round-trip constant value expressions.");
<% if (property.type !== 'formatted') { -%>
constantExpression = [NSExpression expressionWithFormat:<%- objCTestValue(property, type, false, 3) %>];
<% } else { -%>
MGLAttributedExpression *attributedConstantExpression = [[MGLAttributedExpression alloc] initWithExpression:[NSExpression expressionWithFormat:<%- objCTestValue(property, 'string', true, 3) %>]
attributes:@{}];
constantExpression = [NSExpression mgl_expressionForAttributedExpressions:@[[NSExpression expressionForConstantValue:attributedConstantExpression]]];
<% } -%>
NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}];
layer.<%- objCName(property) %> = functionExpression;
@@ -180,7 +189,9 @@
@"Setting <%- objCName(property) %> to a constant string with tokens should convert to an expression.");
<% if (property.type === 'formatted') { -%>
NSExpression* tokenExpression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('format', CAST(token, 'NSString'), %@)", @{}];
MGLAttributedExpression *tokenAttibutedExpression = [[MGLAttributedExpression alloc] initWithExpression:[NSExpression expressionWithFormat:@"CAST(token, 'NSString')"]
attributes:@{}];
NSExpression* tokenExpression = [NSExpression mgl_expressionForAttributedExpressions:@[[NSExpression expressionForConstantValue:tokenAttibutedExpression]]];
<% } else { -%>
NSExpression* tokenExpression = [NSExpression expressionWithFormat:@"CAST(token, \"NSString\")"];
<% } -%>

View File

@@ -3,6 +3,7 @@
#import "MGLStyleLayerTests.h"
#import "../../darwin/src/NSDate+MGLAdditions.h"
#include "../../darwin/src/MGLAttributedExpression.h"
#import "MGLStyleLayer_Private.h"
@@ -1104,7 +1105,9 @@
XCTAssertEqualObjects(layer.text, constantExpression,
@"text should round-trip constant value expressions.");
constantExpression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('format', 'Text Field', %@)", @{}];
MGLAttributedExpression *attributedConstantExpression = [[MGLAttributedExpression alloc] initWithExpression:[NSExpression expressionWithFormat:@"'Text Field'"]
attributes:@{}];
constantExpression = [NSExpression mgl_expressionForAttributedExpressions:@[[NSExpression expressionForConstantValue:attributedConstantExpression]]];
NSExpression *functionExpression = [NSExpression expressionWithFormat:@"mgl_step:from:stops:($zoomLevel, %@, %@)", constantExpression, @{@18: constantExpression}];
layer.text = functionExpression;
@@ -1140,7 +1143,9 @@
XCTAssertEqual(rawLayer->getTextField(), propertyValue,
@"Setting text to a constant string with tokens should convert to an expression.");
NSExpression* tokenExpression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('format', CAST(token, 'NSString'), %@)", @{}];
MGLAttributedExpression *tokenAttibutedExpression = [[MGLAttributedExpression alloc] initWithExpression:[NSExpression expressionWithFormat:@"CAST(token, 'NSString')"]
attributes:@{}];
NSExpression* tokenExpression = [NSExpression mgl_expressionForAttributedExpressions:@[[NSExpression expressionForConstantValue:tokenAttibutedExpression]]];
XCTAssertEqualObjects(layer.text, tokenExpression,
@"Setting text to a constant string with tokens should convert to an expression.");
}

View File

@@ -8,6 +8,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Added an MGLMapView.prefetchesTiles property that you can disable if you don’t want to prefetch simplified tiles as a performance optimization. ([#14031](https://github.com/mapbox/mapbox-gl-native/pull/14031))
* Fixed an issue that caused `MGL_FUNCTION` to ignore multiple formatting parameters when passed a `format` function as parameter. ([#14064](https://github.com/mapbox/mapbox-gl-native/pull/14064))
* Added a Galician localization. ([#14095](https://github.com/mapbox/mapbox-gl-native/pull/14095))
* Added `mgl_attributed:` expression operator, which concatenate `MGLAttributedExpression` objects for specifying rich text in the `MGLSymbolStyleLayer.text` property. ([#14094](https://github.com/mapbox/mapbox-gl-native/pull/14094))
### User interaction

View File

@@ -390,6 +390,7 @@ In style specification | Method, function, or predicate type | Format string syn
`zoom` | `NSExpression.zoomLevelVariableExpression` | `$zoomLevel`
`heatmap-density` | `NSExpression.heatmapDensityVariableExpression` | `$heatmapDensity`
`line-progress` | `NSExpression.lineProgressVariableExpression` | `$lineProgress`
`format` | `+[NSExpression mgl_expressionForAttributedExpressions:]` or `mgl_attributed:` | `mgl_attributed({x, y, z})`
For operators that have no corresponding `NSExpression` symbol, use the
`MGL_FUNCTION()` format string syntax.

View File

@@ -57,6 +57,10 @@
1FCAE2A520B872A400C577DD /* MGLLocationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FCAE2A120B872A400C577DD /* MGLLocationManager.m */; };
1FCAE2A820B88B3800C577DD /* MGLLocationManager_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FCAE2A620B88B3800C577DD /* MGLLocationManager_Private.h */; };
1FCAE2A920B88B3800C577DD /* MGLLocationManager_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FCAE2A620B88B3800C577DD /* MGLLocationManager_Private.h */; };
1FF48587223710BE00F19727 /* MGLAttributedExpression.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF48585223710BE00F19727 /* MGLAttributedExpression.h */; settings = {ATTRIBUTES = (Public, ); }; };
1FF48588223710BE00F19727 /* MGLAttributedExpression.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF48585223710BE00F19727 /* MGLAttributedExpression.h */; settings = {ATTRIBUTES = (Public, ); }; };
1FF48589223710BE00F19727 /* MGLAttributedExpression.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF48586223710BE00F19727 /* MGLAttributedExpression.m */; };
1FF4858A223710BE00F19727 /* MGLAttributedExpression.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF48586223710BE00F19727 /* MGLAttributedExpression.m */; };
30E578171DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */; };
30E578181DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */; };
30E578191DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 30E578121DAA7D690050F07E /* UIImage+MGLAdditions.mm */; };
@@ -887,6 +891,8 @@
1FDB00C921F8F15000D21389 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = cs; path = cs.lproj/Foundation.stringsdict; sourceTree = "<group>"; };
1FDB00CA21F8F15100D21389 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
1FDB00CB21F8F15300D21389 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = cs; path = cs.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
1FF48585223710BE00F19727 /* MGLAttributedExpression.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLAttributedExpression.h; sourceTree = "<group>"; };
1FF48586223710BE00F19727 /* MGLAttributedExpression.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLAttributedExpression.m; sourceTree = "<group>"; };
20DABE861DF78148007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Foundation.strings"; sourceTree = "<group>"; };
20DABE881DF78148007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+MGLAdditions.h"; path = "src/UIImage+MGLAdditions.h"; sourceTree = SOURCE_ROOT; };
@@ -2086,6 +2092,8 @@
DA00FC8C1D5EEB0D009AABC8 /* MGLAttributionInfo.h */,
DAF0D8171DFE6B2800B28378 /* MGLAttributionInfo_Private.h */,
DA00FC8D1D5EEB0D009AABC8 /* MGLAttributionInfo.mm */,
1FF48585223710BE00F19727 /* MGLAttributedExpression.h */,
1FF48586223710BE00F19727 /* MGLAttributedExpression.m */,
556660C91E1BF3A900E2C41B /* MGLFoundation.h */,
558DE79E1E5615E400C7916D /* MGLFoundation_Private.h */,
558DE79F1E5615E400C7916D /* MGLFoundation.mm */,
@@ -2502,6 +2510,7 @@
30E578171DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */,
96036A01200565C700510F3D /* NSOrthography+MGLAdditions.h in Headers */,
1F7454961ECD450D00021D39 /* MGLLight_Private.h in Headers */,
1FF48587223710BE00F19727 /* MGLAttributedExpression.h in Headers */,
DAD1656C1CF41981001FF4B9 /* MGLFeature.h in Headers */,
40EDA1C01CFE0E0200D9EA68 /* MGLAnnotationContainerView.h in Headers */,
9620BB381E69FE1700705A1D /* MGLSDKUpdateChecker.h in Headers */,
@@ -2658,6 +2667,7 @@
353AFA151D65AB17005A69F4 /* NSDate+MGLAdditions.h in Headers */,
AC518E00201BB55A00EBC820 /* MGLTelemetryConfig.h in Headers */,
3510FFFA1D6DCC4700F413B2 /* NSCompoundPredicate+MGLAdditions.h in Headers */,
1FF48588223710BE00F19727 /* MGLAttributedExpression.h in Headers */,
DA72620C1DEEE3480043BB89 /* MGLOpenGLStyleLayer.h in Headers */,
35CE61831D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */,
96E516F32000597100A02306 /* NSDictionary+MGLAdditions.h in Headers */,
@@ -3267,6 +3277,7 @@
DA8848291CBAFA6200AB86E3 /* MGLStyle.mm in Sources */,
357FE2DF1E02D2B20068B753 /* NSCoder+MGLAdditions.mm in Sources */,
40834BF81FE05E1800C1BD0D /* NSData+MMEGZIP.m in Sources */,
1FF48589223710BE00F19727 /* MGLAttributedExpression.m in Sources */,
DA88481C1CBAFA6200AB86E3 /* MGLGeometry.mm in Sources */,
558DE7A21E5615E400C7916D /* MGLFoundation.mm in Sources */,
40834BE91FE05E1800C1BD0D /* MMECommonEventData.m in Sources */,
@@ -3404,6 +3415,7 @@
3510FFF31D6D9D8C00F413B2 /* NSExpression+MGLAdditions.mm in Sources */,
40834C0C1FE05E1800C1BD0D /* NSData+MMEGZIP.m in Sources */,
DAA4E4321CBB730400178DFB /* MGLMapView.mm in Sources */,
1FF4858A223710BE00F19727 /* MGLAttributedExpression.m in Sources */,
40834BFD1FE05E1800C1BD0D /* MMECommonEventData.m in Sources */,
DAA4E41E1CBB730400178DFB /* MGLMapCamera.mm in Sources */,
FA68F14E1E9D656600F9F6C2 /* MGLFillExtrusionStyleLayer.mm in Sources */,

View File

@@ -89,6 +89,7 @@
"platform/darwin/src/MGLStyle.mm",
"platform/darwin/src/NSCoder+MGLAdditions.mm",
"platform/ios/vendor/mapbox-events-ios/MapboxMobileEvents/NSData+MMEGZIP.m",
"platform/darwin/src/MGLAttributedExpression.m",
"platform/darwin/src/MGLGeometry.mm",
"platform/darwin/src/MGLFoundation.mm",
"platform/ios/vendor/mapbox-events-ios/MapboxMobileEvents/MMECommonEventData.m",
@@ -187,6 +188,7 @@
"MGLHeatmapStyleLayer.h": "platform/darwin/src/MGLHeatmapStyleLayer.h",
"MGLCircleStyleLayer.h": "platform/darwin/src/MGLCircleStyleLayer.h",
"MGLMultiPoint.h": "platform/darwin/src/MGLMultiPoint.h",
"MGLAttributedExpression.h": "platform/darwin/src/MGLAttributedExpression.h",
"MGLFeature.h": "platform/darwin/src/MGLFeature.h",
"MGLMapCamera.h": "platform/darwin/src/MGLMapCamera.h",
"MGLForegroundStyleLayer.h": "platform/darwin/src/MGLForegroundStyleLayer.h",

View File

@@ -72,3 +72,4 @@ FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[];
#import "MGLLocationManager.h"
#import "MGLLoggingConfiguration.h"
#import "MGLNetworkConfiguration.h"
#import "MGLAttributedExpression.h"

View File

@@ -9,6 +9,7 @@
* Added the `-[MGLShapeSource leavesOfCluster:offset:limit:]`, `-[MGLShapeSource childrenOfCluster:]`, `-[MGLShapeSource zoomLevelForExpandingCluster:]` methods for inspecting a cluster in an `MGLShapeSource`s created with the `MGLShapeSourceOptionClustered` option. Feature querying now returns clusters represented by `MGLPointFeatureCluster` objects (that conform to the `MGLCluster` protocol). ([#12952](https://github.com/mapbox/mapbox-gl-native/pull/12952)
* Added `MGLNetworkConfiguration` class to customize the SDK's `NSURLSessionConfiguration` object. ([#11447](https://github.com/mapbox/mapbox-gl-native/pull/13886))
* Fixed an issue that caused `MGL_FUNCTION` to ignore multiple formatting parameters when passed a `format` function as parameter. ([#14064](https://github.com/mapbox/mapbox-gl-native/pull/14064))
* Added `mgl_attributed:` expression operator, which concatenate `MGLAttributedExpression` objects for specifying rich text in the `MGLSymbolStyleLayer.text` property. ([#14094](https://github.com/mapbox/mapbox-gl-native/pull/14094))
### Annotations

View File

@@ -383,6 +383,7 @@ In style specification | Method, function, or predicate type | Format string syn
`zoom` | `NSExpression.zoomLevelVariableExpression` | `$zoomLevel`
`heatmap-density` | `NSExpression.heatmapDensityVariableExpression` | `$heatmapDensity`
`line-progress` | `NSExpression.lineProgressVariableExpression` | `$lineProgress`
`format` | `+[NSExpression mgl_expressionForAttributedExpressions:]` or `mgl_attributed:` | `mgl_attributed({x, y, z})`
For operators that have no corresponding `NSExpression` symbol, use the
`MGL_FUNCTION()` format string syntax.

View File

@@ -29,6 +29,8 @@
1F95931B1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F95931A1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm */; };
1F9EF4061FBA1B0E0063FBB0 /* mapbox_helmet.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 1F9EF4051FBA1B0D0063FBB0 /* mapbox_helmet.pdf */; };
1FC481852098F323000D09B4 /* NSPredicate+MGLPrivateAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FC481842098F323000D09B4 /* NSPredicate+MGLPrivateAdditions.h */; };
1FF4858D2237235300F19727 /* MGLAttributedExpression.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FF4858B2237235200F19727 /* MGLAttributedExpression.m */; };
1FF4858E2237235300F19727 /* MGLAttributedExpression.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FF4858C2237235200F19727 /* MGLAttributedExpression.h */; settings = {ATTRIBUTES = (Public, ); }; };
3508EC641D749D39009B0EE4 /* NSExpression+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
3508EC651D749D39009B0EE4 /* NSExpression+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */; };
3526EABD1DF9B19800006B43 /* MGLCodingTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3526EABC1DF9B19800006B43 /* MGLCodingTests.mm */; };
@@ -343,6 +345,8 @@
1FC481842098F323000D09B4 /* NSPredicate+MGLPrivateAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSPredicate+MGLPrivateAdditions.h"; sourceTree = "<group>"; };
1FDB00CC21F8F1FD00D21389 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
1FDB00CD21F8F1FF00D21389 /* cs */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/Localizable.strings; sourceTree = "<group>"; };
1FF4858B2237235200F19727 /* MGLAttributedExpression.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLAttributedExpression.m; sourceTree = "<group>"; };
1FF4858C2237235200F19727 /* MGLAttributedExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAttributedExpression.h; sourceTree = "<group>"; };
3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSExpression+MGLAdditions.h"; sourceTree = "<group>"; };
3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSExpression+MGLAdditions.mm"; sourceTree = "<group>"; };
3526EABC1DF9B19800006B43 /* MGLCodingTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLCodingTests.mm; path = ../../darwin/test/MGLCodingTests.mm; sourceTree = "<group>"; };
@@ -1204,6 +1208,8 @@
DA00FC881D5EEAC3009AABC8 /* MGLAttributionInfo.h */,
DAF0D8151DFE6B1800B28378 /* MGLAttributionInfo_Private.h */,
DA00FC891D5EEAC3009AABC8 /* MGLAttributionInfo.mm */,
1FF4858C2237235200F19727 /* MGLAttributedExpression.h */,
1FF4858B2237235200F19727 /* MGLAttributedExpression.m */,
556660C51E1BEA0100E2C41B /* MGLFoundation.h */,
558DE7A41E56161C00C7916D /* MGLFoundation_Private.h */,
558DE7A51E56161C00C7916D /* MGLFoundation.mm */,
@@ -1276,6 +1282,7 @@
DAE6C38D1CC31E2A00DB3429 /* MGLOfflineRegion_Private.h in Headers */,
DA7DC9831DED647F0027472F /* MGLRasterTileSource_Private.h in Headers */,
747ABE5B219B2BDB00523B67 /* MGLBackgroundStyleLayer_Private.h in Headers */,
1FF4858E2237235300F19727 /* MGLAttributedExpression.h in Headers */,
1753ED401E53CE6100A9FD90 /* MGLConversion.h in Headers */,
747ABE59219B2BDB00523B67 /* MGLFillExtrusionStyleLayer_Private.h in Headers */,
DA8F259C1D51CB000010E6B5 /* MGLStyleValue_Private.h in Headers */,
@@ -1653,6 +1660,7 @@
352742821D4C243B00A1ECE6 /* MGLSource.mm in Sources */,
DAE6C3881CC31E2A00DB3429 /* MGLMapCamera.mm in Sources */,
DA6408D81DA4E5DA00908C90 /* MGLVectorStyleLayer.m in Sources */,
1FF4858D2237235300F19727 /* MGLAttributedExpression.m in Sources */,
DA8F25B31D51CB270010E6B5 /* NSValue+MGLStyleAttributeAdditions.mm in Sources */,
DAE6C3911CC31E2A00DB3429 /* MGLPolygon.mm in Sources */,
35C6DF851E214C0400ACA483 /* MGLDistanceFormatter.m in Sources */,

View File

@@ -47,6 +47,7 @@
"platform/darwin/src/MGLSource.mm",
"platform/darwin/src/MGLMapCamera.mm",
"platform/darwin/src/MGLVectorStyleLayer.m",
"platform/darwin/src/MGLAttributedExpression.m",
"platform/darwin/src/NSValue+MGLStyleAttributeAdditions.mm",
"platform/darwin/src/MGLPolygon.mm",
"platform/darwin/src/MGLDistanceFormatter.m",
@@ -80,6 +81,7 @@
"MGLComputedShapeSource.h": "platform/darwin/src/MGLComputedShapeSource.h",
"MGLRasterStyleLayer.h": "platform/darwin/src/MGLRasterStyleLayer.h",
"NSExpression+MGLAdditions.h": "platform/darwin/src/NSExpression+MGLAdditions.h",
"MGLAttributedExpression.h": "platform/darwin/src/MGLAttributedExpression.h",
"MGLAnnotation.h": "platform/darwin/src/MGLAnnotation.h",
"MGLHillshadeStyleLayer.h": "platform/darwin/src/MGLHillshadeStyleLayer.h",
"MGLMapSnapshotter.h": "platform/darwin/src/MGLMapSnapshotter.h",

View File

@@ -67,3 +67,4 @@ FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[];
#import "NSPredicate+MGLAdditions.h"
#import "MGLLoggingConfiguration.h"
#import "MGLNetworkConfiguration.h"
#import "MGLAttributedExpression.h"