summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzmiao <zmiao.jamie@gmail.com>2019-09-11 14:06:04 +0300
committerjmkiley <jordan.kiley@mapbox.com>2019-09-25 14:28:56 -0700
commit5dbf1e0257011adc212f07f391b2086769850f65 (patch)
tree51f53a72a659a4abc25125b81e0f0ed3519769b2
parent277a5833afb0d5d1384348c6a1f72f58b0bb0043 (diff)
downloadqtlocation-mapboxgl-5dbf1e0257011adc212f07f391b2086769850f65.tar.gz
[ios] Create expression with expressionWithFormat. Revert changes in NSExpression of sum. Add a TestCase of featureAccumulated.
-rw-r--r--platform/darwin/src/MGLShapeSource.h12
-rw-r--r--platform/darwin/src/MGLShapeSource.mm12
-rw-r--r--platform/darwin/src/NSExpression+MGLAdditions.h7
-rw-r--r--platform/darwin/src/NSExpression+MGLAdditions.mm10
-rw-r--r--platform/darwin/test/MGLExpressionTests.mm7
-rw-r--r--platform/ios/app/MBXViewController.m36
6 files changed, 62 insertions, 22 deletions
diff --git a/platform/darwin/src/MGLShapeSource.h b/platform/darwin/src/MGLShapeSource.h
index c4421e3ddf..08891ee90c 100644
--- a/platform/darwin/src/MGLShapeSource.h
+++ b/platform/darwin/src/MGLShapeSource.h
@@ -41,6 +41,18 @@ FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionClus
*/
FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionClusterRadius;
+/**
+ An `NSDictionary` objcet containing custom properties on the generated clusters if clustering is enabled,
+ aggregating values from clustered points. Has the form {"property_name": [recude_operator, [map_expression]]} or
+ {"property_name": [[reduce_operator, accumulated, expression], [map_expression]]}
+
+ recude_operator is any expression function that accepts at least 2 operands (e.g. "sum" or "max", etc.).
+ It accumulates the property value from clusters/points the cluster contains. It can either be
+ a literal with single operator, or be a valid expression with two expression arguments: `accumulated` and
+ an other valid expression produces value of the same type of `accumulated`
+
+ map_expression produces the value of a single point, it shall be a valid expression
+ */
FOUNDATION_EXTERN MGL_EXPORT const MGLShapeSourceOption MGLShapeSourceOptionClusterProperties;
/**
An `NSNumber` object containing an integer; specifies the maximum zoom level at
diff --git a/platform/darwin/src/MGLShapeSource.mm b/platform/darwin/src/MGLShapeSource.mm
index c1ac6fbbbe..8ec92880cb 100644
--- a/platform/darwin/src/MGLShapeSource.mm
+++ b/platform/darwin/src/MGLShapeSource.mm
@@ -109,7 +109,17 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
[NSException raise:NSInvalidArgumentException
format:@"Failed to convert MGLShapeSourceOptionClusterProperties map expression."];
}
- NSExpression *reduceExpre = expArray[0];
+
+ NSString *reduceOperator = expArray[0];
+ NSExpression *reduceExpre;
+ // If reduceOperator is only a string instead of expression, create the integrated full expression before parsing
+ if ([reduceOperator isKindOfClass:[NSString class]]) {
+ NSString *reduceExpression = [NSString stringWithFormat:@"%@({ $featureAccumulated, %@})", reduceOperator, key];
+ reduceExpre = [NSExpression expressionWithFormat:reduceExpression];
+ } else {
+ reduceExpre = expArray[0];
+ }
+
auto reduce = MGLClusterPropertyFromNSExpression(reduceExpre);
if (!reduce) {
[NSException raise:NSInvalidArgumentException
diff --git a/platform/darwin/src/NSExpression+MGLAdditions.h b/platform/darwin/src/NSExpression+MGLAdditions.h
index 2a33367e9c..2109310e69 100644
--- a/platform/darwin/src/NSExpression+MGLAdditions.h
+++ b/platform/darwin/src/NSExpression+MGLAdditions.h
@@ -86,6 +86,13 @@ FOUNDATION_EXTERN MGL_EXPORT const MGLExpressionInterpolationMode MGLExpressionI
/**
`NSExpression` variable that corresponds to the
+ <a href="https://docs.mapbox.com/mapbox-gl-js/style-spec/#accumulated"><code>id</code></a>
+ expression operator in the Mapbox Style Specification.
+ */
+@property (class, nonatomic, readonly) NSExpression *featureAccumulatedVariableExpression;
+
+/**
+ `NSExpression` variable that corresponds to the
<a href="https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions-properties"><code>properties</code></a>
expression operator in the Mapbox Style Specification.
*/
diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm
index 3d77b1ea1f..b502851722 100644
--- a/platform/darwin/src/NSExpression+MGLAdditions.mm
+++ b/platform/darwin/src/NSExpression+MGLAdditions.mm
@@ -1066,14 +1066,8 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
NSExpression *count = [NSExpression expressionForFunction:@"count:" arguments:self.arguments];
return [NSExpression expressionForFunction:@"divide:by:" arguments:@[sum, count]].mgl_jsonExpressionObject;
} else if ([function isEqualToString:@"sum:"]) {
- id context = self.arguments.firstObject;
- if ([context isKindOfClass:[NSExpression class]]) {
- NSArray *arguments = [self.arguments valueForKeyPath:@"mgl_jsonExpressionObject"];
- return [@[@"+"] arrayByAddingObjectsFromArray:arguments];
- } else {
- NSArray *arguments = [self.arguments.firstObject.collection valueForKeyPath:@"mgl_jsonExpressionObject"];
- return [@[@"+"] arrayByAddingObjectsFromArray:arguments];
- }
+ NSArray *arguments = [self.arguments.firstObject.collection valueForKeyPath:@"mgl_jsonExpressionObject"];
+ return [@[@"+"] arrayByAddingObjectsFromArray:arguments];
} else if ([function isEqualToString:@"count:"]) {
NSArray *arguments = self.arguments.firstObject.mgl_jsonExpressionObject;
return @[@"length", arguments];
diff --git a/platform/darwin/test/MGLExpressionTests.mm b/platform/darwin/test/MGLExpressionTests.mm
index f1fe3ea878..b3558e2bf4 100644
--- a/platform/darwin/test/MGLExpressionTests.mm
+++ b/platform/darwin/test/MGLExpressionTests.mm
@@ -180,6 +180,13 @@ using namespace std::string_literals;
XCTAssertEqualObjects([expression expressionValueWithObject:nil context:context], @1);
}
{
+ NSExpression *expression = [NSExpression expressionForVariable:@"featureAccumulated"];
+ XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, @[@"accumulated"]);
+ XCTAssertEqualObjects([NSExpression expressionWithFormat:@"$featureAccumulated"].mgl_jsonExpressionObject, @[@"accumulated"]);
+ XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:@[@"accumulated"]], expression);
+ }
+
+ {
NSExpression *expression = [NSExpression expressionForVariable:@"geometryType"];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, @[@"geometry-type"]);
XCTAssertEqualObjects([NSExpression expressionWithFormat:@"$geometryType"].mgl_jsonExpressionObject, @[@"geometry-type"]);
diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m
index 6d56e39364..c319b43682 100644
--- a/platform/ios/app/MBXViewController.m
+++ b/platform/ios/app/MBXViewController.m
@@ -1319,26 +1319,36 @@ CLLocationCoordinate2D randomWorldCoordinate() {
NSURL *geoJSONURL = [NSURL fileURLWithPath:filePath];
// MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"mutable-data-source-url-id" URL:geoJSONURL options:nil];
- NSExpression *reduceExpression = [NSExpression expressionForFunction:@"sum:" arguments:@[[NSExpression expressionForVariable:@"featureAccumulated"], [NSExpression expressionForKeyPath:@"sumVal"]]];
-
- NSExpression *mapExpression = [NSExpression expressionForKeyPath:@"mag"];
-
- NSArray<NSExpression *> *expressArray = @[reduceExpression, mapExpression];
- NSDictionary *clusterProperty = @{@"sumVal" : expressArray};
-
- MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"mutable-data-source-id" URL:geoJSONURL options:@{
- MGLShapeSourceOptionClustered: @(YES),
- MGLShapeSourceOptionClusterRadius: @(15),
- MGLShapeSourceOptionClusterProperties: clusterProperty
- }];
+ // Input property with format {"property_name": [[reduce_operator, accumulated, expression], [map_expression]]}
+// NSExpression *reduceExpression1 = [NSExpression expressionForFunction:@"sum:" arguments:@[[NSExpression expressionForVariable:@"featureAccumulated"], [NSExpression expressionForKeyPath:@"sumVal"]]];
+ NSExpression *reduceExpression1 = [NSExpression expressionWithFormat:@"sum({ $featureAccumulated, sumVal })"];
+ NSExpression *mapExpression1 = [NSExpression expressionForKeyPath:@"mag"];
+ NSArray *expressArray1 = @[reduceExpression1, mapExpression1];
+ // Input propety with format {"property_name": [[literal(reduce_operator)], [map_expression]]}
+ NSString *reduceExpression2 = @"max";
+ NSExpression *mapExpression2 = [NSExpression expressionForKeyPath:@"mag"];
+ NSArray *expressArray2 = @[reduceExpression2, mapExpression2];
+
+ NSDictionary *clusterProperty = @{@"sumVal" : expressArray1,
+ @"maxVal" : expressArray2
+ };
+
+ MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"mutable-data-source-id"
+ URL:geoJSONURL
+ options:@{
+ MGLShapeSourceOptionClustered: @(YES),
+ MGLShapeSourceOptionClusterRadius: @(15),
+ MGLShapeSourceOptionClusterProperties: clusterProperty
+ }];
+
[self.mapView.style addSource:source];
// Create image cluster style layer
MGLSymbolStyleLayer *clusterLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"clusteredPortsNumbers" source:source];
clusterLayer.textColor = [NSExpression expressionForConstantValue:[UIColor redColor]];
clusterLayer.textFontSize = [NSExpression expressionForConstantValue:@(30)];
- clusterLayer.text = [NSExpression expressionWithFormat:@"CAST(point_count, 'NSString')"];
+ clusterLayer.text = [NSExpression expressionWithFormat:@"CAST(maxVal, 'NSString')"];
[self.mapView.style addLayer:clusterLayer];
}