diff options
author | zmiao <zmiao.jamie@gmail.com> | 2019-09-11 14:06:04 +0300 |
---|---|---|
committer | jmkiley <jordan.kiley@mapbox.com> | 2019-09-25 14:28:56 -0700 |
commit | 5dbf1e0257011adc212f07f391b2086769850f65 (patch) | |
tree | 51f53a72a659a4abc25125b81e0f0ed3519769b2 | |
parent | 277a5833afb0d5d1384348c6a1f72f58b0bb0043 (diff) | |
download | qtlocation-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.h | 12 | ||||
-rw-r--r-- | platform/darwin/src/MGLShapeSource.mm | 12 | ||||
-rw-r--r-- | platform/darwin/src/NSExpression+MGLAdditions.h | 7 | ||||
-rw-r--r-- | platform/darwin/src/NSExpression+MGLAdditions.mm | 10 | ||||
-rw-r--r-- | platform/darwin/test/MGLExpressionTests.mm | 7 | ||||
-rw-r--r-- | platform/ios/app/MBXViewController.m | 36 |
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]; } |