diff options
Diffstat (limited to 'platform/darwin/src/MGLFeature.mm')
-rw-r--r-- | platform/darwin/src/MGLFeature.mm | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm index d24c807625..fbf262af29 100644 --- a/platform/darwin/src/MGLFeature.mm +++ b/platform/darwin/src/MGLFeature.mm @@ -1,4 +1,6 @@ +#import "MGLFoundation_Private.h" #import "MGLFeature_Private.h" +#import "MGLCluster.h" #import "MGLPointAnnotation.h" #import "MGLPolyline.h" @@ -19,6 +21,11 @@ #import <mbgl/style/conversion/geojson.hpp> #import <mapbox/feature.hpp> +// Cluster constants +static NSString * const MGLClusterIdentifierKey = @"cluster_id"; +static NSString * const MGLClusterCountKey = @"point_count"; +const NSUInteger MGLClusterIdentifierInvalid = NSUIntegerMax; + @interface MGLEmptyFeature () @end @@ -92,6 +99,31 @@ MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER(); @end +@implementation MGLPointFeatureCluster + +- (NSUInteger)clusterIdentifier { + NSNumber *clusterNumber = MGL_OBJC_DYNAMIC_CAST([self attributeForKey:MGLClusterIdentifierKey], NSNumber); + MGLAssert(clusterNumber, @"Clusters should have a cluster_id"); + + if (!clusterNumber) { + return MGLClusterIdentifierInvalid; + } + + NSUInteger clusterIdentifier = [clusterNumber unsignedIntegerValue]; + MGLAssert(clusterIdentifier <= UINT32_MAX, @"Cluster identifiers are 32bit"); + + return clusterIdentifier; +} + +- (NSUInteger)clusterPointCount { + NSNumber *count = MGL_OBJC_DYNAMIC_CAST([self attributeForKey:MGLClusterCountKey], NSNumber); + MGLAssert(count, @"Clusters should have a point_count"); + + return [count unsignedIntegerValue]; +} +@end + + @interface MGLPolylineFeature () @end @@ -318,14 +350,38 @@ MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER(); */ template <typename T> class GeometryEvaluator { +private: + const mbgl::PropertyMap *shared_properties; + public: + GeometryEvaluator(const mbgl::PropertyMap *properties = nullptr): + shared_properties(properties) + {} + MGLShape <MGLFeature> * operator()(const mbgl::EmptyGeometry &) const { MGLEmptyFeature *feature = [[MGLEmptyFeature alloc] init]; return feature; } MGLShape <MGLFeature> * operator()(const mbgl::Point<T> &geometry) const { - MGLPointFeature *feature = [[MGLPointFeature alloc] init]; + Class pointFeatureClass = [MGLPointFeature class]; + + // If we're dealing with a cluster, we should change the class type. + // This could be generic and build the subclass at runtime if it turns + // out we need to support more than point clusters. + if (shared_properties) { + auto clusterIt = shared_properties->find("cluster"); + if (clusterIt != shared_properties->end()) { + auto clusterValue = clusterIt->second; + if (clusterValue.template is<bool>()) { + if (clusterValue.template get<bool>()) { + pointFeatureClass = [MGLPointFeatureCluster class]; + } + } + } + } + + MGLPointFeature *feature = [[pointFeatureClass alloc] init]; feature.coordinate = toLocationCoordinate2D(geometry); return feature; } @@ -443,7 +499,7 @@ id <MGLFeature> MGLFeatureFromMBGLFeature(const mbgl::Feature &feature) { ValueEvaluator evaluator; attributes[@(pair.first.c_str())] = mbgl::Value::visit(value, evaluator); } - GeometryEvaluator<double> evaluator; + GeometryEvaluator<double> evaluator(&feature.properties); MGLShape <MGLFeature> *shape = mapbox::geometry::geometry<double>::visit(feature.geometry, evaluator); if (!feature.id.is<mapbox::feature::null_value_t>()) { shape.identifier = mbgl::FeatureIdentifier::visit(feature.id, ValueEvaluator()); |