summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Rex <julian.rex@mapbox.com>2019-01-12 01:25:18 -0500
committerJulian Rex <julian.rex@mapbox.com>2019-01-12 14:36:51 -0500
commit360ad1c06ddb2cb8219d480908eedc3bc8a00e42 (patch)
tree86974013620359e656cf3702cd460d56e5d40e2e
parent8c4066d6a74ac6b89463c2629fa7397fe99ef818 (diff)
downloadqtlocation-mapboxgl-360ad1c06ddb2cb8219d480908eedc3bc8a00e42.tar.gz
Introduces MGLPointFeatureCluster subclass (since update feature extension required MGLShape)
-rw-r--r--platform/darwin/src/MGLCluster.h7
-rw-r--r--platform/darwin/src/MGLCluster.mm155
-rw-r--r--platform/darwin/src/MGLCluster_Private.h19
-rw-r--r--platform/darwin/src/MGLFeature.h6
-rw-r--r--platform/darwin/src/MGLFeature.mm74
-rw-r--r--platform/darwin/src/MGLFeature_Private.h4
-rw-r--r--platform/darwin/src/MGLShapeSource.h9
-rw-r--r--platform/darwin/src/MGLShapeSource.mm10
-rw-r--r--platform/darwin/src/MGLShapeSource_Private.h2
-rw-r--r--platform/darwin/test/MGLCodingTests.mm24
-rw-r--r--platform/darwin/test/MGLFeatureTests.mm2
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj25
12 files changed, 104 insertions, 233 deletions
diff --git a/platform/darwin/src/MGLCluster.h b/platform/darwin/src/MGLCluster.h
index 2a3b5270da..a7caf2ddcf 100644
--- a/platform/darwin/src/MGLCluster.h
+++ b/platform/darwin/src/MGLCluster.h
@@ -1,4 +1,3 @@
-#import <Foundation/Foundation.h>
#import "MGLFoundation.h"
@protocol MGLFeature;
@@ -32,7 +31,6 @@ FOUNDATION_EXTERN MGL_EXPORT const NSUInteger MGLClusterIdentifierInvalid;
throw ExampleError.featureIsNotACluster
}
- print("Approximate number of points in cluster: \(cluster.clusterPointCountAbbreviation)")
```
*/
MGL_EXPORT
@@ -44,11 +42,6 @@ MGL_EXPORT
/** The number of points within this cluster */
@property (nonatomic, readonly) NSUInteger clusterPointCount;
-///**
-// An `NSString` abbreviation for the number of points within this cluster. For
-// example "1.2k".
-// */
-//@property (nonatomic, readonly) NSString *clusterPointCountAbbreviation;
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLCluster.mm b/platform/darwin/src/MGLCluster.mm
deleted file mode 100644
index 2cc296fa91..0000000000
--- a/platform/darwin/src/MGLCluster.mm
+++ /dev/null
@@ -1,155 +0,0 @@
-#import "MGLFoundation_Private.h"
-#import "MGLCluster_Private.h"
-#import "MGLLoggingConfiguration_Private.h"
-#import "MGLFeature.h"
-#import <objc/runtime.h>
-
-NSString * const MGLClusterBoolKey = @"cluster";
-NSString * const MGLClusterIdentifierKey = @"cluster_id";
-NSString * const MGLClusterCountKey = @"point_count";
-//NSString * const MGLClusterCountAbbreviationKey = @"point_count_abbreviated";
-
-const NSUInteger MGLClusterIdentifierInvalid = NSUIntegerMax;
-
-BOOL MGLFeatureHasClusterAttribute(id<MGLFeature> feature) {
- NSNumber *isCluster = MGL_OBJC_DYNAMIC_CAST([feature attributeForKey:MGLClusterBoolKey], NSNumber);
- return [isCluster boolValue];
-}
-
-#pragma mark - Custom subclassing
-
-NSString *MGLClusterSubclassNameForFeature(id<MGLFeature> feature) {
- NSString *className = NSStringFromClass([feature class]);
- NSString *subclassName = [className stringByAppendingString:@"_Cluster"];
- return subclassName;
-}
-
-/**
- Static free function used as implementation for custom subclasses (that conform
- to both `MGLFeature` and `MGLCluster`).
- */
-static NSUInteger MGLClusterIdentifierIMP(id self, SEL _cmd) {
-
- id<MGLFeature> feature = MGL_OBJC_DYNAMIC_CAST_AS_PROTOCOL(self, MGLFeature);
-
- NSNumber *clusterNumber = MGL_OBJC_DYNAMIC_CAST([feature attributeForKey:MGLClusterIdentifierKey], NSNumber);
- MGLAssert(clusterNumber, @"Clusters should have a cluster_id");
-
- if (!clusterNumber) {
- return MGLClusterIdentifierInvalid;
- }
-
- NSUInteger identifier = [clusterNumber unsignedIntegerValue];
- MGLAssert(identifier <= UINT32_MAX, @"Cluster identifiers are 32bit");
-
- return identifier;
-}
-
-/**
- Static free function used as implementation for custom subclasses (that conform
- to both `MGLFeature` and `MGLCluster`).
- */
-static NSUInteger MGLClusterPointCountIMP(id self, SEL _cmd) {
- id<MGLFeature> feature = MGL_OBJC_DYNAMIC_CAST_AS_PROTOCOL(self, MGLFeature);
-
- NSNumber *count = MGL_OBJC_DYNAMIC_CAST([feature attributeForKey:MGLClusterCountKey], NSNumber);
- MGLAssert(count, @"Clusters should have a point_count");
-
- return [count unsignedIntegerValue];
-}
-
-///**
-// Static free function used as implementation for custom subclasses (that conform
-// to both `MGLFeature` and `MGLCluster`).
-// */
-//static NSString *MGLClusterPointCountAbbreviationIMP(id self, SEL _cmd) {
-// id<MGLFeature> feature = MGL_OBJC_DYNAMIC_CAST_AS_PROTOCOL(self, MGLFeature);
-//
-// NSString *abbreviation = MGL_OBJC_DYNAMIC_CAST([feature attributeForKey:MGLClusterCountAbbreviationKey], NSString);
-// MGLAssert(abbreviation, @"Clusters should have a point_count_abbreviated");
-//
-// if (!abbreviation) {
-// return @"0";
-// }
-//
-// return abbreviation;
-//}
-
-static IMP MGLFeatureClusterIMPFromSelector(SEL selector) {
- if (selector == @selector(clusterIdentifier)) {
- return (IMP)MGLClusterIdentifierIMP;
- }
- else if (selector == @selector(clusterPointCount)) {
- return (IMP)MGLClusterPointCountIMP;
- }
-// else if (selector == @selector(clusterPointCountAbbreviation)) {
-// return (IMP)MGLClusterPointCountAbbreviationIMP;
-// }
- MGLCAssert(0, @"Unrecognized selector: %@", NSStringFromSelector(selector));
- return NULL;
-}
-
-/**
- Converts a feature to a custom subclass that supports both `MGLFeature` and
- `MGLCluster`, or returns `nil` if the feature doesn't have the requisite cluster
- attributes.
- */
-id<MGLFeature, MGLCluster> MGLConvertFeatureToClusterSubclass(id<MGLFeature> feature) {
-
- Protocol *clusterProtocol = @protocol(MGLCluster);
-
- if ([feature conformsToProtocol:clusterProtocol]) {
- return (id<MGLFeature, MGLCluster>)feature;
- }
-
- if (!MGLFeatureHasClusterAttribute(feature)) {
- return nil;
- }
-
- Class currentClass = [feature class];
-
- NSString *subclassName = MGLClusterSubclassNameForFeature(feature);
-
- // Does this new subclass already exist?
- Class clusterSubclass = NSClassFromString(subclassName);
-
- if (!clusterSubclass) {
- clusterSubclass = objc_allocateClassPair(currentClass, subclassName.UTF8String, 0);
-
- // Add protocol to this new subclass
- class_addProtocol(clusterSubclass, clusterProtocol);
-
- // Install protocol methods
- // Run through using `protocol_copyMethodDescriptionList` and the above
- // `MGLFeatureClusterIMPFromSelector` method. We do this so that we avoid
- // having to hand-craft the type encodings passed to `class_addMethod`.
- unsigned int count = 0;
- struct objc_method_description *methodDescriptionList = protocol_copyMethodDescriptionList(clusterProtocol, YES, YES, &count);
-
- for (unsigned int index = 0; index < count; index++) {
- struct objc_method_description desc = methodDescriptionList[index];
-
- IMP imp = MGLFeatureClusterIMPFromSelector(desc.name);
-
- if (imp) {
- class_addMethod(clusterSubclass, desc.name, imp, desc.types);
- }
- }
-
- free(methodDescriptionList); methodDescriptionList = NULL;
-
- objc_registerClassPair(clusterSubclass);
- }
-
- // Now change the class of the feature
- object_setClass(feature, clusterSubclass);
- MGLCAssert([feature conformsToProtocol:clusterProtocol], @"Feature subclass %@ should conform to MGLCluster", subclassName);
-
- id<MGLFeature, MGLCluster> cluster = (id<MGLFeature, MGLCluster>)feature;
-
- MGLCAssert([cluster respondsToSelector:@selector(clusterIdentifier)], @"Feature subclass %@ - missing selector `clusterIdentifier`", subclassName);
- MGLCAssert([cluster respondsToSelector:@selector(clusterPointCount)], @"Feature subclass %@ - missing selector `clusterPointCount`", subclassName);
-// MGLCAssert([cluster respondsToSelector:@selector(clusterPointCountAbbreviation)], @"Feature subclass %@ - missing selector `clusterPointCountAbbreviation`", subclassName);
-
- return cluster;
-}
diff --git a/platform/darwin/src/MGLCluster_Private.h b/platform/darwin/src/MGLCluster_Private.h
deleted file mode 100644
index 5117c68918..0000000000
--- a/platform/darwin/src/MGLCluster_Private.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#import <Foundation/Foundation.h>
-#import "MGLFoundation.h"
-#import "MGLCluster.h"
-
-@protocol MGLFeature;
-
-FOUNDATION_EXPORT NSString * const MGLClusterBoolKey;
-FOUNDATION_EXPORT NSString * const MGLClusterIdentifierKey;
-FOUNDATION_EXPORT NSString * const MGLClusterCountKey;
-//FOUNDATION_EXPORT NSString * const MGLClusterCountAbbreviationKey;
-
-FOUNDATION_EXPORT BOOL MGLFeatureHasClusterAttribute(id<MGLFeature> feature);
-
-FOUNDATION_EXPORT MGL_EXPORT
-NSString *MGLClusterSubclassNameForFeature(id<MGLFeature> feature);
-
-FOUNDATION_EXPORT
-id<MGLFeature, MGLCluster> MGLConvertFeatureToClusterSubclass(id<MGLFeature> feature);
-
diff --git a/platform/darwin/src/MGLFeature.h b/platform/darwin/src/MGLFeature.h
index 8886c8df55..e17b463a7f 100644
--- a/platform/darwin/src/MGLFeature.h
+++ b/platform/darwin/src/MGLFeature.h
@@ -6,6 +6,7 @@
#import "MGLPointAnnotation.h"
#import "MGLPointCollection.h"
#import "MGLShapeCollection.h"
+#import "MGLCluster.h"
NS_ASSUME_NONNULL_BEGIN
@@ -192,6 +193,11 @@ MGL_EXPORT
@interface MGLPointFeature : MGLPointAnnotation <MGLFeature>
@end
+
+MGL_EXPORT
+@interface MGLPointFeatureCluster : MGLPointFeature <MGLCluster>
+@end
+
/**
An `MGLPolylineFeature` object associates a polyline shape with an optional
identifier and attributes.
diff --git a/platform/darwin/src/MGLFeature.mm b/platform/darwin/src/MGLFeature.mm
index e579a87eb0..55700b6b22 100644
--- a/platform/darwin/src/MGLFeature.mm
+++ b/platform/darwin/src/MGLFeature.mm
@@ -1,11 +1,13 @@
+#import "MGLFoundation_Private.h"
#import "MGLFeature_Private.h"
+#import "MGLCluster.h"
#import "MGLPointAnnotation.h"
#import "MGLPolyline.h"
#import "MGLPolygon.h"
#import "MGLValueEvaluator.h"
-#import "MGLCluster_Private.h"
+#import "MGLCluster.h"
#import "MGLShape_Private.h"
#import "MGLPointCollection_Private.h"
#import "MGLPolyline_Private.h"
@@ -20,6 +22,9 @@
#import <mbgl/style/conversion/geojson.hpp>
#import <mapbox/feature.hpp>
+static NSString * const MGLClusterIdentifierKey = @"cluster_id";
+static NSString * const MGLClusterCountKey = @"point_count";
+
@interface MGLEmptyFeature ()
@end
@@ -93,6 +98,42 @@ MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER();
@end
+const NSUInteger MGLClusterIdentifierInvalid = NSUIntegerMax;
+
+@implementation MGLPointFeatureCluster
+
+// If it turns out we need to cluster other classes, then consider moving the
+// following MGLCluster methods into free functions, and generate the subclasses
+// at runtime
+- (NSUInteger)clusterIdentifier {
+ id<MGLFeature> feature = MGL_OBJC_DYNAMIC_CAST_AS_PROTOCOL(self, MGLFeature);
+
+ NSNumber *clusterNumber = MGL_OBJC_DYNAMIC_CAST([feature 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 {
+ id<MGLFeature> feature = MGL_OBJC_DYNAMIC_CAST_AS_PROTOCOL(self, MGLFeature);
+
+ NSNumber *count = MGL_OBJC_DYNAMIC_CAST([feature attributeForKey:MGLClusterCountKey], NSNumber);
+ MGLAssert(count, @"Clusters should have a point_count");
+
+ return [count unsignedIntegerValue];
+}
+
+
+@end
+
+
@interface MGLPolylineFeature ()
@end
@@ -319,14 +360,34 @@ MGL_DEFINE_FEATURE_ATTRIBUTES_GETTER();
*/
template <typename T>
class GeometryEvaluator {
+private:
+ mbgl::PropertyMap _properties;
+
public:
+
+ GeometryEvaluator(mbgl::PropertyMap properties = {}):
+ _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];
+
+ auto clusterIt = _properties.find("cluster");
+ if (clusterIt != _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;
}
@@ -376,6 +437,9 @@ public:
}
private:
+
+// mbgl::PropertyMap _properties;
+
static CLLocationCoordinate2D toLocationCoordinate2D(const mbgl::Point<T> &point) {
return CLLocationCoordinate2DMake(point.y, point.x);
}
@@ -444,17 +508,13 @@ 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());
}
shape.attributes = attributes;
- if (MGLFeatureHasClusterAttribute(shape)) {
- MGLConvertFeatureToClusterSubclass(shape);
- }
-
return shape;
}
diff --git a/platform/darwin/src/MGLFeature_Private.h b/platform/darwin/src/MGLFeature_Private.h
index b3406fe2b4..9b0e16f4b9 100644
--- a/platform/darwin/src/MGLFeature_Private.h
+++ b/platform/darwin/src/MGLFeature_Private.h
@@ -47,10 +47,6 @@ NS_ASSUME_NONNULL_END
NSSet<Class> *identifierClasses = [NSSet setWithArray:@[[NSString class], [NSNumber class]]]; \
identifier = [decoder decodeObjectOfClasses:identifierClasses forKey:@"identifier"]; \
_attributes = [decoder decodeObjectOfClass:[NSDictionary class] forKey:@"attributes"]; \
- /* If this feature is a cluster, then change the class */ \
- if (MGLFeatureHasClusterAttribute(self)) { \
- MGLConvertFeatureToClusterSubclass(self); \
- } \
} \
return self; \
}
diff --git a/platform/darwin/src/MGLShapeSource.h b/platform/darwin/src/MGLShapeSource.h
index 1c37252a3d..2982fda068 100644
--- a/platform/darwin/src/MGLShapeSource.h
+++ b/platform/darwin/src/MGLShapeSource.h
@@ -5,8 +5,9 @@
NS_ASSUME_NONNULL_BEGIN
@protocol MGLFeature;
-@protocol MGLCluster;
+//@protocol MGLCluster;
@class MGLPointFeature;
+@class MGLPointFeatureCluster;
@class MGLShape;
/**
@@ -337,7 +338,7 @@ MGL_EXPORT
@return An array of objects that conform to the `MGLFeature` protocol.
*/
-- (NSArray<id <MGLFeature>> *)leavesOfCluster:(MGLShape<MGLCluster> *)cluster offset:(NSUInteger)offset limit:(NSUInteger)limit;
+- (NSArray<id <MGLFeature>> *)leavesOfCluster:(MGLPointFeatureCluster *)cluster offset:(NSUInteger)offset limit:(NSUInteger)limit;
/**
Returns an array of map features that are the immediate children of the specified
@@ -353,7 +354,7 @@ MGL_EXPORT
zoom level doesn't the zoom level for expanding that cluster. See
`-[MGLShapeSource zoomLevelForExpandingCluster:]`.
*/
-- (NSArray<id<MGLFeature>> *)childrenOfCluster:(MGLShape<MGLCluster> *)cluster;
+- (NSArray<id<MGLFeature>> *)childrenOfCluster:(MGLPointFeatureCluster *)cluster;
/**
Returns the zoom level at which the given cluster expands.
@@ -364,7 +365,7 @@ MGL_EXPORT
@return Zoom level. This should be >= 0; any negative return value should be
considered an error.
*/
-- (double)zoomLevelForExpandingCluster:(MGLShape<MGLCluster> *)cluster;
+- (double)zoomLevelForExpandingCluster:(MGLPointFeatureCluster *)cluster;
@end
diff --git a/platform/darwin/src/MGLShapeSource.mm b/platform/darwin/src/MGLShapeSource.mm
index 7720f94328..ac0f404756 100644
--- a/platform/darwin/src/MGLShapeSource.mm
+++ b/platform/darwin/src/MGLShapeSource.mm
@@ -7,7 +7,7 @@
#import "MGLSource_Private.h"
#import "MGLFeature_Private.h"
#import "MGLShape_Private.h"
-#import "MGLCluster_Private.h"
+#import "MGLCluster.h"
#import "NSPredicate+MGLPrivateAdditions.h"
#import "NSURL+MGLAdditions.h"
@@ -216,7 +216,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
}
-- (NSArray<id <MGLFeature>> *)leavesOfCluster:(MGLShape<MGLCluster> *)cluster offset:(NSUInteger)offset limit:(NSUInteger)limit {
+- (NSArray<id <MGLFeature>> *)leavesOfCluster:(MGLPointFeatureCluster *)cluster offset:(NSUInteger)offset limit:(NSUInteger)limit {
const std::map<std::string, mbgl::Value> options = {
{ "limit", static_cast<uint64_t>(limit) },
{ "offset", static_cast<uint64_t>(offset) }
@@ -236,7 +236,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
return MGLFeaturesFromMBGLFeatures(leaves);
}
-- (NSArray<id <MGLFeature>> *)childrenOfCluster:(MGLShape<MGLCluster> *)cluster {
+- (NSArray<id <MGLFeature>> *)childrenOfCluster:(MGLPointFeatureCluster *)cluster {
auto featureExtension = [self featureExtensionValueOfCluster:cluster extension:"children" options:{}];
if (!featureExtension) {
@@ -251,7 +251,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
return MGLFeaturesFromMBGLFeatures(leaves);
}
-- (double)zoomLevelForExpandingCluster:(MGLShape<MGLCluster> *)cluster {
+- (double)zoomLevelForExpandingCluster:(MGLPointFeatureCluster *)cluster {
auto featureExtension = [self featureExtensionValueOfCluster:cluster extension:"expansion-zoom" options:{}];
if (!featureExtension) {
@@ -282,7 +282,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
printf("%*s%s\n", (int)indent, "", log.UTF8String);
- id<MGLCluster> cluster = MGL_OBJC_DYNAMIC_CAST_AS_PROTOCOL(feature, MGLCluster);
+ MGLPointFeatureCluster *cluster = MGL_OBJC_DYNAMIC_CAST(feature, MGLPointFeatureCluster);
if (cluster) {
for (id <MGLFeature> child in [self childrenOfCluster:cluster]) {
diff --git a/platform/darwin/src/MGLShapeSource_Private.h b/platform/darwin/src/MGLShapeSource_Private.h
index 271aa2a9ee..c7eaf3d0a8 100644
--- a/platform/darwin/src/MGLShapeSource_Private.h
+++ b/platform/darwin/src/MGLShapeSource_Private.h
@@ -25,7 +25,7 @@ mbgl::style::GeoJSONOptions MGLGeoJSONOptionsFromDictionary(NSDictionary<MGLShap
@param indent Used during recursion. Specify 0.
*/
-- (void)debugRecursiveLogForFeature:(MGLShape<MGLFeature> *)feature indent:(NSUInteger)indent;
+- (void)debugRecursiveLogForFeature:(id<MGLFeature>)feature indent:(NSUInteger)indent;
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/test/MGLCodingTests.mm b/platform/darwin/test/MGLCodingTests.mm
index 2060992457..f4e5c8f13e 100644
--- a/platform/darwin/test/MGLCodingTests.mm
+++ b/platform/darwin/test/MGLCodingTests.mm
@@ -2,7 +2,7 @@
#import <XCTest/XCTest.h>
#import "MGLFoundation_Private.h"
-#import "MGLCluster_Private.h"
+#import "MGLCluster.h"
#if TARGET_OS_IPHONE
#import "MGLUserLocation_Private.h"
@@ -45,7 +45,7 @@
}
- (void)testPointFeatureCluster {
- MGLPointFeature *pointFeature = [[MGLPointFeature alloc] init];
+ MGLPointFeature *pointFeature = [[MGLPointFeatureCluster alloc] init];
pointFeature.title = @"title";
pointFeature.subtitle = @"subtitle";
pointFeature.identifier = @(123);
@@ -55,17 +55,17 @@
@"point_count" : @(2),
};
- XCTAssert([pointFeature isMemberOfClass:[MGLPointFeature class]], @"");
+ XCTAssert([pointFeature isKindOfClass:[MGLPointFeature class]], @"");
NSString *filePath = [self temporaryFilePathForClass:MGLPointFeature.class];
[NSKeyedArchiver archiveRootObject:pointFeature toFile:filePath];
MGLPointFeature *unarchivedPointFeature = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
XCTAssertEqualObjects(pointFeature, unarchivedPointFeature);
-
+
// Unarchive process should convert to a cluster
- NSString *subclassName = MGLClusterSubclassNameForFeature(pointFeature);
- XCTAssert([unarchivedPointFeature isMemberOfClass:NSClassFromString(subclassName)]);
+// NSString *subclassName = MGLClusterSubclassNameForFeature(pointFeature);
+ XCTAssert([unarchivedPointFeature isMemberOfClass:[MGLPointFeatureCluster class]]);
id<MGLCluster> cluster = MGL_OBJC_DYNAMIC_CAST_AS_PROTOCOL(unarchivedPointFeature, MGLCluster);
@@ -73,12 +73,12 @@
XCTAssert(cluster.clusterIdentifier == 456);
XCTAssert(cluster.clusterPointCount == 2);
- // Archiving shouldn't affect
- [NSKeyedArchiver archiveRootObject:unarchivedPointFeature toFile:filePath];
- MGLPointFeature *unarchivedPointFeature2 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
-
- XCTAssert([unarchivedPointFeature2 isMemberOfClass:NSClassFromString(@"MGLPointFeature_Cluster")]);
- XCTAssertEqualObjects(pointFeature, unarchivedPointFeature2);
+// // Archiving shouldn't affect
+// [NSKeyedArchiver archiveRootObject:unarchivedPointFeature toFile:filePath];
+// MGLPointFeature *unarchivedPointFeature2 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
+//
+// XCTAssert([unarchivedPointFeature2 isMemberOfClass:[MGLPointFeatureCluster class]]);
+// XCTAssertEqualObjects(pointFeature, unarchivedPointFeature2);
}
diff --git a/platform/darwin/test/MGLFeatureTests.mm b/platform/darwin/test/MGLFeatureTests.mm
index 87f288f3ce..edc105bca4 100644
--- a/platform/darwin/test/MGLFeatureTests.mm
+++ b/platform/darwin/test/MGLFeatureTests.mm
@@ -102,6 +102,8 @@
XCTAssert(cluster);
XCTAssert(cluster.clusterIdentifier == 1);
XCTAssert(cluster.clusterPointCount == 5);
+
+ XCTAssert([cluster isMemberOfClass:[MGLPointFeatureCluster class]]);
}
- (void)testPropertyConversion {
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index ed803fe107..2c4d7f2eab 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -474,21 +474,17 @@
CA0C27942076CA19001CE5B7 /* MGLMapViewIntegrationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CA0C27932076CA19001CE5B7 /* MGLMapViewIntegrationTest.m */; };
CA1B4A512099FB2200EDD491 /* MGLMapSnapshotterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CA1B4A502099FB2200EDD491 /* MGLMapSnapshotterTest.m */; };
CA34C9C3207FD272005C1A06 /* MGLCameraTransitionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA34C9C2207FD272005C1A06 /* MGLCameraTransitionTests.mm */; };
- CA42323B2159242400BB7C18 /* MGLCluster.h in Headers */ = {isa = PBXBuildFile; fileRef = CA42323A2159242400BB7C18 /* MGLCluster.h */; settings = {ATTRIBUTES = (Public, ); }; };
- CA42323C2159242400BB7C18 /* MGLCluster.h in Headers */ = {isa = PBXBuildFile; fileRef = CA42323A2159242400BB7C18 /* MGLCluster.h */; settings = {ATTRIBUTES = (Public, ); }; };
CA4EB8C720863487006AB465 /* MGLStyleLayerIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CA4EB8C620863487006AB465 /* MGLStyleLayerIntegrationTests.m */; };
CA55CD41202C16AA00CE7095 /* MGLCameraChangeReason.h in Headers */ = {isa = PBXBuildFile; fileRef = CA55CD3E202C16AA00CE7095 /* MGLCameraChangeReason.h */; settings = {ATTRIBUTES = (Public, ); }; };
CA55CD42202C16AA00CE7095 /* MGLCameraChangeReason.h in Headers */ = {isa = PBXBuildFile; fileRef = CA55CD3E202C16AA00CE7095 /* MGLCameraChangeReason.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ CA65C4F821E9BB080068B0D4 /* MGLCluster.h in Headers */ = {isa = PBXBuildFile; fileRef = CA65C4F721E9BB080068B0D4 /* MGLCluster.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ CA65C4F921E9BB080068B0D4 /* MGLCluster.h in Headers */ = {isa = PBXBuildFile; fileRef = CA65C4F721E9BB080068B0D4 /* MGLCluster.h */; settings = {ATTRIBUTES = (Public, ); }; };
CA6914B520E67F50002DB0EE /* MGLAnnotationViewIntegrationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CA6914B420E67F50002DB0EE /* MGLAnnotationViewIntegrationTests.m */; };
CA88DC3021C85D900059ED5A /* MGLStyleURLIntegrationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CA88DC2F21C85D900059ED5A /* MGLStyleURLIntegrationTest.m */; };
CA8FBC0921A47BB100D1203C /* MGLRendererConfigurationTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = CA8FBC0821A47BB100D1203C /* MGLRendererConfigurationTests.mm */; };
CAA69DA4206DCD0E007279CD /* Mapbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA4A26961CB6E795000B7809 /* Mapbox.framework */; };
CAA69DA5206DCD0E007279CD /* Mapbox.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DA4A26961CB6E795000B7809 /* Mapbox.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
CABE5DAD2072FAB40003AF3C /* Mapbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA8847D21CBAF91600AB86E3 /* Mapbox.framework */; };
- CAE21180216552AE00429B6F /* MGLCluster.mm in Sources */ = {isa = PBXBuildFile; fileRef = CAE2117F216552AE00429B6F /* MGLCluster.mm */; };
- CAE21181216552AE00429B6F /* MGLCluster.mm in Sources */ = {isa = PBXBuildFile; fileRef = CAE2117F216552AE00429B6F /* MGLCluster.mm */; };
- CAE211832165BD0300429B6F /* MGLCluster_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CAE211822165BD0300429B6F /* MGLCluster_Private.h */; };
- CAE211842165BD0300429B6F /* MGLCluster_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CAE211822165BD0300429B6F /* MGLCluster_Private.h */; };
CAE7AD5520F46EF5003B6782 /* MGLMapSnapshotterSwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAE7AD5420F46EF5003B6782 /* MGLMapSnapshotterSwiftTests.swift */; };
DA00FC8E1D5EEB0D009AABC8 /* MGLAttributionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DA00FC8C1D5EEB0D009AABC8 /* MGLAttributionInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
DA00FC8F1D5EEB0D009AABC8 /* MGLAttributionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DA00FC8C1D5EEB0D009AABC8 /* MGLAttributionInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -1146,15 +1142,13 @@
CA0C27952076CA50001CE5B7 /* MGLMapViewIntegrationTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLMapViewIntegrationTest.h; sourceTree = "<group>"; };
CA1B4A502099FB2200EDD491 /* MGLMapSnapshotterTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLMapSnapshotterTest.m; sourceTree = "<group>"; };
CA34C9C2207FD272005C1A06 /* MGLCameraTransitionTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLCameraTransitionTests.mm; sourceTree = "<group>"; };
- CA42323A2159242400BB7C18 /* MGLCluster.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLCluster.h; sourceTree = "<group>"; };
CA4EB8C620863487006AB465 /* MGLStyleLayerIntegrationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLStyleLayerIntegrationTests.m; sourceTree = "<group>"; };
CA55CD3E202C16AA00CE7095 /* MGLCameraChangeReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLCameraChangeReason.h; sourceTree = "<group>"; };
CA5E5042209BDC5F001A8A81 /* MGLTestUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MGLTestUtility.h; path = ../../darwin/test/MGLTestUtility.h; sourceTree = "<group>"; };
+ CA65C4F721E9BB080068B0D4 /* MGLCluster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLCluster.h; sourceTree = "<group>"; };
CA6914B420E67F50002DB0EE /* MGLAnnotationViewIntegrationTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MGLAnnotationViewIntegrationTests.m; path = "Annotation Tests/MGLAnnotationViewIntegrationTests.m"; sourceTree = "<group>"; };
CA88DC2F21C85D900059ED5A /* MGLStyleURLIntegrationTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLStyleURLIntegrationTest.m; sourceTree = "<group>"; };
CA8FBC0821A47BB100D1203C /* MGLRendererConfigurationTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLRendererConfigurationTests.mm; path = ../../darwin/test/MGLRendererConfigurationTests.mm; sourceTree = "<group>"; };
- CAE2117F216552AE00429B6F /* MGLCluster.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLCluster.mm; sourceTree = "<group>"; wrapsLines = 0; };
- CAE211822165BD0300429B6F /* MGLCluster_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLCluster_Private.h; sourceTree = "<group>"; };
CAE7AD5320F46EF5003B6782 /* integration-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "integration-Bridging-Header.h"; sourceTree = "<group>"; };
CAE7AD5420F46EF5003B6782 /* MGLMapSnapshotterSwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MGLMapSnapshotterSwiftTests.swift; sourceTree = "<group>"; };
DA00FC8C1D5EEB0D009AABC8 /* MGLAttributionInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAttributionInfo.h; sourceTree = "<group>"; };
@@ -2216,10 +2210,8 @@
DAD165811CF4CFC4001FF4B9 /* Geometry */ = {
isa = PBXGroup;
children = (
+ CA65C4F721E9BB080068B0D4 /* MGLCluster.h */,
DA8847E01CBAFA5100AB86E3 /* MGLAnnotation.h */,
- CAE211822165BD0300429B6F /* MGLCluster_Private.h */,
- CA42323A2159242400BB7C18 /* MGLCluster.h */,
- CAE2117F216552AE00429B6F /* MGLCluster.mm */,
DAD1656A1CF41981001FF4B9 /* MGLFeature_Private.h */,
DAD165691CF41981001FF4B9 /* MGLFeature.h */,
DAD1656B1CF41981001FF4B9 /* MGLFeature.mm */,
@@ -2363,8 +2355,8 @@
DA88483A1CBAFB8500AB86E3 /* MGLAnnotationImage.h in Headers */,
74CB5EBD219B280400102936 /* MGLFillStyleLayer_Private.h in Headers */,
DAF2571B201901E200367EF5 /* MGLHillshadeStyleLayer.h in Headers */,
+ CA65C4F821E9BB080068B0D4 /* MGLCluster.h in Headers */,
DA35A2BB1CCA9A6900E826B2 /* MGLClockDirectionFormatter.h in Headers */,
- CAE211832165BD0300429B6F /* MGLCluster_Private.h in Headers */,
353933FE1D3FB7DD003F57D7 /* MGLSymbolStyleLayer.h in Headers */,
DA8848201CBAFA6200AB86E3 /* MGLOfflinePack_Private.h in Headers */,
DA00FC8E1D5EEB0D009AABC8 /* MGLAttributionInfo.h in Headers */,
@@ -2551,8 +2543,6 @@
55E5666C21C2A2080008B8B5 /* MMEDispatchManager.h in Headers */,
55E5666121C2A2080008B8B5 /* MMEEventsManager.h in Headers */,
55E5666D21C2A2080008B8B5 /* NSData+MMEGZIP.h in Headers */,
- CA42323B2159242400BB7C18 /* MGLPointCluster.h in Headers */,
- CA42323B2159242400BB7C18 /* MGLCluster.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2586,6 +2576,7 @@
071BBB041EE76147001FB02A /* MGLImageSource.h in Headers */,
74CB5EC0219B280400102936 /* MGLHeatmapStyleLayer_Private.h in Headers */,
74CB5ECB219B285000102936 /* MGLLineStyleLayer_Private.h in Headers */,
+ CA65C4F921E9BB080068B0D4 /* MGLCluster.h in Headers */,
DABFB8611CBE99E500D62B32 /* MGLMultiPoint.h in Headers */,
74CB5ECD219B285000102936 /* MGLOpenGLStyleLayer_Private.h in Headers */,
74CB5ECF219B285000102936 /* MGLRasterStyleLayer_Private.h in Headers */,
@@ -2612,7 +2603,6 @@
DABFB8621CBE99E500D62B32 /* MGLOfflinePack.h in Headers */,
96E516FA20005A3D00A02306 /* MGLUserLocationHeadingArrowLayer.h in Headers */,
96E516E62000560B00A02306 /* MGLOfflineRegion_Private.h in Headers */,
- CAE211842165BD0300429B6F /* MGLCluster_Private.h in Headers */,
DAD1656D1CF41981001FF4B9 /* MGLFeature.h in Headers */,
96E516E72000560B00A02306 /* MGLOfflineStorage_Private.h in Headers */,
DA17BE311CC4BDAA00402C41 /* MGLMapView_Private.h in Headers */,
@@ -2671,7 +2661,6 @@
DAC25FCD200FD83F009BE98E /* NSExpression+MGLPrivateAdditions.h in Headers */,
74CB5ED2219B286400102936 /* MGLSymbolStyleLayer_Private.h in Headers */,
354B83971D2E873E005D9406 /* MGLUserLocationAnnotationView.h in Headers */,
- CA42323C2159242400BB7C18 /* MGLCluster.h in Headers */,
DAF0D8111DFE0EA000B28378 /* MGLRasterTileSource_Private.h in Headers */,
96E516FF20005A4F00A02306 /* MGLMapboxEvents.h in Headers */,
1F6A82A321360F9D00BA5B41 /* MGLLoggingConfiguration.h in Headers */,
@@ -3212,7 +3201,6 @@
DA8848501CBAFB9800AB86E3 /* MGLAnnotationImage.m in Sources */,
40834BF01FE05E1800C1BD0D /* MMELocationManager.m in Sources */,
DA8848281CBAFA6200AB86E3 /* MGLShape.mm in Sources */,
- CAE21180216552AE00429B6F /* MGLCluster.mm in Sources */,
DA35A2B31CCA141D00E826B2 /* MGLCompassDirectionFormatter.m in Sources */,
DD0902A91DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */,
35D13AB91D3D15E300AFB4E0 /* MGLStyleLayer.mm in Sources */,
@@ -3348,7 +3336,6 @@
40834C041FE05E1800C1BD0D /* MMELocationManager.m in Sources */,
DA35A2B41CCA141D00E826B2 /* MGLCompassDirectionFormatter.m in Sources */,
35D13ABA1D3D15E300AFB4E0 /* MGLStyleLayer.mm in Sources */,
- CAE21181216552AE00429B6F /* MGLCluster.mm in Sources */,
071BBAFF1EE7613E001FB02A /* MGLImageSource.mm in Sources */,
DA35A2CC1CCAAAD200E826B2 /* NSValue+MGLAdditions.m in Sources */,
40834C591FE05F7600C1BD0D /* TSKTrustKitConfig.m in Sources */,