diff options
author | Julian Rex <julian.rex@mapbox.com> | 2019-01-12 01:25:18 -0500 |
---|---|---|
committer | Julian Rex <julian.rex@mapbox.com> | 2019-01-12 14:36:51 -0500 |
commit | 360ad1c06ddb2cb8219d480908eedc3bc8a00e42 (patch) | |
tree | 86974013620359e656cf3702cd460d56e5d40e2e | |
parent | 8c4066d6a74ac6b89463c2629fa7397fe99ef818 (diff) | |
download | qtlocation-mapboxgl-360ad1c06ddb2cb8219d480908eedc3bc8a00e42.tar.gz |
Introduces MGLPointFeatureCluster subclass (since update feature extension required MGLShape)
-rw-r--r-- | platform/darwin/src/MGLCluster.h | 7 | ||||
-rw-r--r-- | platform/darwin/src/MGLCluster.mm | 155 | ||||
-rw-r--r-- | platform/darwin/src/MGLCluster_Private.h | 19 | ||||
-rw-r--r-- | platform/darwin/src/MGLFeature.h | 6 | ||||
-rw-r--r-- | platform/darwin/src/MGLFeature.mm | 74 | ||||
-rw-r--r-- | platform/darwin/src/MGLFeature_Private.h | 4 | ||||
-rw-r--r-- | platform/darwin/src/MGLShapeSource.h | 9 | ||||
-rw-r--r-- | platform/darwin/src/MGLShapeSource.mm | 10 | ||||
-rw-r--r-- | platform/darwin/src/MGLShapeSource_Private.h | 2 | ||||
-rw-r--r-- | platform/darwin/test/MGLCodingTests.mm | 24 | ||||
-rw-r--r-- | platform/darwin/test/MGLFeatureTests.mm | 2 | ||||
-rw-r--r-- | platform/ios/ios.xcodeproj/project.pbxproj | 25 |
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 */, |