summaryrefslogtreecommitdiff
path: root/platform/darwin/src/MGLFeature.mm
diff options
context:
space:
mode:
Diffstat (limited to 'platform/darwin/src/MGLFeature.mm')
-rw-r--r--platform/darwin/src/MGLFeature.mm60
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());