summaryrefslogtreecommitdiff
path: root/platform/darwin/src/MGLShapeSource.mm
diff options
context:
space:
mode:
Diffstat (limited to 'platform/darwin/src/MGLShapeSource.mm')
-rw-r--r--platform/darwin/src/MGLShapeSource.mm61
1 files changed, 57 insertions, 4 deletions
diff --git a/platform/darwin/src/MGLShapeSource.mm b/platform/darwin/src/MGLShapeSource.mm
index 3628a0eb74..a4a100aaa2 100644
--- a/platform/darwin/src/MGLShapeSource.mm
+++ b/platform/darwin/src/MGLShapeSource.mm
@@ -3,6 +3,7 @@
#import "MGLLoggingConfiguration_Private.h"
#import "MGLStyle_Private.h"
+#import "MGLStyleValue_Private.h"
#import "MGLMapView_Private.h"
#import "MGLSource_Private.h"
#import "MGLFeature_Private.h"
@@ -19,6 +20,7 @@
const MGLShapeSourceOption MGLShapeSourceOptionBuffer = @"MGLShapeSourceOptionBuffer";
const MGLShapeSourceOption MGLShapeSourceOptionClusterRadius = @"MGLShapeSourceOptionClusterRadius";
const MGLShapeSourceOption MGLShapeSourceOptionClustered = @"MGLShapeSourceOptionClustered";
+const MGLShapeSourceOption MGLShapeSourceOptionClusterProperties = @"MGLShapeSourceOptionClusterProperties";
const MGLShapeSourceOption MGLShapeSourceOptionMaximumZoomLevel = @"MGLShapeSourceOptionMaximumZoomLevel";
const MGLShapeSourceOption MGLShapeSourceOptionMaximumZoomLevelForClustering = @"MGLShapeSourceOptionMaximumZoomLevelForClustering";
const MGLShapeSourceOption MGLShapeSourceOptionMinimumZoomLevel = @"MGLShapeSourceOptionMinimumZoomLevel";
@@ -84,6 +86,57 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
geoJSONOptions.cluster = value.boolValue;
}
+ if (NSDictionary *value = options[MGLShapeSourceOptionClusterProperties]) {
+ if (![value isKindOfClass:[NSDictionary<NSString *, NSArray *> class]]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"MGLShapeSourceOptionClusterProperties must be an NSDictionary with an NSString as a key and an array containing two NSExpression objects as a value."];
+ }
+
+ NSEnumerator *stringEnumerator = [value keyEnumerator];
+ NSString *key;
+
+ while (key = [stringEnumerator nextObject]) {
+ NSArray *expressionsArray = value[key];
+ if (![expressionsArray isKindOfClass:[NSArray class]]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"MGLShapeSourceOptionClusterProperties dictionary member value must be an array containing two objects."];
+ }
+ // Check that the array has 2 values. One should be a the reduce expression and one should be the map expression.
+ if ([expressionsArray count] != 2) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"MGLShapeSourceOptionClusterProperties member value requires array of two objects."];
+ }
+
+ // reduceExpression should be a valid NSExpression
+ NSExpression *reduceExpression = expressionsArray[0];
+ if (![reduceExpression isKindOfClass:[NSExpression class]]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"MGLShapeSourceOptionClusterProperties array value requires two expression objects."];
+ }
+ auto reduce = MGLClusterPropertyFromNSExpression(reduceExpression);
+ if (!reduce) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Failed to convert MGLShapeSourceOptionClusterProperties reduce expression."];
+ }
+
+ // mapExpression should be a valid NSExpression
+ NSExpression *mapExpression = expressionsArray[1];
+ if (![mapExpression isKindOfClass:[NSExpression class]]) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"MGLShapeSourceOptionClusterProperties member value must contain a valid NSExpression."];
+ }
+ auto map = MGLClusterPropertyFromNSExpression(mapExpression);
+ if (!map) {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Failed to convert MGLShapeSourceOptionClusterProperties map expression."];
+ }
+
+ std::string keyString = std::string([key UTF8String]);
+
+ geoJSONOptions.clusterProperties.emplace(keyString, std::make_pair(std::move(map), std::move(reduce)));
+ }
+ }
+
if (NSNumber *value = options[MGLShapeSourceOptionLineDistanceMetrics]) {
if (![value isKindOfClass:[NSNumber class]]) {
[NSException raise:NSInvalidArgumentException
@@ -209,12 +262,12 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
auto geoJSON = [cluster geoJSONObject];
- if (!geoJSON.is<mbgl::Feature>()) {
+ if (!geoJSON.is<mbgl::GeoJSONFeature>()) {
MGLAssert(0, @"cluster geoJSON object is not a feature.");
return extensionValue;
}
- auto clusterFeature = geoJSON.get<mbgl::Feature>();
+ auto clusterFeature = geoJSON.get<mbgl::GeoJSONFeature>();
extensionValue = self.mapView.renderer->queryFeatureExtensions(self.rawSource->getID(),
clusterFeature,
@@ -240,7 +293,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
return @[];
}
- std::vector<mbgl::Feature> leaves = featureExtension->get<mbgl::FeatureCollection>();
+ std::vector<mbgl::GeoJSONFeature> leaves = featureExtension->get<mbgl::FeatureCollection>();
return MGLFeaturesFromMBGLFeatures(leaves);
}
@@ -255,7 +308,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
return @[];
}
- std::vector<mbgl::Feature> leaves = featureExtension->get<mbgl::FeatureCollection>();
+ std::vector<mbgl::GeoJSONFeature> leaves = featureExtension->get<mbgl::FeatureCollection>();
return MGLFeaturesFromMBGLFeatures(leaves);
}