├── FBAnnotationClustering ├── .gitkeep ├── FBAnnotationCluster.m ├── FBAnnotationClustering.h ├── Info.plist ├── FBAnnotationCluster.h ├── FBQuadTree.h ├── FBQuadTreeNode.h ├── FBClusteringManager.h ├── FBQuadTreeNode.m ├── FBQuadTree.m └── FBClusteringManager.m ├── CHANGELOG.md ├── Images └── example.png ├── Example ├── AnnotationClustering │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── main.m │ ├── AnnotationClustering-Prefix.pch │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── AnnotationClustering-Info.plist │ └── Base.lproj │ │ ├── Main_iPad.storyboard │ │ └── Main_iPhone.storyboard ├── AnnotationClusteringTests │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── AnnotationClusteringTests-Info.plist │ └── AnnotationClusteringTests.m ├── Pods │ ├── Headers │ │ ├── Public │ │ │ └── FBAnnotationClustering │ │ │ │ ├── FBQuadTree.h │ │ │ │ ├── FBQuadTreeNode.h │ │ │ │ ├── FBAnnotationCluster.h │ │ │ │ ├── FBClusteringManager.h │ │ │ │ └── FBAnnotationClustering.h │ │ └── Private │ │ │ └── FBAnnotationClustering │ │ │ ├── FBQuadTree.h │ │ │ ├── FBQuadTreeNode.h │ │ │ ├── FBAnnotationCluster.h │ │ │ ├── FBClusteringManager.h │ │ │ └── FBAnnotationClustering.h │ ├── Target Support Files │ │ ├── Pods │ │ │ ├── Pods-dummy.m │ │ │ ├── Pods.debug.xcconfig │ │ │ ├── Pods.release.xcconfig │ │ │ ├── Pods-environment.h │ │ │ ├── Pods-acknowledgements.markdown │ │ │ ├── Pods-acknowledgements.plist │ │ │ └── Pods-resources.sh │ │ └── Pods-FBAnnotationClustering │ │ │ ├── Pods-FBAnnotationClustering.xcconfig │ │ │ ├── Pods-FBAnnotationClustering-prefix.pch │ │ │ ├── Pods-FBAnnotationClustering-dummy.m │ │ │ └── Pods-FBAnnotationClustering-Private.xcconfig │ ├── Manifest.lock │ ├── Local Podspecs │ │ └── FBAnnotationClustering.podspec.json │ └── Pods.xcodeproj │ │ └── project.pbxproj ├── Podfile ├── AnnotationClustering.xcworkspace │ └── contents.xcworkspacedata ├── AnnotationClustering.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── project.pbxproj ├── Classes │ ├── Models │ │ ├── FBAnnotation.m │ │ └── FBAnnotation.h │ ├── Application │ │ ├── FBAppDelegate.h │ │ └── FBAppDelegate.m │ └── Controllers │ │ ├── FBViewController.h │ │ └── FBViewController.m └── Podfile.lock ├── FBAnnotationClustering.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcshareddata │ └── xcschemes │ │ └── FBAnnotationClustering.xcscheme └── project.pbxproj ├── .gitignore ├── FBAnnotationClustering.podspec ├── LICENSE ├── README.md └── Rakefile /FBAnnotationClustering/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # FBAnnotationClustering CHANGELOG 2 | 3 | ## 0.1.0 4 | 5 | Initial release. 6 | -------------------------------------------------------------------------------- /Images/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/infinum/FBAnnotationClustering/HEAD/Images/example.png -------------------------------------------------------------------------------- /Example/AnnotationClustering/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/AnnotationClusteringTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/Pods/Headers/Public/FBAnnotationClustering/FBQuadTree.h: -------------------------------------------------------------------------------- 1 | ../../../../../FBAnnotationClustering/FBQuadTree.h -------------------------------------------------------------------------------- /Example/Pods/Headers/Private/FBAnnotationClustering/FBQuadTree.h: -------------------------------------------------------------------------------- 1 | ../../../../../FBAnnotationClustering/FBQuadTree.h -------------------------------------------------------------------------------- /Example/Pods/Headers/Private/FBAnnotationClustering/FBQuadTreeNode.h: -------------------------------------------------------------------------------- 1 | ../../../../../FBAnnotationClustering/FBQuadTreeNode.h -------------------------------------------------------------------------------- /Example/Pods/Headers/Public/FBAnnotationClustering/FBQuadTreeNode.h: -------------------------------------------------------------------------------- 1 | ../../../../../FBAnnotationClustering/FBQuadTreeNode.h -------------------------------------------------------------------------------- /Example/Pods/Headers/Private/FBAnnotationClustering/FBAnnotationCluster.h: -------------------------------------------------------------------------------- 1 | ../../../../../FBAnnotationClustering/FBAnnotationCluster.h -------------------------------------------------------------------------------- /Example/Pods/Headers/Private/FBAnnotationClustering/FBClusteringManager.h: -------------------------------------------------------------------------------- 1 | ../../../../../FBAnnotationClustering/FBClusteringManager.h -------------------------------------------------------------------------------- /Example/Pods/Headers/Public/FBAnnotationClustering/FBAnnotationCluster.h: -------------------------------------------------------------------------------- 1 | ../../../../../FBAnnotationClustering/FBAnnotationCluster.h -------------------------------------------------------------------------------- /Example/Pods/Headers/Public/FBAnnotationClustering/FBClusteringManager.h: -------------------------------------------------------------------------------- 1 | ../../../../../FBAnnotationClustering/FBClusteringManager.h -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | target "AnnotationClustering" do 2 | pod "FBAnnotationClustering", :path => "../FBAnnotationClustering.podspec" 3 | end -------------------------------------------------------------------------------- /Example/Pods/Headers/Private/FBAnnotationClustering/FBAnnotationClustering.h: -------------------------------------------------------------------------------- 1 | ../../../../../FBAnnotationClustering/FBAnnotationClustering.h -------------------------------------------------------------------------------- /Example/Pods/Headers/Public/FBAnnotationClustering/FBAnnotationClustering.h: -------------------------------------------------------------------------------- 1 | ../../../../../FBAnnotationClustering/FBAnnotationClustering.h -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods/Pods-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods : NSObject 3 | @end 4 | @implementation PodsDummy_Pods 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FBAnnotationClustering/Pods-FBAnnotationClustering.xcconfig: -------------------------------------------------------------------------------- 1 | PODS_FBANNOTATIONCLUSTERING_OTHER_LDFLAGS = -framework "CoreLocation" -framework "MapKit" -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FBAnnotationClustering/Pods-FBAnnotationClustering-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #import "Pods-environment.h" 6 | -------------------------------------------------------------------------------- /Example/AnnotationClustering.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /FBAnnotationClustering.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/AnnotationClustering.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FBAnnotationClustering/Pods-FBAnnotationClustering-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_FBAnnotationClustering : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_FBAnnotationClustering 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Classes/Models/FBAnnotation.m: -------------------------------------------------------------------------------- 1 | // 2 | // FBAnnotation.m 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 06/01/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import "FBAnnotation.h" 10 | 11 | @implementation FBAnnotation 12 | 13 | 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | -------------------------------------------------------------------------------- /FBAnnotationClustering/FBAnnotationCluster.m: -------------------------------------------------------------------------------- 1 | // 2 | // FBAnnotationCluster.m 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 06/01/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import "FBAnnotationCluster.h" 10 | 11 | @implementation FBAnnotationCluster 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Classes/Application/FBAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // FBAppDelegate.h 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 06/04/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FBAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FBAnnotationClustering (0.1.2) 3 | 4 | DEPENDENCIES: 5 | - FBAnnotationClustering (from `../FBAnnotationClustering.podspec`) 6 | 7 | EXTERNAL SOURCES: 8 | FBAnnotationClustering: 9 | :path: ../FBAnnotationClustering.podspec 10 | 11 | SPEC CHECKSUMS: 12 | FBAnnotationClustering: 8be556cf48b27262acab01ad8419bc01703615e3 13 | 14 | COCOAPODS: 0.37.1 15 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FBAnnotationClustering (0.1.2) 3 | 4 | DEPENDENCIES: 5 | - FBAnnotationClustering (from `../FBAnnotationClustering.podspec`) 6 | 7 | EXTERNAL SOURCES: 8 | FBAnnotationClustering: 9 | :path: ../FBAnnotationClustering.podspec 10 | 11 | SPEC CHECKSUMS: 12 | FBAnnotationClustering: 8be556cf48b27262acab01ad8419bc01703615e3 13 | 14 | COCOAPODS: 0.37.1 15 | -------------------------------------------------------------------------------- /Example/Classes/Controllers/FBViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FBViewController.h 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 06/04/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface FBViewController : UIViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /FBAnnotationClustering/FBAnnotationClustering.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject_FBAnnotationClustering.h 3 | // Pods 4 | // 5 | // Created by Filip Beć on 04/09/14. 6 | // 7 | // 8 | 9 | #import 10 | 11 | #ifndef _FBANNOTATIONCLUSTERING_ 12 | #define _FBANNOTATIONCLUSTERING_ 13 | 14 | #import "FBClusteringManager.h" 15 | #import "FBAnnotationCluster.h" 16 | #import "FBQuadTree.h" 17 | #endif /* _FBANNOTATIONCLUSTERING_ */ 18 | -------------------------------------------------------------------------------- /Example/AnnotationClustering/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 06/04/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "FBAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([FBAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/Classes/Models/FBAnnotation.h: -------------------------------------------------------------------------------- 1 | // 2 | // FBAnnotation.h 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 06/01/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | @import MapKit; 11 | 12 | // My custom annotation objects 13 | 14 | @interface FBAnnotation : NSObject 15 | 16 | @property (nonatomic, assign) CLLocationCoordinate2D coordinate; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Example/AnnotationClustering/AnnotationClustering-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-FBAnnotationClustering/Pods-FBAnnotationClustering-Private.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods-FBAnnotationClustering.xcconfig" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/FBAnnotationClustering" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FBAnnotationClustering" 4 | OTHER_LDFLAGS = ${PODS_FBANNOTATIONCLUSTERING_OTHER_LDFLAGS} -ObjC 5 | PODS_ROOT = ${SRCROOT} 6 | SKIP_INSTALL = YES -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods/Pods.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FBAnnotationClustering" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/FBAnnotationClustering" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"Pods-FBAnnotationClustering" -framework "CoreLocation" -framework "MapKit" 5 | OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) 6 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods/Pods.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FBAnnotationClustering" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/FBAnnotationClustering" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"Pods-FBAnnotationClustering" -framework "CoreLocation" -framework "MapKit" 5 | OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) 6 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods/Pods-environment.h: -------------------------------------------------------------------------------- 1 | 2 | // To check if a library is compiled with CocoaPods you 3 | // can use the `COCOAPODS` macro definition which is 4 | // defined in the xcconfigs so it is available in 5 | // headers also when they are imported in the client 6 | // project. 7 | 8 | 9 | // FBAnnotationClustering 10 | #define COCOAPODS_POD_AVAILABLE_FBAnnotationClustering 11 | #define COCOAPODS_VERSION_MAJOR_FBAnnotationClustering 0 12 | #define COCOAPODS_VERSION_MINOR_FBAnnotationClustering 1 13 | #define COCOAPODS_VERSION_PATCH_FBAnnotationClustering 2 14 | 15 | -------------------------------------------------------------------------------- /Example/AnnotationClusteringTests/AnnotationClusteringTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.infinum.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/AnnotationClusteringTests/AnnotationClusteringTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // AnnotationClusteringTests.m 3 | // AnnotationClusteringTests 4 | // 5 | // Created by Filip Bec on 06/04/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AnnotationClusteringTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation AnnotationClusteringTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/FBAnnotationClustering.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "FBAnnotationClustering", 3 | "version": "0.1.2", 4 | "summary": "Clustering library for iOS maps", 5 | "homepage": "https://github.com/infinum/FBAnnotationClustering", 6 | "screenshots": "https://raw.githubusercontent.com/infinum/FBAnnotationClustering/master/Images/example.png", 7 | "license": "MIT", 8 | "authors": { 9 | "Filip Beć": "filip.bec@gmail.com" 10 | }, 11 | "source": { 12 | "git": "https://github.com/infinum/FBAnnotationClustering.git", 13 | "tag": "0.1.2" 14 | }, 15 | "social_media_url": "https://twitter.com/FilipBec", 16 | "requires_arc": true, 17 | "platforms": { 18 | "ios": "6.0" 19 | }, 20 | "source_files": "FBAnnotationClustering", 21 | "public_header_files": "FBAnnotationClustering/*.h", 22 | "frameworks": [ 23 | "CoreLocation", 24 | "MapKit" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /FBAnnotationClustering/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /FBAnnotationClustering.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'FBAnnotationClustering' 3 | s.version = '0.2.2' 4 | s.summary = 'Clustering library for iOS maps' 5 | s.homepage = 'https://github.com/infinum/FBAnnotationClustering' 6 | s.screenshots = 'https://raw.githubusercontent.com/infinum/FBAnnotationClustering/master/Images/example.png' 7 | s.license = 'MIT' 8 | s.author = { 'Filip Beć' => 'filip.bec@gmail.com' } 9 | s.source = { :git => 'https://github.com/infinum/FBAnnotationClustering.git', :tag => '0.2.2' } 10 | s.social_media_url = 'https://twitter.com/FilipBec' 11 | s.requires_arc = true 12 | 13 | s.ios.deployment_target = '6.0' 14 | s.tvos.deployment_target = '9.2' 15 | 16 | s.source_files = 'FBAnnotationClustering' 17 | s.public_header_files = 'FBAnnotationClustering/*.h' 18 | 19 | s.frameworks = 'CoreLocation', 'MapKit' 20 | end 21 | -------------------------------------------------------------------------------- /FBAnnotationClustering/FBAnnotationCluster.h: -------------------------------------------------------------------------------- 1 | // 2 | // FBAnnotationCluster.h 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 06/01/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | /** 14 | Class that is used to display annotation clusters. 15 | */ 16 | @interface FBAnnotationCluster : NSObject 17 | 18 | /// Coordinate of the annotation. It will always be set. 19 | @property (nonatomic, assign) CLLocationCoordinate2D coordinate; 20 | 21 | /// Title of the annotation. Default is @c nil, but can be set. 22 | @property (nonatomic, copy) NSString *title; 23 | 24 | /// Subtitle of the annotation. Default is @c nil, but can be set. 25 | @property (nonatomic, copy) NSString *subtitle; 26 | 27 | /// Array of the annotations that are representer with this cluster. 28 | @property (nonatomic, strong) NSArray *annotations; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /FBAnnotationClustering/FBQuadTree.h: -------------------------------------------------------------------------------- 1 | // 2 | // FBQuadTree.h 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 05/01/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FBQuadTreeNode.h" 11 | 12 | /** 13 | Quad Tree. You should never use this class. 14 | */ 15 | @interface FBQuadTree : NSObject 16 | 17 | /// Root node. 18 | @property (nonatomic, strong) FBQuadTreeNode *rootNode; 19 | 20 | 21 | /** 22 | Insert new annotation in tree. 23 | */ 24 | - (BOOL)insertAnnotation:(id)annotation; 25 | 26 | /** 27 | Remove an annotation from the tree. 28 | */ 29 | - (BOOL)removeAnnotation:(id)annotation; 30 | 31 | /** 32 | Enumerate annotations in @c box. 33 | */ 34 | - (void)enumerateAnnotationsInBox:(FBBoundingBox)box usingBlock:(void (^)(id obj))block; 35 | 36 | 37 | /** 38 | Enumerate all annotations. 39 | */ 40 | - (void)enumerateAnnotationsUsingBlock:(void (^)(id obj))block; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Example/AnnotationClustering/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Filip Beć 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Example/AnnotationClustering/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## FBAnnotationClustering 5 | 6 | Copyright (c) 2014 Filip Beć 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - http://cocoapods.org 27 | -------------------------------------------------------------------------------- /Example/AnnotationClustering/AnnotationClustering-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.infinum.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | Main_iPhone 29 | UIMainStoryboardFile~ipad 30 | Main_iPad 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /FBAnnotationClustering/FBQuadTreeNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // FBQuadTreeNode.h 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 05/01/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | #define kNodeCapacity 8 13 | 14 | typedef struct { 15 | CGFloat x0; 16 | CGFloat y0; 17 | CGFloat xf; 18 | CGFloat yf; 19 | } FBBoundingBox; 20 | 21 | FBBoundingBox FBBoundingBoxMake(CGFloat x0, CGFloat y0, CGFloat xf, CGFloat yf); 22 | 23 | FBBoundingBox FBBoundingBoxForMapRect(MKMapRect mapRect); 24 | MKMapRect FBMapRectForBoundingBox(FBBoundingBox boundingBox); 25 | 26 | BOOL FBBoundingBoxContainsCoordinate(FBBoundingBox box, CLLocationCoordinate2D coordinate); 27 | BOOL FBBoundingBoxIntersectsBoundingBox(FBBoundingBox box1, FBBoundingBox box2); 28 | 29 | 30 | /** 31 | Quad Tree Node. You should never use this class. 32 | */ 33 | @interface FBQuadTreeNode : NSObject 34 | 35 | @property (nonatomic, assign) NSUInteger count; 36 | @property (nonatomic, assign) FBBoundingBox boundingBox; 37 | 38 | @property (nonatomic, strong) NSMutableArray *annotations; 39 | 40 | @property (nonatomic, strong) FBQuadTreeNode *northEast; 41 | @property (nonatomic, strong) FBQuadTreeNode *northWest; 42 | @property (nonatomic, strong) FBQuadTreeNode *southEast; 43 | @property (nonatomic, strong) FBQuadTreeNode *southWest; 44 | 45 | 46 | /** 47 | Custom init method. 48 | @param box Bounding box of the node. 49 | @returns An instance of @c FBQuadTreeNode 50 | */ 51 | - (id)initWithBoundingBox:(FBBoundingBox)box; 52 | 53 | /** 54 | Check if node is leaf in tree. 55 | @returns @c YES if node is leaf, else returns @c NO 56 | */ 57 | - (BOOL)isLeaf; 58 | 59 | /** 60 | Create new child nodes. 61 | */ 62 | - (void)subdivide; 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /Example/Classes/Application/FBAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // FBAppDelegate.m 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 06/04/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import "FBAppDelegate.h" 10 | 11 | @implementation FBAppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods/Pods-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2014 Filip Beć <filip.bec@gmail.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | Title 38 | FBAnnotationClustering 39 | Type 40 | PSGroupSpecifier 41 | 42 | 43 | FooterText 44 | Generated by CocoaPods - http://cocoapods.org 45 | Title 46 | 47 | Type 48 | PSGroupSpecifier 49 | 50 | 51 | StringsTable 52 | Acknowledgements 53 | Title 54 | Acknowledgements 55 | 56 | 57 | -------------------------------------------------------------------------------- /FBAnnotationClustering.xcodeproj/xcshareddata/xcschemes/FBAnnotationClustering.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /FBAnnotationClustering/FBClusteringManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // FBClusterManager.h 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 05/01/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FBQuadTreeNode.h" 11 | #import "FBAnnotationCluster.h" 12 | 13 | @class FBClusteringManager; 14 | 15 | @protocol FBClusteringManagerDelegate 16 | @optional 17 | /** 18 | Method that allows you to define factor for default size of cluster cells. 19 | @param coordinator An instance of FBClusterManager. 20 | 21 | @discussion Cell size factor will scale size of default cell size. With value smaller than 1.0 cell size will be smaller than default and you will see more clusters on the map. With factor larger than 1.0 cell size will be bigger than default and you will see less clusters on the map. 22 | */ 23 | - (CGFloat)cellSizeFactorForCoordinator:(FBClusteringManager *)coordinator; 24 | 25 | @end 26 | 27 | 28 | /** 29 | Class that is responsible for clustering coordination. 30 | */ 31 | @interface FBClusteringManager : NSObject 32 | 33 | 34 | @property (nonatomic, assign) id delegate; 35 | 36 | 37 | /** 38 | Creates a new instance of @c FBClusterManager with array of annotations. 39 | 40 | @param annotations Custom annotation objects. 41 | @returns An instance of FBClusterManager 42 | */ 43 | - (id)initWithAnnotations:(NSArray *)annotations; 44 | 45 | 46 | /** 47 | Replace current annotations new array of annotations. 48 | 49 | @param annotations Custom annotation objects. 50 | */ 51 | - (void)setAnnotations:(NSArray *)annotations; 52 | 53 | 54 | /** 55 | Add array of annotations to current annotation collection. 56 | 57 | @param annotations Custom annotation objects. 58 | */ 59 | - (void)addAnnotations:(NSArray *)annotations; 60 | 61 | 62 | /** 63 | Remove array of annotations from current collection. 64 | 65 | @param annotations Custom annotation objects. 66 | */ 67 | - (void)removeAnnotations:(NSArray *)annotations; 68 | 69 | 70 | /** 71 | Method that return array of your custom annotations or annotation clusters. 72 | 73 | @param rect An instance of MKMapRect. 74 | @param zoomScale An instance of MKMapRect. 75 | @returns Array of annotations objects of type @c FBAnnotationCluster or your custom class. 76 | */ 77 | - (NSArray *)clusteredAnnotationsWithinMapRect:(MKMapRect)rect 78 | withZoomScale:(double)zoomScale; 79 | 80 | - (NSArray *)clusteredAnnotationsWithinMapRect:(MKMapRect)rect 81 | withZoomScale:(double)zoomScale 82 | withFilter:(BOOL (^)(id)) filter; 83 | 84 | /** 85 | All annotations in quad tree. 86 | @returns Array of annotations of your custom class. 87 | */ 88 | - (NSArray *)allAnnotations; 89 | 90 | 91 | /** 92 | Method that will update map with new annotations. 93 | @param annotations Array of new annotation objects. 94 | @param mapView An instance of MKMapView 95 | 96 | @discussion This method will remove only annotations that are on the map, but are not in the new array of annotations. Only new annotations will be added on the map. Annotations that are already on the map will not be updated. 97 | */ 98 | - (void)displayAnnotations:(NSArray *)annotations 99 | onMapView:(MKMapView *)mapView; 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /FBAnnotationClustering/FBQuadTreeNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // FBQuadTreeNode.m 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 05/01/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import "FBQuadTreeNode.h" 10 | 11 | @implementation FBQuadTreeNode 12 | 13 | - (id)init 14 | { 15 | self = [super init]; 16 | if (self) { 17 | self.count = 0; 18 | self.northEast = nil; 19 | self.northWest = nil; 20 | self.southEast = nil; 21 | self.southWest = nil; 22 | self.annotations = [[NSMutableArray alloc] initWithCapacity:kNodeCapacity]; 23 | } 24 | return self; 25 | } 26 | 27 | - (id)initWithBoundingBox:(FBBoundingBox)box 28 | { 29 | self = [self init]; 30 | if (self) { 31 | self.boundingBox = box; 32 | } 33 | return self; 34 | } 35 | 36 | - (BOOL)isLeaf 37 | { 38 | return self.northEast ? NO : YES; 39 | } 40 | 41 | - (void)subdivide 42 | { 43 | self.northEast = [[FBQuadTreeNode alloc] init]; 44 | self.northWest = [[FBQuadTreeNode alloc] init]; 45 | self.southEast = [[FBQuadTreeNode alloc] init]; 46 | self.southWest = [[FBQuadTreeNode alloc] init]; 47 | 48 | FBBoundingBox box = self.boundingBox; 49 | CGFloat xMid = (box.xf + box.x0) / 2.0; 50 | CGFloat yMid = (box.yf + box.y0) / 2.0; 51 | 52 | self.northEast.boundingBox = FBBoundingBoxMake(xMid, box.y0, box.xf, yMid); 53 | self.northWest.boundingBox = FBBoundingBoxMake(box.x0, box.y0, xMid, yMid); 54 | self.southEast.boundingBox = FBBoundingBoxMake(xMid, yMid, box.xf, box.yf); 55 | self.southWest.boundingBox = FBBoundingBoxMake(box.x0, yMid, xMid, box.yf); 56 | 57 | } 58 | 59 | #pragma mark - 60 | #pragma mark - Bounding box functions 61 | 62 | FBBoundingBox FBBoundingBoxMake(CGFloat x0, CGFloat y0, CGFloat xf, CGFloat yf) 63 | { 64 | FBBoundingBox box; 65 | box.x0 = x0; 66 | box.y0 = y0; 67 | box.xf = xf; 68 | box.yf = yf; 69 | return box; 70 | } 71 | 72 | FBBoundingBox FBBoundingBoxForMapRect(MKMapRect mapRect) 73 | { 74 | CLLocationCoordinate2D topLeft = MKCoordinateForMapPoint(mapRect.origin); 75 | CLLocationCoordinate2D botRight = MKCoordinateForMapPoint(MKMapPointMake(MKMapRectGetMaxX(mapRect), MKMapRectGetMaxY(mapRect))); 76 | 77 | CLLocationDegrees minLat = botRight.latitude; 78 | CLLocationDegrees maxLat = topLeft.latitude; 79 | 80 | CLLocationDegrees minLon = topLeft.longitude; 81 | CLLocationDegrees maxLon = botRight.longitude; 82 | 83 | return FBBoundingBoxMake(minLat, minLon, maxLat, maxLon); 84 | } 85 | 86 | MKMapRect FBMapRectForBoundingBox(FBBoundingBox boundingBox) 87 | { 88 | MKMapPoint topLeft = MKMapPointForCoordinate(CLLocationCoordinate2DMake(boundingBox.x0, boundingBox.y0)); 89 | MKMapPoint botRight = MKMapPointForCoordinate(CLLocationCoordinate2DMake(boundingBox.xf, boundingBox.yf)); 90 | 91 | return MKMapRectMake(topLeft.x, botRight.y, fabs(botRight.x - topLeft.x), fabs(botRight.y - topLeft.y)); 92 | } 93 | 94 | BOOL FBBoundingBoxContainsCoordinate(FBBoundingBox box, CLLocationCoordinate2D coordinate) 95 | { 96 | BOOL containsX = box.x0 <= coordinate.latitude && coordinate.latitude <= box.xf; 97 | BOOL containsY = box.y0 <= coordinate.longitude && coordinate.longitude <= box.yf; 98 | return containsX && containsY; 99 | } 100 | 101 | BOOL FBBoundingBoxIntersectsBoundingBox(FBBoundingBox box1, FBBoundingBox box2) 102 | { 103 | return (box1.x0 <= box2.xf && box1.xf >= box2.x0 && box1.y0 <= box2.yf && box1.yf >= box2.y0); 104 | } 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /FBAnnotationClustering/FBQuadTree.m: -------------------------------------------------------------------------------- 1 | // 2 | // FBQuadTree.m 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 05/01/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import "FBQuadTree.h" 10 | 11 | @implementation FBQuadTree 12 | 13 | - (id)init 14 | { 15 | self = [super init]; 16 | if (self) { 17 | self.rootNode = [[FBQuadTreeNode alloc] initWithBoundingBox:FBBoundingBoxForMapRect(MKMapRectWorld)]; 18 | } 19 | return self; 20 | } 21 | 22 | - (BOOL)insertAnnotation:(id)annotation 23 | { 24 | return [self insertAnnotation:annotation toNode:self.rootNode]; 25 | } 26 | 27 | - (BOOL)removeAnnotation:(id)annotation 28 | { 29 | return [self removeAnnotation:annotation fromNode:self.rootNode]; 30 | } 31 | 32 | - (BOOL)removeAnnotation:(id)annotation fromNode:(FBQuadTreeNode *)node 33 | { 34 | if (!FBBoundingBoxContainsCoordinate(node.boundingBox, [annotation coordinate])) { 35 | return NO; 36 | } 37 | 38 | if ([node.annotations containsObject:annotation]) { 39 | [node.annotations removeObject:annotation]; 40 | node.count--; 41 | return YES; 42 | } 43 | 44 | if ((node.northEast != nil) && [self removeAnnotation:annotation fromNode:node.northEast]) return YES; 45 | if ((node.northWest != nil) && [self removeAnnotation:annotation fromNode:node.northWest]) return YES; 46 | if ((node.southEast != nil) && [self removeAnnotation:annotation fromNode:node.southEast]) return YES; 47 | if ((node.southWest != nil) && [self removeAnnotation:annotation fromNode:node.southWest]) return YES; 48 | 49 | return NO; 50 | } 51 | 52 | 53 | - (BOOL)insertAnnotation:(id)annotation toNode:(FBQuadTreeNode *)node 54 | { 55 | if (!FBBoundingBoxContainsCoordinate(node.boundingBox, [annotation coordinate])) { 56 | return NO; 57 | } 58 | 59 | if (node.count < kNodeCapacity) { 60 | node.annotations[node.count++] = annotation; 61 | return YES; 62 | } 63 | 64 | if ([node isLeaf]) { 65 | [node subdivide]; 66 | } 67 | 68 | if ([self insertAnnotation:annotation toNode:node.northEast]) return YES; 69 | if ([self insertAnnotation:annotation toNode:node.northWest]) return YES; 70 | if ([self insertAnnotation:annotation toNode:node.southEast]) return YES; 71 | if ([self insertAnnotation:annotation toNode:node.southWest]) return YES; 72 | 73 | return NO; 74 | } 75 | 76 | - (void)enumerateAnnotationsInBox:(FBBoundingBox)box usingBlock:(void (^)(id))block 77 | { 78 | [self enumerateAnnotationsInBox:box withNode:self.rootNode usingBlock:block]; 79 | } 80 | 81 | - (void)enumerateAnnotationsUsingBlock:(void (^)(id))block 82 | { 83 | [self enumerateAnnotationsInBox:FBBoundingBoxForMapRect(MKMapRectWorld) withNode:self.rootNode usingBlock:block]; 84 | } 85 | 86 | - (void)enumerateAnnotationsInBox:(FBBoundingBox)box withNode:(FBQuadTreeNode*)node usingBlock:(void (^)(id))block 87 | { 88 | if (!FBBoundingBoxIntersectsBoundingBox(node.boundingBox, box)) { 89 | return; 90 | } 91 | 92 | NSArray *tempArray = [node.annotations copy]; 93 | 94 | for (id annotation in tempArray) { 95 | if (FBBoundingBoxContainsCoordinate(box, [annotation coordinate])) { 96 | block(annotation); 97 | } 98 | } 99 | 100 | if ([node isLeaf]) { 101 | return; 102 | } 103 | 104 | [self enumerateAnnotationsInBox:box withNode:node.northEast usingBlock:block]; 105 | [self enumerateAnnotationsInBox:box withNode:node.northWest usingBlock:block]; 106 | [self enumerateAnnotationsInBox:box withNode:node.southEast usingBlock:block]; 107 | [self enumerateAnnotationsInBox:box withNode:node.southWest usingBlock:block]; 108 | } 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FBAnnotationClustering 2 | 3 | [![Version](http://cocoapod-badges.herokuapp.com/v/FBAnnotationClustering/badge.png)](http://cocoadocs.org/docsets/FBAnnotationClustering) 4 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 5 | [![Platform](http://cocoapod-badges.herokuapp.com/p/FBAnnotationClustering/badge.png)](http://cocoadocs.org/docsets/FBAnnotationClustering) 6 | 7 | FBAnnotationClustering is **no longer maintained**. All issues and pull request will not be checked. 8 | 9 | FBAnnotationClustering is an iOS library for clustering map notifications in an easy and performant way. Check out the [blog post](https://www.infinum.co/the-capsized-eight/articles/a-blazingly-fast-open-source-algorithm-for-poi-clustering-on-ios) about it. 10 | 11 |

12 | FBAnnotationClustering example 13 |

14 | 15 | ## Usage 16 | 17 | Create your clustering manager (and initialize with annotations or add annotations later): 18 | 19 | self.clusteringManager = [[FBClusteringManager alloc] initWithAnnotations:arrayOfAnnotations]; 20 | 21 | Implement MKMapView delegate method `mapView:regionDidChangeAnimated:` to display annotations grouped in clusters on the map. An example of implementation: 22 | 23 | - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 24 | { 25 | [[NSOperationQueue new] addOperationWithBlock:^{ 26 | double scale = self.mapView.bounds.size.width / self.mapView.visibleMapRect.size.width; 27 | NSArray *annotations = [self.clusteringManager clusteredAnnotationsWithinMapRect:mapView.visibleMapRect withZoomScale:scale]; 28 | 29 | [self.clusteringManager displayAnnotations:annotations onMapView:mapView]; 30 | }]; 31 | } 32 | 33 | **Important:** Call the method `mapView:regionDidChangeAnimated:` whenever you want to refresh currently visible map rectangle by yourself (for example, if you added annotations to `clusteringManager`) 34 | 35 | All clusters will have `FBAnnotationCluster` class, so when MKMapView delegate methods are called, you can check if current annotation is cluster by checking its class. For example: 36 | 37 | - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation 38 | { 39 | if ([annotation isKindOfClass:[FBAnnotationCluster class]]) { 40 | FBAnnotationCluster *cluster = (FBAnnotationCluster *)annotation; 41 | NSLog(@"Annotation is cluster. Number of annotations in cluster: %lu", (unsigned long)cluster.annotations.count); 42 | } else { 43 | NSLog(@"Normal annotation.") 44 | } 45 | 46 | ... 47 | } 48 | 49 | To run the example project; clone the repo, and run `pod install` from the Example directory first. 50 | 51 | 52 | ## Requirements 53 | 54 | * iOS SDK 6 55 | * ARC 56 | 57 | ## Installation 58 | 59 | FBAnnotationClustering is available through [CocoaPods](http://cocoapods.org), to install 60 | it simply add the following line to your Podfile: 61 | 62 | pod "FBAnnotationClustering" 63 | 64 | If you don't like Cocapods, you can add all files from [FBAnnotationClustering](FBAnnotationClustering) directory to your project. 65 | 66 | ## TODO 67 | 68 | * replace `NSRecursiveLock` with GCD serial queue 69 | * `removeAnnotations:` method 70 | 71 | 72 | /** 73 | Remove array of annotations from current annotation collection. 74 | 75 | @param annotations Custom annotation objects. 76 | */ 77 | - (void)removeAnnotations:(NSArray *)annotations; 78 | 79 | 80 | ## Author 81 | 82 | Filip Beć, filip.bec@infinum.co 83 | 84 | ## Credits 85 | 86 | FBAnnotationClustering is based on a blog post written by [thoughtbot](http://robots.thoughtbot.com/how-to-handle-large-amounts-of-data-on-maps). 87 | 88 | Maintained and sponsored by 89 | [Infinum](http://www.infinum.co). 90 | 91 | 92 | 93 | ## License 94 | 95 | FBAnnotationClustering is available under the MIT license. See the LICENSE file for more info. 96 | 97 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | desc "Runs the specs [EMPTY]" 2 | task :spec do 3 | # Provide your own implementation 4 | end 5 | 6 | task :version do 7 | git_remotes = `git remote`.strip.split("\n") 8 | 9 | if git_remotes.count > 0 10 | puts "-- fetching version number from github" 11 | sh 'git fetch' 12 | 13 | remote_version = remote_spec_version 14 | end 15 | 16 | if remote_version.nil? 17 | puts "There is no current released version. You're about to release a new Pod." 18 | version = "0.0.1" 19 | else 20 | puts "The current released version of your pod is " + remote_spec_version.to_s() 21 | version = suggested_version_number 22 | end 23 | 24 | puts "Enter the version you want to release (" + version + ") " 25 | new_version_number = $stdin.gets.strip 26 | if new_version_number == "" 27 | new_version_number = version 28 | end 29 | 30 | replace_version_number(new_version_number) 31 | end 32 | 33 | desc "Release a new version of the Pod (append repo=name to push to a private spec repo)" 34 | task :release do 35 | # Allow override of spec repo name using `repo=private` after task name 36 | repo = ENV["repo"] || "master" 37 | 38 | puts "* Running version" 39 | sh "rake version" 40 | 41 | unless ENV['SKIP_CHECKS'] 42 | if `git symbolic-ref HEAD 2>/dev/null`.strip.split('/').last != 'master' 43 | $stderr.puts "[!] You need to be on the `master' branch in order to be able to do a release." 44 | exit 1 45 | end 46 | 47 | if `git tag`.strip.split("\n").include?(spec_version) 48 | $stderr.puts "[!] A tag for version `#{spec_version}' already exists. Change the version in the podspec" 49 | exit 1 50 | end 51 | 52 | puts "You are about to release `#{spec_version}`, is that correct? [y/n]" 53 | exit if $stdin.gets.strip.downcase != 'y' 54 | end 55 | 56 | puts "* Running specs" 57 | sh "rake spec" 58 | 59 | puts "* Linting the podspec" 60 | sh "pod lib lint" 61 | 62 | # Then release 63 | sh "git commit #{podspec_path} CHANGELOG.md -m 'Release #{spec_version}'" 64 | sh "git tag -a #{spec_version} -m 'Release #{spec_version}'" 65 | sh "git push origin master" 66 | sh "git push origin --tags" 67 | sh "pod push #{repo} #{podspec_path}" 68 | end 69 | 70 | # @return [Pod::Version] The version as reported by the Podspec. 71 | # 72 | def spec_version 73 | require 'cocoapods' 74 | spec = Pod::Specification.from_file(podspec_path) 75 | spec.version 76 | end 77 | 78 | # @return [Pod::Version] The version as reported by the Podspec from remote. 79 | # 80 | def remote_spec_version 81 | require 'cocoapods-core' 82 | 83 | if spec_file_exist_on_remote? 84 | remote_spec = eval(`git show origin/master:#{podspec_path}`) 85 | remote_spec.version 86 | else 87 | nil 88 | end 89 | end 90 | 91 | # @return [Bool] If the remote repository has a copy of the podpesc file or not. 92 | # 93 | def spec_file_exist_on_remote? 94 | test_condition = `if git rev-parse --verify --quiet origin/master:#{podspec_path} >/dev/null; 95 | then 96 | echo 'true' 97 | else 98 | echo 'false' 99 | fi` 100 | 101 | 'true' == test_condition.strip 102 | end 103 | 104 | # @return [String] The relative path of the Podspec. 105 | # 106 | def podspec_path 107 | podspecs = Dir.glob('*.podspec') 108 | if podspecs.count == 1 109 | podspecs.first 110 | else 111 | raise "Could not select a podspec" 112 | end 113 | end 114 | 115 | # @return [String] The suggested version number based on the local and remote version numbers. 116 | # 117 | def suggested_version_number 118 | if spec_version != remote_spec_version 119 | spec_version.to_s() 120 | else 121 | next_version(spec_version).to_s() 122 | end 123 | end 124 | 125 | # @param [Pod::Version] version 126 | # the version for which you need the next version 127 | # 128 | # @note It is computed by bumping the last component of the versino string by 1. 129 | # 130 | # @return [Pod::Version] The version that comes next after the version supplied. 131 | # 132 | def next_version(version) 133 | version_components = version.to_s().split("."); 134 | last = (version_components.last.to_i() + 1).to_s 135 | version_components[-1] = last 136 | Pod::Version.new(version_components.join(".")) 137 | end 138 | 139 | # @param [String] new_version_number 140 | # the new version number 141 | # 142 | # @note This methods replaces the version number in the podspec file with a new version number. 143 | # 144 | # @return void 145 | # 146 | def replace_version_number(new_version_number) 147 | text = File.read(podspec_path) 148 | text.gsub!(/(s.version( )*= ")#{spec_version}(")/, "\\1#{new_version_number}\\3") 149 | File.open(podspec_path, "w") { |file| file.puts text } 150 | end -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods/Pods-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | realpath() { 12 | DIRECTORY=$(cd "${1%/*}" && pwd) 13 | FILENAME="${1##*/}" 14 | echo "$DIRECTORY/$FILENAME" 15 | } 16 | 17 | install_resource() 18 | { 19 | case $1 in 20 | *.storyboard) 21 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 22 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 23 | ;; 24 | *.xib) 25 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 26 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 27 | ;; 28 | *.framework) 29 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 30 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 31 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 32 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 33 | ;; 34 | *.xcdatamodel) 35 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" 36 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" 37 | ;; 38 | *.xcdatamodeld) 39 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" 40 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" 41 | ;; 42 | *.xcmappingmodel) 43 | echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" 44 | xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" 45 | ;; 46 | *.xcassets) 47 | ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1") 48 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 49 | ;; 50 | /*) 51 | echo "$1" 52 | echo "$1" >> "$RESOURCES_TO_COPY" 53 | ;; 54 | *) 55 | echo "${PODS_ROOT}/$1" 56 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" 57 | ;; 58 | esac 59 | } 60 | 61 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 62 | if [[ "${ACTION}" == "install" ]]; then 63 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 64 | fi 65 | rm -f "$RESOURCES_TO_COPY" 66 | 67 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 68 | then 69 | case "${TARGETED_DEVICE_FAMILY}" in 70 | 1,2) 71 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 72 | ;; 73 | 1) 74 | TARGET_DEVICE_ARGS="--target-device iphone" 75 | ;; 76 | 2) 77 | TARGET_DEVICE_ARGS="--target-device ipad" 78 | ;; 79 | *) 80 | TARGET_DEVICE_ARGS="--target-device mac" 81 | ;; 82 | esac 83 | 84 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 85 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 86 | while read line; do 87 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 88 | XCASSET_FILES+=("$line") 89 | fi 90 | done <<<"$OTHER_XCASSETS" 91 | 92 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 93 | fi 94 | -------------------------------------------------------------------------------- /Example/Classes/Controllers/FBViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FBViewController.m 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 06/04/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import "FBViewController.h" 10 | #import "FBAnnotation.h" 11 | 12 | #define kNUMBER_OF_LOCATIONS 1000 13 | #define kFIRST_LOCATIONS_TO_REMOVE 50 14 | 15 | @interface FBViewController () 16 | 17 | @property (weak, nonatomic) IBOutlet MKMapView *mapView; 18 | @property (weak, nonatomic) IBOutlet UILabel *numberOfAnnotationsLabel; 19 | 20 | @property (nonatomic, assign) NSUInteger numberOfLocations; 21 | @property (nonatomic, strong) FBClusteringManager *clusteringManager; 22 | 23 | @end 24 | 25 | @implementation FBViewController 26 | 27 | - (void)viewDidLoad 28 | { 29 | [super viewDidLoad]; 30 | // Do any additional setup after loading the view, typically from a nib. 31 | 32 | NSMutableArray *array = [self randomLocationsWithCount:kNUMBER_OF_LOCATIONS]; 33 | self.numberOfLocations = kNUMBER_OF_LOCATIONS; 34 | [self updateLabelText]; 35 | 36 | // Create clustering manager 37 | self.clusteringManager = [[FBClusteringManager alloc] initWithAnnotations:array]; 38 | self.clusteringManager.delegate = self; 39 | 40 | self.mapView.centerCoordinate = CLLocationCoordinate2DMake(0, 0); 41 | [self mapView:self.mapView regionDidChangeAnimated:NO]; 42 | 43 | NSMutableArray *annotationsToRemove = [[NSMutableArray alloc] init]; 44 | for (int i=0; i)annotation 69 | { 70 | static NSString *const AnnotatioViewReuseID = @"AnnotatioViewReuseID"; 71 | 72 | MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotatioViewReuseID]; 73 | 74 | if (!annotationView) { 75 | annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotatioViewReuseID]; 76 | } 77 | 78 | // This is how you can check if annotation is a cluster 79 | if ([annotation isKindOfClass:[FBAnnotationCluster class]]) { 80 | FBAnnotationCluster *cluster = (FBAnnotationCluster *)annotation; 81 | cluster.title = [NSString stringWithFormat:@"%lu", (unsigned long)cluster.annotations.count]; 82 | 83 | annotationView.pinColor = MKPinAnnotationColorGreen; 84 | annotationView.canShowCallout = YES; 85 | } else { 86 | annotationView.pinColor = MKPinAnnotationColorRed; 87 | annotationView.canShowCallout = NO; 88 | } 89 | 90 | return annotationView; 91 | } 92 | 93 | #pragma mark - FBClusterManager delegate - optional 94 | 95 | - (CGFloat)cellSizeFactorForCoordinator:(FBClusteringManager *)coordinator 96 | { 97 | return 1.5; 98 | } 99 | 100 | #pragma mark - Add annotations button action handler 101 | 102 | - (IBAction)addNewAnnotations:(id)sender 103 | { 104 | NSMutableArray *array = [self randomLocationsWithCount:kNUMBER_OF_LOCATIONS]; 105 | [self.clusteringManager addAnnotations:array]; 106 | 107 | self.numberOfLocations += kNUMBER_OF_LOCATIONS; 108 | [self updateLabelText]; 109 | 110 | // Update annotations on the map 111 | [self mapView:self.mapView regionDidChangeAnimated:NO]; 112 | } 113 | 114 | #pragma mark - Utility 115 | 116 | - (NSMutableArray *)randomLocationsWithCount:(NSUInteger)count 117 | { 118 | NSMutableArray *array = [NSMutableArray array]; 119 | for (int i = 0; i < count; i++) { 120 | FBAnnotation *a = [[FBAnnotation alloc] init]; 121 | a.coordinate = CLLocationCoordinate2DMake(drand48() * 40 - 20, drand48() * 80 - 40); 122 | 123 | [array addObject:a]; 124 | } 125 | return array; 126 | } 127 | 128 | - (void)updateLabelText 129 | { 130 | self.numberOfAnnotationsLabel.text = [NSString stringWithFormat:@"Sum of all annotations: %lu", (unsigned long)self.numberOfLocations]; 131 | } 132 | 133 | @end 134 | -------------------------------------------------------------------------------- /Example/AnnotationClustering/Base.lproj/Main_iPad.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 34 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /Example/AnnotationClustering/Base.lproj/Main_iPhone.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 37 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /FBAnnotationClustering/FBClusteringManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // FBClusterManager.m 3 | // AnnotationClustering 4 | // 5 | // Created by Filip Bec on 05/01/14. 6 | // Copyright (c) 2014 Infinum Ltd. All rights reserved. 7 | // 8 | 9 | #import "FBClusteringManager.h" 10 | #import "FBQuadTree.h" 11 | 12 | static NSString * const kFBClusteringManagerLockName = @"co.infinum.clusteringLock"; 13 | 14 | #pragma mark - Utility functions 15 | 16 | NSInteger FBZoomScaleToZoomLevel(MKZoomScale scale) 17 | { 18 | double totalTilesAtMaxZoom = MKMapSizeWorld.width / 256.0; 19 | NSInteger zoomLevelAtMaxZoom = log2(totalTilesAtMaxZoom); 20 | NSInteger zoomLevel = MAX(0, zoomLevelAtMaxZoom + floor(log2f(scale) + 0.5)); 21 | 22 | return zoomLevel; 23 | } 24 | 25 | CGFloat FBCellSizeForZoomScale(MKZoomScale zoomScale) 26 | { 27 | NSInteger zoomLevel = FBZoomScaleToZoomLevel(zoomScale); 28 | 29 | switch (zoomLevel) { 30 | case 13: 31 | case 14: 32 | case 15: 33 | return 64; 34 | case 16: 35 | case 17: 36 | case 18: 37 | return 32; 38 | case 19: 39 | return 16; 40 | 41 | default: 42 | return 88; 43 | } 44 | } 45 | 46 | #pragma mark - FBClusteringManager 47 | 48 | @interface FBClusteringManager () 49 | 50 | @property (nonatomic, strong) FBQuadTree *tree; 51 | @property (nonatomic, strong) NSRecursiveLock *lock; 52 | 53 | @end 54 | 55 | 56 | @implementation FBClusteringManager 57 | 58 | - (id)init 59 | { 60 | return [self initWithAnnotations:nil]; 61 | } 62 | 63 | - (id)initWithAnnotations:(NSArray *)annotations 64 | { 65 | self = [super init]; 66 | if (self) { 67 | _lock = [NSRecursiveLock new]; 68 | [self addAnnotations:annotations]; 69 | } 70 | return self; 71 | } 72 | 73 | - (void)setAnnotations:(NSArray *)annotations 74 | { 75 | self.tree = nil; 76 | [self addAnnotations:annotations]; 77 | } 78 | 79 | - (void)addAnnotations:(NSArray *)annotations 80 | { 81 | if (!self.tree) { 82 | self.tree = [[FBQuadTree alloc] init]; 83 | } 84 | 85 | [self.lock lock]; 86 | for (id annotation in annotations) { 87 | [self.tree insertAnnotation:annotation]; 88 | } 89 | [self.lock unlock]; 90 | } 91 | 92 | - (void)removeAnnotations:(NSArray *)annotations 93 | { 94 | if (!self.tree) { 95 | return; 96 | } 97 | 98 | [self.lock lock]; 99 | for (id annotation in annotations) { 100 | [self.tree removeAnnotation:annotation]; 101 | } 102 | [self.lock unlock]; 103 | } 104 | 105 | - (NSArray *)clusteredAnnotationsWithinMapRect:(MKMapRect)rect withZoomScale:(double)zoomScale 106 | { 107 | return [self clusteredAnnotationsWithinMapRect:rect withZoomScale:zoomScale withFilter:nil]; 108 | } 109 | 110 | - (NSArray *)clusteredAnnotationsWithinMapRect:(MKMapRect)rect withZoomScale:(double)zoomScale withFilter:(BOOL (^)(id)) filter 111 | { 112 | double cellSize = FBCellSizeForZoomScale(zoomScale); 113 | if ([self.delegate respondsToSelector:@selector(cellSizeFactorForCoordinator:)]) { 114 | cellSize *= [self.delegate cellSizeFactorForCoordinator:self]; 115 | } 116 | double scaleFactor = zoomScale / cellSize; 117 | 118 | NSInteger minX = floor(MKMapRectGetMinX(rect) * scaleFactor); 119 | NSInteger maxX = floor(MKMapRectGetMaxX(rect) * scaleFactor); 120 | NSInteger minY = floor(MKMapRectGetMinY(rect) * scaleFactor); 121 | NSInteger maxY = floor(MKMapRectGetMaxY(rect) * scaleFactor); 122 | 123 | NSMutableArray *clusteredAnnotations = [[NSMutableArray alloc] init]; 124 | 125 | [self.lock lock]; 126 | for (NSInteger x = minX; x <= maxX; x++) { 127 | for (NSInteger y = minY; y <= maxY; y++) { 128 | MKMapRect mapRect = MKMapRectMake(x/scaleFactor, y/scaleFactor, 1.0/scaleFactor, 1.0/scaleFactor); 129 | FBBoundingBox mapBox = FBBoundingBoxForMapRect(mapRect); 130 | 131 | __block double totalLatitude = 0; 132 | __block double totalLongitude = 0; 133 | 134 | NSMutableArray *annotations = [[NSMutableArray alloc] init]; 135 | 136 | [self.tree enumerateAnnotationsInBox:mapBox usingBlock:^(id obj) { 137 | 138 | if(!filter || (filter(obj) == TRUE)) 139 | { 140 | totalLatitude += [obj coordinate].latitude; 141 | totalLongitude += [obj coordinate].longitude; 142 | [annotations addObject:obj]; 143 | } 144 | }]; 145 | 146 | NSInteger count = [annotations count]; 147 | if (count == 1) { 148 | [clusteredAnnotations addObjectsFromArray:annotations]; 149 | } 150 | 151 | if (count > 1) { 152 | CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(totalLatitude/count, totalLongitude/count); 153 | FBAnnotationCluster *cluster = [[FBAnnotationCluster alloc] init]; 154 | cluster.coordinate = coordinate; 155 | cluster.annotations = annotations; 156 | [clusteredAnnotations addObject:cluster]; 157 | } 158 | } 159 | } 160 | [self.lock unlock]; 161 | 162 | return [NSArray arrayWithArray:clusteredAnnotations]; 163 | } 164 | 165 | - (NSArray *)allAnnotations 166 | { 167 | NSMutableArray *annotations = [[NSMutableArray alloc] init]; 168 | 169 | [self.lock lock]; 170 | [self.tree enumerateAnnotationsUsingBlock:^(id obj) { 171 | [annotations addObject:obj]; 172 | }]; 173 | [self.lock unlock]; 174 | 175 | return annotations; 176 | } 177 | 178 | - (void)displayAnnotations:(NSArray *)annotations onMapView:(MKMapView *)mapView 179 | { 180 | NSMutableSet *before = [NSMutableSet setWithArray:mapView.annotations]; 181 | MKUserLocation *userLocation = [mapView userLocation]; 182 | if (userLocation) { 183 | [before removeObject:userLocation]; 184 | } 185 | NSSet *after = [NSSet setWithArray:annotations]; 186 | 187 | NSMutableSet *toKeep = [NSMutableSet setWithSet:before]; 188 | [toKeep intersectSet:after]; 189 | 190 | NSMutableSet *toAdd = [NSMutableSet setWithSet:after]; 191 | [toAdd minusSet:toKeep]; 192 | 193 | NSMutableSet *toRemove = [NSMutableSet setWithSet:before]; 194 | [toRemove minusSet:after]; 195 | 196 | [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 197 | [mapView addAnnotations:[toAdd allObjects]]; 198 | [mapView removeAnnotations:[toRemove allObjects]]; 199 | }]; 200 | } 201 | 202 | @end 203 | -------------------------------------------------------------------------------- /FBAnnotationClustering.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | E1E352F01C762CD100D2DE8A /* FBAnnotationCluster.h in Headers */ = {isa = PBXBuildFile; fileRef = E1E352E61C762CD100D2DE8A /* FBAnnotationCluster.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | E1E352F11C762CD100D2DE8A /* FBAnnotationCluster.m in Sources */ = {isa = PBXBuildFile; fileRef = E1E352E71C762CD100D2DE8A /* FBAnnotationCluster.m */; }; 12 | E1E352F21C762CD100D2DE8A /* FBAnnotationClustering.h in Headers */ = {isa = PBXBuildFile; fileRef = E1E352E81C762CD100D2DE8A /* FBAnnotationClustering.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | E1E352F31C762CD100D2DE8A /* FBClusteringManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E1E352E91C762CD100D2DE8A /* FBClusteringManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 14 | E1E352F41C762CD100D2DE8A /* FBClusteringManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E1E352EA1C762CD100D2DE8A /* FBClusteringManager.m */; }; 15 | E1E352F51C762CD100D2DE8A /* FBQuadTree.h in Headers */ = {isa = PBXBuildFile; fileRef = E1E352EB1C762CD100D2DE8A /* FBQuadTree.h */; settings = {ATTRIBUTES = (Public, ); }; }; 16 | E1E352F61C762CD100D2DE8A /* FBQuadTree.m in Sources */ = {isa = PBXBuildFile; fileRef = E1E352EC1C762CD100D2DE8A /* FBQuadTree.m */; }; 17 | E1E352F71C762CD100D2DE8A /* FBQuadTreeNode.h in Headers */ = {isa = PBXBuildFile; fileRef = E1E352ED1C762CD100D2DE8A /* FBQuadTreeNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 18 | E1E352F81C762CD100D2DE8A /* FBQuadTreeNode.m in Sources */ = {isa = PBXBuildFile; fileRef = E1E352EE1C762CD100D2DE8A /* FBQuadTreeNode.m */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | E1E352D91C762B4100D2DE8A /* FBAnnotationClustering.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBAnnotationClustering.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | E1E352E61C762CD100D2DE8A /* FBAnnotationCluster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBAnnotationCluster.h; sourceTree = ""; }; 24 | E1E352E71C762CD100D2DE8A /* FBAnnotationCluster.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBAnnotationCluster.m; sourceTree = ""; }; 25 | E1E352E81C762CD100D2DE8A /* FBAnnotationClustering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBAnnotationClustering.h; sourceTree = ""; }; 26 | E1E352E91C762CD100D2DE8A /* FBClusteringManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBClusteringManager.h; sourceTree = ""; }; 27 | E1E352EA1C762CD100D2DE8A /* FBClusteringManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBClusteringManager.m; sourceTree = ""; }; 28 | E1E352EB1C762CD100D2DE8A /* FBQuadTree.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBQuadTree.h; sourceTree = ""; }; 29 | E1E352EC1C762CD100D2DE8A /* FBQuadTree.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBQuadTree.m; sourceTree = ""; }; 30 | E1E352ED1C762CD100D2DE8A /* FBQuadTreeNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBQuadTreeNode.h; sourceTree = ""; }; 31 | E1E352EE1C762CD100D2DE8A /* FBQuadTreeNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBQuadTreeNode.m; sourceTree = ""; }; 32 | E1E352EF1C762CD100D2DE8A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | /* End PBXFileReference section */ 34 | 35 | /* Begin PBXFrameworksBuildPhase section */ 36 | E1E352D51C762B4100D2DE8A /* Frameworks */ = { 37 | isa = PBXFrameworksBuildPhase; 38 | buildActionMask = 2147483647; 39 | files = ( 40 | ); 41 | runOnlyForDeploymentPostprocessing = 0; 42 | }; 43 | /* End PBXFrameworksBuildPhase section */ 44 | 45 | /* Begin PBXGroup section */ 46 | E1E352CF1C762B4100D2DE8A = { 47 | isa = PBXGroup; 48 | children = ( 49 | E1E352DB1C762B4100D2DE8A /* FBAnnotationClustering */, 50 | E1E352DA1C762B4100D2DE8A /* Products */, 51 | ); 52 | sourceTree = ""; 53 | }; 54 | E1E352DA1C762B4100D2DE8A /* Products */ = { 55 | isa = PBXGroup; 56 | children = ( 57 | E1E352D91C762B4100D2DE8A /* FBAnnotationClustering.framework */, 58 | ); 59 | name = Products; 60 | sourceTree = ""; 61 | }; 62 | E1E352DB1C762B4100D2DE8A /* FBAnnotationClustering */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | E1E352E61C762CD100D2DE8A /* FBAnnotationCluster.h */, 66 | E1E352E71C762CD100D2DE8A /* FBAnnotationCluster.m */, 67 | E1E352E81C762CD100D2DE8A /* FBAnnotationClustering.h */, 68 | E1E352E91C762CD100D2DE8A /* FBClusteringManager.h */, 69 | E1E352EA1C762CD100D2DE8A /* FBClusteringManager.m */, 70 | E1E352EB1C762CD100D2DE8A /* FBQuadTree.h */, 71 | E1E352EC1C762CD100D2DE8A /* FBQuadTree.m */, 72 | E1E352ED1C762CD100D2DE8A /* FBQuadTreeNode.h */, 73 | E1E352EE1C762CD100D2DE8A /* FBQuadTreeNode.m */, 74 | E1E352EF1C762CD100D2DE8A /* Info.plist */, 75 | ); 76 | path = FBAnnotationClustering; 77 | sourceTree = ""; 78 | }; 79 | /* End PBXGroup section */ 80 | 81 | /* Begin PBXHeadersBuildPhase section */ 82 | E1E352D61C762B4100D2DE8A /* Headers */ = { 83 | isa = PBXHeadersBuildPhase; 84 | buildActionMask = 2147483647; 85 | files = ( 86 | E1E352F31C762CD100D2DE8A /* FBClusteringManager.h in Headers */, 87 | E1E352F21C762CD100D2DE8A /* FBAnnotationClustering.h in Headers */, 88 | E1E352F51C762CD100D2DE8A /* FBQuadTree.h in Headers */, 89 | E1E352F01C762CD100D2DE8A /* FBAnnotationCluster.h in Headers */, 90 | E1E352F71C762CD100D2DE8A /* FBQuadTreeNode.h in Headers */, 91 | ); 92 | runOnlyForDeploymentPostprocessing = 0; 93 | }; 94 | /* End PBXHeadersBuildPhase section */ 95 | 96 | /* Begin PBXNativeTarget section */ 97 | E1E352D81C762B4100D2DE8A /* FBAnnotationClustering */ = { 98 | isa = PBXNativeTarget; 99 | buildConfigurationList = E1E352E11C762B4100D2DE8A /* Build configuration list for PBXNativeTarget "FBAnnotationClustering" */; 100 | buildPhases = ( 101 | E1E352D41C762B4100D2DE8A /* Sources */, 102 | E1E352D51C762B4100D2DE8A /* Frameworks */, 103 | E1E352D61C762B4100D2DE8A /* Headers */, 104 | E1E352D71C762B4100D2DE8A /* Resources */, 105 | ); 106 | buildRules = ( 107 | ); 108 | dependencies = ( 109 | ); 110 | name = FBAnnotationClustering; 111 | productName = FBAnnotationClustering; 112 | productReference = E1E352D91C762B4100D2DE8A /* FBAnnotationClustering.framework */; 113 | productType = "com.apple.product-type.framework"; 114 | }; 115 | /* End PBXNativeTarget section */ 116 | 117 | /* Begin PBXProject section */ 118 | E1E352D01C762B4100D2DE8A /* Project object */ = { 119 | isa = PBXProject; 120 | attributes = { 121 | LastUpgradeCheck = 0720; 122 | ORGANIZATIONNAME = "Infinum Ltd."; 123 | TargetAttributes = { 124 | E1E352D81C762B4100D2DE8A = { 125 | CreatedOnToolsVersion = 7.2.1; 126 | }; 127 | }; 128 | }; 129 | buildConfigurationList = E1E352D31C762B4100D2DE8A /* Build configuration list for PBXProject "FBAnnotationClustering" */; 130 | compatibilityVersion = "Xcode 3.2"; 131 | developmentRegion = English; 132 | hasScannedForEncodings = 0; 133 | knownRegions = ( 134 | en, 135 | ); 136 | mainGroup = E1E352CF1C762B4100D2DE8A; 137 | productRefGroup = E1E352DA1C762B4100D2DE8A /* Products */; 138 | projectDirPath = ""; 139 | projectRoot = ""; 140 | targets = ( 141 | E1E352D81C762B4100D2DE8A /* FBAnnotationClustering */, 142 | ); 143 | }; 144 | /* End PBXProject section */ 145 | 146 | /* Begin PBXResourcesBuildPhase section */ 147 | E1E352D71C762B4100D2DE8A /* Resources */ = { 148 | isa = PBXResourcesBuildPhase; 149 | buildActionMask = 2147483647; 150 | files = ( 151 | ); 152 | runOnlyForDeploymentPostprocessing = 0; 153 | }; 154 | /* End PBXResourcesBuildPhase section */ 155 | 156 | /* Begin PBXSourcesBuildPhase section */ 157 | E1E352D41C762B4100D2DE8A /* Sources */ = { 158 | isa = PBXSourcesBuildPhase; 159 | buildActionMask = 2147483647; 160 | files = ( 161 | E1E352F81C762CD100D2DE8A /* FBQuadTreeNode.m in Sources */, 162 | E1E352F11C762CD100D2DE8A /* FBAnnotationCluster.m in Sources */, 163 | E1E352F61C762CD100D2DE8A /* FBQuadTree.m in Sources */, 164 | E1E352F41C762CD100D2DE8A /* FBClusteringManager.m in Sources */, 165 | ); 166 | runOnlyForDeploymentPostprocessing = 0; 167 | }; 168 | /* End PBXSourcesBuildPhase section */ 169 | 170 | /* Begin XCBuildConfiguration section */ 171 | E1E352DF1C762B4100D2DE8A /* Debug */ = { 172 | isa = XCBuildConfiguration; 173 | buildSettings = { 174 | ALWAYS_SEARCH_USER_PATHS = NO; 175 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 176 | CLANG_CXX_LIBRARY = "libc++"; 177 | CLANG_ENABLE_MODULES = YES; 178 | CLANG_ENABLE_OBJC_ARC = YES; 179 | CLANG_WARN_BOOL_CONVERSION = YES; 180 | CLANG_WARN_CONSTANT_CONVERSION = YES; 181 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 182 | CLANG_WARN_EMPTY_BODY = YES; 183 | CLANG_WARN_ENUM_CONVERSION = YES; 184 | CLANG_WARN_INT_CONVERSION = YES; 185 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 186 | CLANG_WARN_UNREACHABLE_CODE = YES; 187 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 188 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 189 | COPY_PHASE_STRIP = NO; 190 | CURRENT_PROJECT_VERSION = 1; 191 | DEBUG_INFORMATION_FORMAT = dwarf; 192 | ENABLE_STRICT_OBJC_MSGSEND = YES; 193 | ENABLE_TESTABILITY = YES; 194 | GCC_C_LANGUAGE_STANDARD = gnu99; 195 | GCC_DYNAMIC_NO_PIC = NO; 196 | GCC_NO_COMMON_BLOCKS = YES; 197 | GCC_OPTIMIZATION_LEVEL = 0; 198 | GCC_PREPROCESSOR_DEFINITIONS = ( 199 | "DEBUG=1", 200 | "$(inherited)", 201 | ); 202 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 203 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 204 | GCC_WARN_UNDECLARED_SELECTOR = YES; 205 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 206 | GCC_WARN_UNUSED_FUNCTION = YES; 207 | GCC_WARN_UNUSED_VARIABLE = YES; 208 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 209 | MTL_ENABLE_DEBUG_INFO = YES; 210 | ONLY_ACTIVE_ARCH = YES; 211 | SDKROOT = iphoneos; 212 | TARGETED_DEVICE_FAMILY = "1,2"; 213 | VERSIONING_SYSTEM = "apple-generic"; 214 | VERSION_INFO_PREFIX = ""; 215 | }; 216 | name = Debug; 217 | }; 218 | E1E352E01C762B4100D2DE8A /* Release */ = { 219 | isa = XCBuildConfiguration; 220 | buildSettings = { 221 | ALWAYS_SEARCH_USER_PATHS = NO; 222 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 223 | CLANG_CXX_LIBRARY = "libc++"; 224 | CLANG_ENABLE_MODULES = YES; 225 | CLANG_ENABLE_OBJC_ARC = YES; 226 | CLANG_WARN_BOOL_CONVERSION = YES; 227 | CLANG_WARN_CONSTANT_CONVERSION = YES; 228 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 229 | CLANG_WARN_EMPTY_BODY = YES; 230 | CLANG_WARN_ENUM_CONVERSION = YES; 231 | CLANG_WARN_INT_CONVERSION = YES; 232 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 233 | CLANG_WARN_UNREACHABLE_CODE = YES; 234 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 235 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 236 | COPY_PHASE_STRIP = NO; 237 | CURRENT_PROJECT_VERSION = 1; 238 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 239 | ENABLE_NS_ASSERTIONS = NO; 240 | ENABLE_STRICT_OBJC_MSGSEND = YES; 241 | GCC_C_LANGUAGE_STANDARD = gnu99; 242 | GCC_NO_COMMON_BLOCKS = YES; 243 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 244 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 245 | GCC_WARN_UNDECLARED_SELECTOR = YES; 246 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 247 | GCC_WARN_UNUSED_FUNCTION = YES; 248 | GCC_WARN_UNUSED_VARIABLE = YES; 249 | IPHONEOS_DEPLOYMENT_TARGET = 9.2; 250 | MTL_ENABLE_DEBUG_INFO = NO; 251 | SDKROOT = iphoneos; 252 | TARGETED_DEVICE_FAMILY = "1,2"; 253 | VALIDATE_PRODUCT = YES; 254 | VERSIONING_SYSTEM = "apple-generic"; 255 | VERSION_INFO_PREFIX = ""; 256 | }; 257 | name = Release; 258 | }; 259 | E1E352E21C762B4100D2DE8A /* Debug */ = { 260 | isa = XCBuildConfiguration; 261 | buildSettings = { 262 | DEFINES_MODULE = YES; 263 | DYLIB_COMPATIBILITY_VERSION = 1; 264 | DYLIB_CURRENT_VERSION = 1; 265 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 266 | INFOPLIST_FILE = FBAnnotationClustering/Info.plist; 267 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 268 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 269 | PRODUCT_BUNDLE_IDENTIFIER = com.infinum.FBAnnotationClustering; 270 | PRODUCT_NAME = "$(TARGET_NAME)"; 271 | SKIP_INSTALL = YES; 272 | }; 273 | name = Debug; 274 | }; 275 | E1E352E31C762B4100D2DE8A /* Release */ = { 276 | isa = XCBuildConfiguration; 277 | buildSettings = { 278 | DEFINES_MODULE = YES; 279 | DYLIB_COMPATIBILITY_VERSION = 1; 280 | DYLIB_CURRENT_VERSION = 1; 281 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 282 | INFOPLIST_FILE = FBAnnotationClustering/Info.plist; 283 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 284 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 285 | PRODUCT_BUNDLE_IDENTIFIER = com.infinum.FBAnnotationClustering; 286 | PRODUCT_NAME = "$(TARGET_NAME)"; 287 | SKIP_INSTALL = YES; 288 | }; 289 | name = Release; 290 | }; 291 | /* End XCBuildConfiguration section */ 292 | 293 | /* Begin XCConfigurationList section */ 294 | E1E352D31C762B4100D2DE8A /* Build configuration list for PBXProject "FBAnnotationClustering" */ = { 295 | isa = XCConfigurationList; 296 | buildConfigurations = ( 297 | E1E352DF1C762B4100D2DE8A /* Debug */, 298 | E1E352E01C762B4100D2DE8A /* Release */, 299 | ); 300 | defaultConfigurationIsVisible = 0; 301 | defaultConfigurationName = Release; 302 | }; 303 | E1E352E11C762B4100D2DE8A /* Build configuration list for PBXNativeTarget "FBAnnotationClustering" */ = { 304 | isa = XCConfigurationList; 305 | buildConfigurations = ( 306 | E1E352E21C762B4100D2DE8A /* Debug */, 307 | E1E352E31C762B4100D2DE8A /* Release */, 308 | ); 309 | defaultConfigurationIsVisible = 0; 310 | defaultConfigurationName = Release; 311 | }; 312 | /* End XCConfigurationList section */ 313 | }; 314 | rootObject = E1E352D01C762B4100D2DE8A /* Project object */; 315 | } 316 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1F2755EE6457F3ABCB05526C /* FBAnnotationCluster.h in Headers */ = {isa = PBXBuildFile; fileRef = D10B19FA16E0F96B32694B37 /* FBAnnotationCluster.h */; }; 11 | 230111A9AC22CD3C7169D183 /* FBAnnotationCluster.m in Sources */ = {isa = PBXBuildFile; fileRef = D63F24F5273457602FBA67EA /* FBAnnotationCluster.m */; }; 12 | 2E629529E83423A22A419DB8 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FEF0D4C0F3DF3855FCF0BA1B /* Foundation.framework */; }; 13 | 47BD55B975CAFF97A70BE51F /* FBAnnotationClustering.h in Headers */ = {isa = PBXBuildFile; fileRef = 28E85C02195308E602F0DDBE /* FBAnnotationClustering.h */; }; 14 | 5FDE8333E8C10B25209A11D8 /* FBQuadTreeNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3663C14A8064333943C1A8B0 /* FBQuadTreeNode.h */; }; 15 | 6413CDC32F01E1F63E6AD825 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE902CCBD73FB7E4B787DBAE /* MapKit.framework */; }; 16 | 6E348167BE41ACB4E22CEB92 /* Pods-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 538D2468806BBCF27C2568BA /* Pods-dummy.m */; }; 17 | 83C8E264AE73C0EF54A8E85C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FEF0D4C0F3DF3855FCF0BA1B /* Foundation.framework */; }; 18 | 971732DFA55044200E897E38 /* Pods-FBAnnotationClustering-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C281F7F10CDEB5AADDD703AD /* Pods-FBAnnotationClustering-dummy.m */; }; 19 | B3800966EAF83DC52996D642 /* FBClusteringManager.h in Headers */ = {isa = PBXBuildFile; fileRef = CEEB84049BA1AE40C0D26EC2 /* FBClusteringManager.h */; }; 20 | BE1A6F2FF38010DFD82F9120 /* FBClusteringManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8402DB24A4D2D1CAC3759C6D /* FBClusteringManager.m */; }; 21 | C314623E58DEE8CBE26B7337 /* FBQuadTree.h in Headers */ = {isa = PBXBuildFile; fileRef = FD66FE75C103B042C69B25C5 /* FBQuadTree.h */; }; 22 | C8A58CB4C4D052E5C9EC745F /* FBQuadTree.m in Sources */ = {isa = PBXBuildFile; fileRef = 940D4CA0C8962D6E3E428650 /* FBQuadTree.m */; }; 23 | F8439367A557D44B5B7C89BC /* FBQuadTreeNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 71B51B577AFD828E75AFD276 /* FBQuadTreeNode.m */; }; 24 | FC7C615BBCA809B9C1059046 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 85856AC116E120434E928E34 /* CoreLocation.framework */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXContainerItemProxy section */ 28 | 40C75EFF072D1CADA1C79FAB /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = 994E7505722C01E294FB84AE /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = 656299E91232636B85E5E89D; 33 | remoteInfo = "Pods-FBAnnotationClustering"; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | 05E0F314E1D39CF8A4D54515 /* Pods-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-resources.sh"; sourceTree = ""; }; 39 | 233A0567F9A2A80CE1C275F8 /* Pods-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-acknowledgements.markdown"; sourceTree = ""; }; 40 | 28E85C02195308E602F0DDBE /* FBAnnotationClustering.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = FBAnnotationClustering.h; sourceTree = ""; }; 41 | 3663C14A8064333943C1A8B0 /* FBQuadTreeNode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = FBQuadTreeNode.h; sourceTree = ""; }; 42 | 39E2421312B5DE4017223A40 /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 43 | 46A44E2DA6A79149024713A5 /* Pods-FBAnnotationClustering.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-FBAnnotationClustering.xcconfig"; sourceTree = ""; }; 44 | 538D2468806BBCF27C2568BA /* Pods-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-dummy.m"; sourceTree = ""; }; 45 | 68E3E6C81C04657D6EA37223 /* Pods-FBAnnotationClustering-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-FBAnnotationClustering-Private.xcconfig"; sourceTree = ""; }; 46 | 71B51B577AFD828E75AFD276 /* FBQuadTreeNode.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = FBQuadTreeNode.m; sourceTree = ""; }; 47 | 8402DB24A4D2D1CAC3759C6D /* FBClusteringManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = FBClusteringManager.m; sourceTree = ""; }; 48 | 85856AC116E120434E928E34 /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/System/Library/Frameworks/CoreLocation.framework; sourceTree = DEVELOPER_DIR; }; 49 | 89E6BED1730D9A6A051DC7C3 /* Pods-environment.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-environment.h"; sourceTree = ""; }; 50 | 940D4CA0C8962D6E3E428650 /* FBQuadTree.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = FBQuadTree.m; sourceTree = ""; }; 51 | 9E10339F9D3F3EA5F5920902 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Pods.release.xcconfig; sourceTree = ""; }; 52 | C17768AF84A171BC9BBE6592 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | C281F7F10CDEB5AADDD703AD /* Pods-FBAnnotationClustering-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-FBAnnotationClustering-dummy.m"; sourceTree = ""; }; 54 | C512DDE43244CF21726CE691 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Pods.debug.xcconfig; sourceTree = ""; }; 55 | CE902CCBD73FB7E4B787DBAE /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/System/Library/Frameworks/MapKit.framework; sourceTree = DEVELOPER_DIR; }; 56 | CEEB84049BA1AE40C0D26EC2 /* FBClusteringManager.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = FBClusteringManager.h; sourceTree = ""; }; 57 | D10B19FA16E0F96B32694B37 /* FBAnnotationCluster.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = FBAnnotationCluster.h; sourceTree = ""; }; 58 | D63F24F5273457602FBA67EA /* FBAnnotationCluster.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = FBAnnotationCluster.m; sourceTree = ""; }; 59 | DB080E6A5CAA3E293DF10FE0 /* libPods-FBAnnotationClustering.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-FBAnnotationClustering.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 60 | E1DEEBEDE884C8FC9BC28362 /* Pods-FBAnnotationClustering-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-FBAnnotationClustering-prefix.pch"; sourceTree = ""; }; 61 | FB08F660751CB949061CC00F /* Pods-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-acknowledgements.plist"; sourceTree = ""; }; 62 | FD66FE75C103B042C69B25C5 /* FBQuadTree.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = FBQuadTree.h; sourceTree = ""; }; 63 | FEF0D4C0F3DF3855FCF0BA1B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 64 | /* End PBXFileReference section */ 65 | 66 | /* Begin PBXFrameworksBuildPhase section */ 67 | 3C923BC5411AF1FA98C39387 /* Frameworks */ = { 68 | isa = PBXFrameworksBuildPhase; 69 | buildActionMask = 2147483647; 70 | files = ( 71 | 2E629529E83423A22A419DB8 /* Foundation.framework in Frameworks */, 72 | ); 73 | runOnlyForDeploymentPostprocessing = 0; 74 | }; 75 | 5CFDCF00CCB425D8050DD061 /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | FC7C615BBCA809B9C1059046 /* CoreLocation.framework in Frameworks */, 80 | 83C8E264AE73C0EF54A8E85C /* Foundation.framework in Frameworks */, 81 | 6413CDC32F01E1F63E6AD825 /* MapKit.framework in Frameworks */, 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | /* End PBXFrameworksBuildPhase section */ 86 | 87 | /* Begin PBXGroup section */ 88 | 0F22455307228A0B3BE7B67D /* Development Pods */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 4E3AFF7CF44A790518C829FC /* FBAnnotationClustering */, 92 | ); 93 | name = "Development Pods"; 94 | sourceTree = ""; 95 | }; 96 | 1AE4433C896E3F972A23989F /* Frameworks */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | 2EEFC2FEDA0FC8B7461D25C0 /* iOS */, 100 | ); 101 | name = Frameworks; 102 | sourceTree = ""; 103 | }; 104 | 243E70DC26441BABA422374B /* Pods */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 233A0567F9A2A80CE1C275F8 /* Pods-acknowledgements.markdown */, 108 | FB08F660751CB949061CC00F /* Pods-acknowledgements.plist */, 109 | 538D2468806BBCF27C2568BA /* Pods-dummy.m */, 110 | 89E6BED1730D9A6A051DC7C3 /* Pods-environment.h */, 111 | 05E0F314E1D39CF8A4D54515 /* Pods-resources.sh */, 112 | C512DDE43244CF21726CE691 /* Pods.debug.xcconfig */, 113 | 9E10339F9D3F3EA5F5920902 /* Pods.release.xcconfig */, 114 | ); 115 | name = Pods; 116 | path = "Target Support Files/Pods"; 117 | sourceTree = ""; 118 | }; 119 | 2EEFC2FEDA0FC8B7461D25C0 /* iOS */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | 85856AC116E120434E928E34 /* CoreLocation.framework */, 123 | FEF0D4C0F3DF3855FCF0BA1B /* Foundation.framework */, 124 | CE902CCBD73FB7E4B787DBAE /* MapKit.framework */, 125 | ); 126 | name = iOS; 127 | sourceTree = ""; 128 | }; 129 | 4E3AFF7CF44A790518C829FC /* FBAnnotationClustering */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | AD00C45F9C301B6AFBCA5CBC /* FBAnnotationClustering */, 133 | 8E03A97F6E7996B5399F47F8 /* Support Files */, 134 | ); 135 | name = FBAnnotationClustering; 136 | path = ../..; 137 | sourceTree = ""; 138 | }; 139 | 553D668234A90597C62B331A /* Targets Support Files */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | 243E70DC26441BABA422374B /* Pods */, 143 | ); 144 | name = "Targets Support Files"; 145 | sourceTree = ""; 146 | }; 147 | 8E03A97F6E7996B5399F47F8 /* Support Files */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 46A44E2DA6A79149024713A5 /* Pods-FBAnnotationClustering.xcconfig */, 151 | 68E3E6C81C04657D6EA37223 /* Pods-FBAnnotationClustering-Private.xcconfig */, 152 | C281F7F10CDEB5AADDD703AD /* Pods-FBAnnotationClustering-dummy.m */, 153 | E1DEEBEDE884C8FC9BC28362 /* Pods-FBAnnotationClustering-prefix.pch */, 154 | ); 155 | name = "Support Files"; 156 | path = "Example/Pods/Target Support Files/Pods-FBAnnotationClustering"; 157 | sourceTree = ""; 158 | }; 159 | AD00C45F9C301B6AFBCA5CBC /* FBAnnotationClustering */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | D10B19FA16E0F96B32694B37 /* FBAnnotationCluster.h */, 163 | D63F24F5273457602FBA67EA /* FBAnnotationCluster.m */, 164 | 28E85C02195308E602F0DDBE /* FBAnnotationClustering.h */, 165 | CEEB84049BA1AE40C0D26EC2 /* FBClusteringManager.h */, 166 | 8402DB24A4D2D1CAC3759C6D /* FBClusteringManager.m */, 167 | FD66FE75C103B042C69B25C5 /* FBQuadTree.h */, 168 | 940D4CA0C8962D6E3E428650 /* FBQuadTree.m */, 169 | 3663C14A8064333943C1A8B0 /* FBQuadTreeNode.h */, 170 | 71B51B577AFD828E75AFD276 /* FBQuadTreeNode.m */, 171 | ); 172 | path = FBAnnotationClustering; 173 | sourceTree = ""; 174 | }; 175 | CA8FEBA88188E98539D76831 /* Products */ = { 176 | isa = PBXGroup; 177 | children = ( 178 | C17768AF84A171BC9BBE6592 /* libPods.a */, 179 | DB080E6A5CAA3E293DF10FE0 /* libPods-FBAnnotationClustering.a */, 180 | ); 181 | name = Products; 182 | sourceTree = ""; 183 | }; 184 | F4443EF86D567598B474A832 = { 185 | isa = PBXGroup; 186 | children = ( 187 | 39E2421312B5DE4017223A40 /* Podfile */, 188 | 0F22455307228A0B3BE7B67D /* Development Pods */, 189 | 1AE4433C896E3F972A23989F /* Frameworks */, 190 | CA8FEBA88188E98539D76831 /* Products */, 191 | 553D668234A90597C62B331A /* Targets Support Files */, 192 | ); 193 | sourceTree = ""; 194 | }; 195 | /* End PBXGroup section */ 196 | 197 | /* Begin PBXHeadersBuildPhase section */ 198 | AF2B3536EDF12302BDFFB67C /* Headers */ = { 199 | isa = PBXHeadersBuildPhase; 200 | buildActionMask = 2147483647; 201 | files = ( 202 | 1F2755EE6457F3ABCB05526C /* FBAnnotationCluster.h in Headers */, 203 | 47BD55B975CAFF97A70BE51F /* FBAnnotationClustering.h in Headers */, 204 | B3800966EAF83DC52996D642 /* FBClusteringManager.h in Headers */, 205 | C314623E58DEE8CBE26B7337 /* FBQuadTree.h in Headers */, 206 | 5FDE8333E8C10B25209A11D8 /* FBQuadTreeNode.h in Headers */, 207 | ); 208 | runOnlyForDeploymentPostprocessing = 0; 209 | }; 210 | /* End PBXHeadersBuildPhase section */ 211 | 212 | /* Begin PBXNativeTarget section */ 213 | 3370D7F355672284AE2E5DEB /* Pods */ = { 214 | isa = PBXNativeTarget; 215 | buildConfigurationList = 9BE4CFF2F35C88C74F279528 /* Build configuration list for PBXNativeTarget "Pods" */; 216 | buildPhases = ( 217 | 9F326E7F478457E1185BE048 /* Sources */, 218 | 3C923BC5411AF1FA98C39387 /* Frameworks */, 219 | ); 220 | buildRules = ( 221 | ); 222 | dependencies = ( 223 | 0019CB04166AB4429441080A /* PBXTargetDependency */, 224 | ); 225 | name = Pods; 226 | productName = Pods; 227 | productReference = C17768AF84A171BC9BBE6592 /* libPods.a */; 228 | productType = "com.apple.product-type.library.static"; 229 | }; 230 | 656299E91232636B85E5E89D /* Pods-FBAnnotationClustering */ = { 231 | isa = PBXNativeTarget; 232 | buildConfigurationList = BE312520F27B414C8162B4FC /* Build configuration list for PBXNativeTarget "Pods-FBAnnotationClustering" */; 233 | buildPhases = ( 234 | 0D5A018A26568D670E6D1EEC /* Sources */, 235 | 5CFDCF00CCB425D8050DD061 /* Frameworks */, 236 | AF2B3536EDF12302BDFFB67C /* Headers */, 237 | ); 238 | buildRules = ( 239 | ); 240 | dependencies = ( 241 | ); 242 | name = "Pods-FBAnnotationClustering"; 243 | productName = "Pods-FBAnnotationClustering"; 244 | productReference = DB080E6A5CAA3E293DF10FE0 /* libPods-FBAnnotationClustering.a */; 245 | productType = "com.apple.product-type.library.static"; 246 | }; 247 | /* End PBXNativeTarget section */ 248 | 249 | /* Begin PBXProject section */ 250 | 994E7505722C01E294FB84AE /* Project object */ = { 251 | isa = PBXProject; 252 | attributes = { 253 | LastUpgradeCheck = 0640; 254 | }; 255 | buildConfigurationList = B7AB3459B1C5EBB044F44CC5 /* Build configuration list for PBXProject "Pods" */; 256 | compatibilityVersion = "Xcode 3.2"; 257 | developmentRegion = English; 258 | hasScannedForEncodings = 0; 259 | knownRegions = ( 260 | en, 261 | ); 262 | mainGroup = F4443EF86D567598B474A832; 263 | productRefGroup = CA8FEBA88188E98539D76831 /* Products */; 264 | projectDirPath = ""; 265 | projectRoot = ""; 266 | targets = ( 267 | 3370D7F355672284AE2E5DEB /* Pods */, 268 | 656299E91232636B85E5E89D /* Pods-FBAnnotationClustering */, 269 | ); 270 | }; 271 | /* End PBXProject section */ 272 | 273 | /* Begin PBXSourcesBuildPhase section */ 274 | 0D5A018A26568D670E6D1EEC /* Sources */ = { 275 | isa = PBXSourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | 230111A9AC22CD3C7169D183 /* FBAnnotationCluster.m in Sources */, 279 | BE1A6F2FF38010DFD82F9120 /* FBClusteringManager.m in Sources */, 280 | C8A58CB4C4D052E5C9EC745F /* FBQuadTree.m in Sources */, 281 | F8439367A557D44B5B7C89BC /* FBQuadTreeNode.m in Sources */, 282 | 971732DFA55044200E897E38 /* Pods-FBAnnotationClustering-dummy.m in Sources */, 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | }; 286 | 9F326E7F478457E1185BE048 /* Sources */ = { 287 | isa = PBXSourcesBuildPhase; 288 | buildActionMask = 2147483647; 289 | files = ( 290 | 6E348167BE41ACB4E22CEB92 /* Pods-dummy.m in Sources */, 291 | ); 292 | runOnlyForDeploymentPostprocessing = 0; 293 | }; 294 | /* End PBXSourcesBuildPhase section */ 295 | 296 | /* Begin PBXTargetDependency section */ 297 | 0019CB04166AB4429441080A /* PBXTargetDependency */ = { 298 | isa = PBXTargetDependency; 299 | name = "Pods-FBAnnotationClustering"; 300 | target = 656299E91232636B85E5E89D /* Pods-FBAnnotationClustering */; 301 | targetProxy = 40C75EFF072D1CADA1C79FAB /* PBXContainerItemProxy */; 302 | }; 303 | /* End PBXTargetDependency section */ 304 | 305 | /* Begin XCBuildConfiguration section */ 306 | 17B2486D04062AD392CAE0F3 /* Debug */ = { 307 | isa = XCBuildConfiguration; 308 | baseConfigurationReference = C512DDE43244CF21726CE691 /* Pods.debug.xcconfig */; 309 | buildSettings = { 310 | ENABLE_STRICT_OBJC_MSGSEND = YES; 311 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 312 | MTL_ENABLE_DEBUG_INFO = YES; 313 | OTHER_LDFLAGS = ""; 314 | OTHER_LIBTOOLFLAGS = ""; 315 | PODS_ROOT = "$(SRCROOT)"; 316 | PRODUCT_NAME = "$(TARGET_NAME)"; 317 | SDKROOT = iphoneos; 318 | SKIP_INSTALL = YES; 319 | }; 320 | name = Debug; 321 | }; 322 | 2A88F3C00B5515D584C42435 /* Release */ = { 323 | isa = XCBuildConfiguration; 324 | buildSettings = { 325 | ALWAYS_SEARCH_USER_PATHS = NO; 326 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 327 | CLANG_CXX_LIBRARY = "libc++"; 328 | CLANG_ENABLE_MODULES = YES; 329 | CLANG_ENABLE_OBJC_ARC = YES; 330 | CLANG_WARN_BOOL_CONVERSION = YES; 331 | CLANG_WARN_CONSTANT_CONVERSION = YES; 332 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 333 | CLANG_WARN_EMPTY_BODY = YES; 334 | CLANG_WARN_ENUM_CONVERSION = YES; 335 | CLANG_WARN_INT_CONVERSION = YES; 336 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 337 | CLANG_WARN_UNREACHABLE_CODE = YES; 338 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 339 | COPY_PHASE_STRIP = YES; 340 | ENABLE_NS_ASSERTIONS = NO; 341 | GCC_C_LANGUAGE_STANDARD = gnu99; 342 | GCC_PREPROCESSOR_DEFINITIONS = "RELEASE=1"; 343 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 344 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 345 | GCC_WARN_UNDECLARED_SELECTOR = YES; 346 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 347 | GCC_WARN_UNUSED_FUNCTION = YES; 348 | GCC_WARN_UNUSED_VARIABLE = YES; 349 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 350 | STRIP_INSTALLED_PRODUCT = NO; 351 | SYMROOT = "${SRCROOT}/../build"; 352 | VALIDATE_PRODUCT = YES; 353 | }; 354 | name = Release; 355 | }; 356 | 7C798D73062C1FD750E43CDB /* Debug */ = { 357 | isa = XCBuildConfiguration; 358 | baseConfigurationReference = 68E3E6C81C04657D6EA37223 /* Pods-FBAnnotationClustering-Private.xcconfig */; 359 | buildSettings = { 360 | ENABLE_STRICT_OBJC_MSGSEND = YES; 361 | GCC_PREFIX_HEADER = "Target Support Files/Pods-FBAnnotationClustering/Pods-FBAnnotationClustering-prefix.pch"; 362 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 363 | MTL_ENABLE_DEBUG_INFO = YES; 364 | OTHER_LDFLAGS = ""; 365 | OTHER_LIBTOOLFLAGS = ""; 366 | PRODUCT_NAME = "$(TARGET_NAME)"; 367 | SDKROOT = iphoneos; 368 | SKIP_INSTALL = YES; 369 | }; 370 | name = Debug; 371 | }; 372 | 906FABFB09EC0B2C7172AAA8 /* Release */ = { 373 | isa = XCBuildConfiguration; 374 | baseConfigurationReference = 9E10339F9D3F3EA5F5920902 /* Pods.release.xcconfig */; 375 | buildSettings = { 376 | ENABLE_STRICT_OBJC_MSGSEND = YES; 377 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 378 | MTL_ENABLE_DEBUG_INFO = NO; 379 | OTHER_LDFLAGS = ""; 380 | OTHER_LIBTOOLFLAGS = ""; 381 | PODS_ROOT = "$(SRCROOT)"; 382 | PRODUCT_NAME = "$(TARGET_NAME)"; 383 | SDKROOT = iphoneos; 384 | SKIP_INSTALL = YES; 385 | }; 386 | name = Release; 387 | }; 388 | A97C0A3E61AFD9F6154A7A57 /* Release */ = { 389 | isa = XCBuildConfiguration; 390 | baseConfigurationReference = 68E3E6C81C04657D6EA37223 /* Pods-FBAnnotationClustering-Private.xcconfig */; 391 | buildSettings = { 392 | ENABLE_STRICT_OBJC_MSGSEND = YES; 393 | GCC_PREFIX_HEADER = "Target Support Files/Pods-FBAnnotationClustering/Pods-FBAnnotationClustering-prefix.pch"; 394 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 395 | MTL_ENABLE_DEBUG_INFO = NO; 396 | OTHER_LDFLAGS = ""; 397 | OTHER_LIBTOOLFLAGS = ""; 398 | PRODUCT_NAME = "$(TARGET_NAME)"; 399 | SDKROOT = iphoneos; 400 | SKIP_INSTALL = YES; 401 | }; 402 | name = Release; 403 | }; 404 | BFE51117520896673AA11201 /* Debug */ = { 405 | isa = XCBuildConfiguration; 406 | buildSettings = { 407 | ALWAYS_SEARCH_USER_PATHS = NO; 408 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 409 | CLANG_CXX_LIBRARY = "libc++"; 410 | CLANG_ENABLE_MODULES = YES; 411 | CLANG_ENABLE_OBJC_ARC = YES; 412 | CLANG_WARN_BOOL_CONVERSION = YES; 413 | CLANG_WARN_CONSTANT_CONVERSION = YES; 414 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; 415 | CLANG_WARN_EMPTY_BODY = YES; 416 | CLANG_WARN_ENUM_CONVERSION = YES; 417 | CLANG_WARN_INT_CONVERSION = YES; 418 | CLANG_WARN_OBJC_ROOT_CLASS = YES; 419 | CLANG_WARN_UNREACHABLE_CODE = YES; 420 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 421 | COPY_PHASE_STRIP = NO; 422 | GCC_C_LANGUAGE_STANDARD = gnu99; 423 | GCC_DYNAMIC_NO_PIC = NO; 424 | GCC_OPTIMIZATION_LEVEL = 0; 425 | GCC_PREPROCESSOR_DEFINITIONS = ( 426 | "DEBUG=1", 427 | "$(inherited)", 428 | ); 429 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 430 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 431 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 432 | GCC_WARN_UNDECLARED_SELECTOR = YES; 433 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 434 | GCC_WARN_UNUSED_FUNCTION = YES; 435 | GCC_WARN_UNUSED_VARIABLE = YES; 436 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 437 | ONLY_ACTIVE_ARCH = YES; 438 | STRIP_INSTALLED_PRODUCT = NO; 439 | SYMROOT = "${SRCROOT}/../build"; 440 | }; 441 | name = Debug; 442 | }; 443 | /* End XCBuildConfiguration section */ 444 | 445 | /* Begin XCConfigurationList section */ 446 | 9BE4CFF2F35C88C74F279528 /* Build configuration list for PBXNativeTarget "Pods" */ = { 447 | isa = XCConfigurationList; 448 | buildConfigurations = ( 449 | 17B2486D04062AD392CAE0F3 /* Debug */, 450 | 906FABFB09EC0B2C7172AAA8 /* Release */, 451 | ); 452 | defaultConfigurationIsVisible = 0; 453 | defaultConfigurationName = Release; 454 | }; 455 | B7AB3459B1C5EBB044F44CC5 /* Build configuration list for PBXProject "Pods" */ = { 456 | isa = XCConfigurationList; 457 | buildConfigurations = ( 458 | BFE51117520896673AA11201 /* Debug */, 459 | 2A88F3C00B5515D584C42435 /* Release */, 460 | ); 461 | defaultConfigurationIsVisible = 0; 462 | defaultConfigurationName = Release; 463 | }; 464 | BE312520F27B414C8162B4FC /* Build configuration list for PBXNativeTarget "Pods-FBAnnotationClustering" */ = { 465 | isa = XCConfigurationList; 466 | buildConfigurations = ( 467 | 7C798D73062C1FD750E43CDB /* Debug */, 468 | A97C0A3E61AFD9F6154A7A57 /* Release */, 469 | ); 470 | defaultConfigurationIsVisible = 0; 471 | defaultConfigurationName = Release; 472 | }; 473 | /* End XCConfigurationList section */ 474 | }; 475 | rootObject = 994E7505722C01E294FB84AE /* Project object */; 476 | } 477 | -------------------------------------------------------------------------------- /Example/AnnotationClustering.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8A86F1B196A24278AA00E45F /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3F00D94D0560465788605775 /* libPods.a */; }; 11 | DC505A8518F0B505008229F7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC505A8418F0B505008229F7 /* Foundation.framework */; }; 12 | DC505A8718F0B505008229F7 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC505A8618F0B505008229F7 /* CoreGraphics.framework */; }; 13 | DC505A8918F0B505008229F7 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC505A8818F0B505008229F7 /* UIKit.framework */; }; 14 | DC505A8F18F0B505008229F7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DC505A8D18F0B505008229F7 /* InfoPlist.strings */; }; 15 | DC505A9118F0B505008229F7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DC505A9018F0B505008229F7 /* main.m */; }; 16 | DC505A9818F0B505008229F7 /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC505A9618F0B505008229F7 /* Main_iPhone.storyboard */; }; 17 | DC505A9B18F0B505008229F7 /* Main_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DC505A9918F0B505008229F7 /* Main_iPad.storyboard */; }; 18 | DC505AA018F0B505008229F7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DC505A9F18F0B505008229F7 /* Images.xcassets */; }; 19 | DC505AA718F0B505008229F7 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC505AA618F0B505008229F7 /* XCTest.framework */; }; 20 | DC505AA818F0B505008229F7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC505A8418F0B505008229F7 /* Foundation.framework */; }; 21 | DC505AA918F0B505008229F7 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC505A8818F0B505008229F7 /* UIKit.framework */; }; 22 | DC505AB118F0B505008229F7 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DC505AAF18F0B505008229F7 /* InfoPlist.strings */; }; 23 | DC505AB318F0B505008229F7 /* AnnotationClusteringTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC505AB218F0B505008229F7 /* AnnotationClusteringTests.m */; }; 24 | DC505AC318F0B9C7008229F7 /* FBAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = DC505ABF18F0B9C7008229F7 /* FBAppDelegate.m */; }; 25 | DC505AC418F0B9C7008229F7 /* FBViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = DC505AC218F0B9C7008229F7 /* FBViewController.m */; }; 26 | DC505AC818F0BA9E008229F7 /* FBAnnotation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC505AC718F0BA9E008229F7 /* FBAnnotation.m */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXContainerItemProxy section */ 30 | DC505AAA18F0B505008229F7 /* PBXContainerItemProxy */ = { 31 | isa = PBXContainerItemProxy; 32 | containerPortal = DC505A7918F0B505008229F7 /* Project object */; 33 | proxyType = 1; 34 | remoteGlobalIDString = DC505A8018F0B505008229F7; 35 | remoteInfo = AnnotationClustering; 36 | }; 37 | /* End PBXContainerItemProxy section */ 38 | 39 | /* Begin PBXFileReference section */ 40 | 07747994D3D1DB6F5D31E65D /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; 41 | 3F00D94D0560465788605775 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | AD84D55ACD714A4191C3DDAF /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 43 | DC505A8118F0B505008229F7 /* AnnotationClustering.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AnnotationClustering.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | DC505A8418F0B505008229F7 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 45 | DC505A8618F0B505008229F7 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 46 | DC505A8818F0B505008229F7 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 47 | DC505A8C18F0B505008229F7 /* AnnotationClustering-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "AnnotationClustering-Info.plist"; sourceTree = ""; }; 48 | DC505A8E18F0B505008229F7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 49 | DC505A9018F0B505008229F7 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 50 | DC505A9218F0B505008229F7 /* AnnotationClustering-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AnnotationClustering-Prefix.pch"; sourceTree = ""; }; 51 | DC505A9718F0B505008229F7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPhone.storyboard; sourceTree = ""; }; 52 | DC505A9A18F0B505008229F7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPad.storyboard; sourceTree = ""; }; 53 | DC505A9F18F0B505008229F7 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 54 | DC505AA518F0B505008229F7 /* AnnotationClusteringTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AnnotationClusteringTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | DC505AA618F0B505008229F7 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 56 | DC505AAE18F0B505008229F7 /* AnnotationClusteringTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "AnnotationClusteringTests-Info.plist"; sourceTree = ""; }; 57 | DC505AB018F0B505008229F7 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 58 | DC505AB218F0B505008229F7 /* AnnotationClusteringTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AnnotationClusteringTests.m; sourceTree = ""; }; 59 | DC505ABE18F0B9C7008229F7 /* FBAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBAppDelegate.h; sourceTree = ""; }; 60 | DC505ABF18F0B9C7008229F7 /* FBAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBAppDelegate.m; sourceTree = ""; }; 61 | DC505AC118F0B9C7008229F7 /* FBViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBViewController.h; sourceTree = ""; }; 62 | DC505AC218F0B9C7008229F7 /* FBViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBViewController.m; sourceTree = ""; }; 63 | DC505AC618F0BA9E008229F7 /* FBAnnotation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBAnnotation.h; sourceTree = ""; }; 64 | DC505AC718F0BA9E008229F7 /* FBAnnotation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBAnnotation.m; sourceTree = ""; }; 65 | /* End PBXFileReference section */ 66 | 67 | /* Begin PBXFrameworksBuildPhase section */ 68 | DC505A7E18F0B505008229F7 /* Frameworks */ = { 69 | isa = PBXFrameworksBuildPhase; 70 | buildActionMask = 2147483647; 71 | files = ( 72 | DC505A8718F0B505008229F7 /* CoreGraphics.framework in Frameworks */, 73 | DC505A8918F0B505008229F7 /* UIKit.framework in Frameworks */, 74 | DC505A8518F0B505008229F7 /* Foundation.framework in Frameworks */, 75 | 8A86F1B196A24278AA00E45F /* libPods.a in Frameworks */, 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | DC505AA218F0B505008229F7 /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | DC505AA718F0B505008229F7 /* XCTest.framework in Frameworks */, 84 | DC505AA918F0B505008229F7 /* UIKit.framework in Frameworks */, 85 | DC505AA818F0B505008229F7 /* Foundation.framework in Frameworks */, 86 | ); 87 | runOnlyForDeploymentPostprocessing = 0; 88 | }; 89 | /* End PBXFrameworksBuildPhase section */ 90 | 91 | /* Begin PBXGroup section */ 92 | 05579FE0F8D92E3787937C7E /* Pods */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 07747994D3D1DB6F5D31E65D /* Pods.debug.xcconfig */, 96 | AD84D55ACD714A4191C3DDAF /* Pods.release.xcconfig */, 97 | ); 98 | name = Pods; 99 | sourceTree = ""; 100 | }; 101 | DC505A7818F0B505008229F7 = { 102 | isa = PBXGroup; 103 | children = ( 104 | DC505A9618F0B505008229F7 /* Main_iPhone.storyboard */, 105 | DC505A9918F0B505008229F7 /* Main_iPad.storyboard */, 106 | DC505ABC18F0B9C7008229F7 /* Classes */, 107 | DC505A8A18F0B505008229F7 /* AnnotationClustering */, 108 | DC505AAC18F0B505008229F7 /* AnnotationClusteringTests */, 109 | DC505A8318F0B505008229F7 /* Frameworks */, 110 | DC505A8218F0B505008229F7 /* Products */, 111 | 05579FE0F8D92E3787937C7E /* Pods */, 112 | ); 113 | sourceTree = ""; 114 | }; 115 | DC505A8218F0B505008229F7 /* Products */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | DC505A8118F0B505008229F7 /* AnnotationClustering.app */, 119 | DC505AA518F0B505008229F7 /* AnnotationClusteringTests.xctest */, 120 | ); 121 | name = Products; 122 | sourceTree = ""; 123 | }; 124 | DC505A8318F0B505008229F7 /* Frameworks */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | DC505A8418F0B505008229F7 /* Foundation.framework */, 128 | DC505A8618F0B505008229F7 /* CoreGraphics.framework */, 129 | DC505A8818F0B505008229F7 /* UIKit.framework */, 130 | DC505AA618F0B505008229F7 /* XCTest.framework */, 131 | 3F00D94D0560465788605775 /* libPods.a */, 132 | ); 133 | name = Frameworks; 134 | sourceTree = ""; 135 | }; 136 | DC505A8A18F0B505008229F7 /* AnnotationClustering */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | DC505A9F18F0B505008229F7 /* Images.xcassets */, 140 | DC505A8B18F0B505008229F7 /* Supporting Files */, 141 | ); 142 | path = AnnotationClustering; 143 | sourceTree = ""; 144 | }; 145 | DC505A8B18F0B505008229F7 /* Supporting Files */ = { 146 | isa = PBXGroup; 147 | children = ( 148 | DC505A8C18F0B505008229F7 /* AnnotationClustering-Info.plist */, 149 | DC505A8D18F0B505008229F7 /* InfoPlist.strings */, 150 | DC505A9018F0B505008229F7 /* main.m */, 151 | DC505A9218F0B505008229F7 /* AnnotationClustering-Prefix.pch */, 152 | ); 153 | name = "Supporting Files"; 154 | sourceTree = ""; 155 | }; 156 | DC505AAC18F0B505008229F7 /* AnnotationClusteringTests */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | DC505AB218F0B505008229F7 /* AnnotationClusteringTests.m */, 160 | DC505AAD18F0B505008229F7 /* Supporting Files */, 161 | ); 162 | path = AnnotationClusteringTests; 163 | sourceTree = ""; 164 | }; 165 | DC505AAD18F0B505008229F7 /* Supporting Files */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | DC505AAE18F0B505008229F7 /* AnnotationClusteringTests-Info.plist */, 169 | DC505AAF18F0B505008229F7 /* InfoPlist.strings */, 170 | ); 171 | name = "Supporting Files"; 172 | sourceTree = ""; 173 | }; 174 | DC505ABC18F0B9C7008229F7 /* Classes */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | DC505AC518F0BA9E008229F7 /* Models */, 178 | DC505ABD18F0B9C7008229F7 /* Application */, 179 | DC505AC018F0B9C7008229F7 /* Controllers */, 180 | ); 181 | path = Classes; 182 | sourceTree = ""; 183 | }; 184 | DC505ABD18F0B9C7008229F7 /* Application */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | DC505ABE18F0B9C7008229F7 /* FBAppDelegate.h */, 188 | DC505ABF18F0B9C7008229F7 /* FBAppDelegate.m */, 189 | ); 190 | path = Application; 191 | sourceTree = ""; 192 | }; 193 | DC505AC018F0B9C7008229F7 /* Controllers */ = { 194 | isa = PBXGroup; 195 | children = ( 196 | DC505AC118F0B9C7008229F7 /* FBViewController.h */, 197 | DC505AC218F0B9C7008229F7 /* FBViewController.m */, 198 | ); 199 | path = Controllers; 200 | sourceTree = ""; 201 | }; 202 | DC505AC518F0BA9E008229F7 /* Models */ = { 203 | isa = PBXGroup; 204 | children = ( 205 | DC505AC618F0BA9E008229F7 /* FBAnnotation.h */, 206 | DC505AC718F0BA9E008229F7 /* FBAnnotation.m */, 207 | ); 208 | path = Models; 209 | sourceTree = ""; 210 | }; 211 | /* End PBXGroup section */ 212 | 213 | /* Begin PBXNativeTarget section */ 214 | DC505A8018F0B505008229F7 /* AnnotationClustering */ = { 215 | isa = PBXNativeTarget; 216 | buildConfigurationList = DC505AB618F0B505008229F7 /* Build configuration list for PBXNativeTarget "AnnotationClustering" */; 217 | buildPhases = ( 218 | C824D8F46E5A49FC8DD53F70 /* Check Pods Manifest.lock */, 219 | DC505A7D18F0B505008229F7 /* Sources */, 220 | DC505A7E18F0B505008229F7 /* Frameworks */, 221 | DC505A7F18F0B505008229F7 /* Resources */, 222 | D2664DE289974DEE8DDE59FB /* Copy Pods Resources */, 223 | ); 224 | buildRules = ( 225 | ); 226 | dependencies = ( 227 | ); 228 | name = AnnotationClustering; 229 | productName = AnnotationClustering; 230 | productReference = DC505A8118F0B505008229F7 /* AnnotationClustering.app */; 231 | productType = "com.apple.product-type.application"; 232 | }; 233 | DC505AA418F0B505008229F7 /* AnnotationClusteringTests */ = { 234 | isa = PBXNativeTarget; 235 | buildConfigurationList = DC505AB918F0B505008229F7 /* Build configuration list for PBXNativeTarget "AnnotationClusteringTests" */; 236 | buildPhases = ( 237 | DC505AA118F0B505008229F7 /* Sources */, 238 | DC505AA218F0B505008229F7 /* Frameworks */, 239 | DC505AA318F0B505008229F7 /* Resources */, 240 | ); 241 | buildRules = ( 242 | ); 243 | dependencies = ( 244 | DC505AAB18F0B505008229F7 /* PBXTargetDependency */, 245 | ); 246 | name = AnnotationClusteringTests; 247 | productName = AnnotationClusteringTests; 248 | productReference = DC505AA518F0B505008229F7 /* AnnotationClusteringTests.xctest */; 249 | productType = "com.apple.product-type.bundle.unit-test"; 250 | }; 251 | /* End PBXNativeTarget section */ 252 | 253 | /* Begin PBXProject section */ 254 | DC505A7918F0B505008229F7 /* Project object */ = { 255 | isa = PBXProject; 256 | attributes = { 257 | CLASSPREFIX = FB; 258 | LastUpgradeCheck = 0510; 259 | ORGANIZATIONNAME = "Infinum Ltd."; 260 | TargetAttributes = { 261 | DC505AA418F0B505008229F7 = { 262 | TestTargetID = DC505A8018F0B505008229F7; 263 | }; 264 | }; 265 | }; 266 | buildConfigurationList = DC505A7C18F0B505008229F7 /* Build configuration list for PBXProject "AnnotationClustering" */; 267 | compatibilityVersion = "Xcode 3.2"; 268 | developmentRegion = English; 269 | hasScannedForEncodings = 0; 270 | knownRegions = ( 271 | en, 272 | Base, 273 | ); 274 | mainGroup = DC505A7818F0B505008229F7; 275 | productRefGroup = DC505A8218F0B505008229F7 /* Products */; 276 | projectDirPath = ""; 277 | projectRoot = ""; 278 | targets = ( 279 | DC505A8018F0B505008229F7 /* AnnotationClustering */, 280 | DC505AA418F0B505008229F7 /* AnnotationClusteringTests */, 281 | ); 282 | }; 283 | /* End PBXProject section */ 284 | 285 | /* Begin PBXResourcesBuildPhase section */ 286 | DC505A7F18F0B505008229F7 /* Resources */ = { 287 | isa = PBXResourcesBuildPhase; 288 | buildActionMask = 2147483647; 289 | files = ( 290 | DC505A9B18F0B505008229F7 /* Main_iPad.storyboard in Resources */, 291 | DC505AA018F0B505008229F7 /* Images.xcassets in Resources */, 292 | DC505A9818F0B505008229F7 /* Main_iPhone.storyboard in Resources */, 293 | DC505A8F18F0B505008229F7 /* InfoPlist.strings in Resources */, 294 | ); 295 | runOnlyForDeploymentPostprocessing = 0; 296 | }; 297 | DC505AA318F0B505008229F7 /* Resources */ = { 298 | isa = PBXResourcesBuildPhase; 299 | buildActionMask = 2147483647; 300 | files = ( 301 | DC505AB118F0B505008229F7 /* InfoPlist.strings in Resources */, 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | }; 305 | /* End PBXResourcesBuildPhase section */ 306 | 307 | /* Begin PBXShellScriptBuildPhase section */ 308 | C824D8F46E5A49FC8DD53F70 /* Check Pods Manifest.lock */ = { 309 | isa = PBXShellScriptBuildPhase; 310 | buildActionMask = 2147483647; 311 | files = ( 312 | ); 313 | inputPaths = ( 314 | ); 315 | name = "Check Pods Manifest.lock"; 316 | outputPaths = ( 317 | ); 318 | runOnlyForDeploymentPostprocessing = 0; 319 | shellPath = /bin/sh; 320 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 321 | showEnvVarsInLog = 0; 322 | }; 323 | D2664DE289974DEE8DDE59FB /* Copy Pods Resources */ = { 324 | isa = PBXShellScriptBuildPhase; 325 | buildActionMask = 2147483647; 326 | files = ( 327 | ); 328 | inputPaths = ( 329 | ); 330 | name = "Copy Pods Resources"; 331 | outputPaths = ( 332 | ); 333 | runOnlyForDeploymentPostprocessing = 0; 334 | shellPath = /bin/sh; 335 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; 336 | showEnvVarsInLog = 0; 337 | }; 338 | /* End PBXShellScriptBuildPhase section */ 339 | 340 | /* Begin PBXSourcesBuildPhase section */ 341 | DC505A7D18F0B505008229F7 /* Sources */ = { 342 | isa = PBXSourcesBuildPhase; 343 | buildActionMask = 2147483647; 344 | files = ( 345 | DC505AC818F0BA9E008229F7 /* FBAnnotation.m in Sources */, 346 | DC505AC318F0B9C7008229F7 /* FBAppDelegate.m in Sources */, 347 | DC505A9118F0B505008229F7 /* main.m in Sources */, 348 | DC505AC418F0B9C7008229F7 /* FBViewController.m in Sources */, 349 | ); 350 | runOnlyForDeploymentPostprocessing = 0; 351 | }; 352 | DC505AA118F0B505008229F7 /* Sources */ = { 353 | isa = PBXSourcesBuildPhase; 354 | buildActionMask = 2147483647; 355 | files = ( 356 | DC505AB318F0B505008229F7 /* AnnotationClusteringTests.m in Sources */, 357 | ); 358 | runOnlyForDeploymentPostprocessing = 0; 359 | }; 360 | /* End PBXSourcesBuildPhase section */ 361 | 362 | /* Begin PBXTargetDependency section */ 363 | DC505AAB18F0B505008229F7 /* PBXTargetDependency */ = { 364 | isa = PBXTargetDependency; 365 | target = DC505A8018F0B505008229F7 /* AnnotationClustering */; 366 | targetProxy = DC505AAA18F0B505008229F7 /* PBXContainerItemProxy */; 367 | }; 368 | /* End PBXTargetDependency section */ 369 | 370 | /* Begin PBXVariantGroup section */ 371 | DC505A8D18F0B505008229F7 /* InfoPlist.strings */ = { 372 | isa = PBXVariantGroup; 373 | children = ( 374 | DC505A8E18F0B505008229F7 /* en */, 375 | ); 376 | name = InfoPlist.strings; 377 | sourceTree = ""; 378 | }; 379 | DC505A9618F0B505008229F7 /* Main_iPhone.storyboard */ = { 380 | isa = PBXVariantGroup; 381 | children = ( 382 | DC505A9718F0B505008229F7 /* Base */, 383 | ); 384 | name = Main_iPhone.storyboard; 385 | path = AnnotationClustering; 386 | sourceTree = ""; 387 | }; 388 | DC505A9918F0B505008229F7 /* Main_iPad.storyboard */ = { 389 | isa = PBXVariantGroup; 390 | children = ( 391 | DC505A9A18F0B505008229F7 /* Base */, 392 | ); 393 | name = Main_iPad.storyboard; 394 | path = AnnotationClustering; 395 | sourceTree = ""; 396 | }; 397 | DC505AAF18F0B505008229F7 /* InfoPlist.strings */ = { 398 | isa = PBXVariantGroup; 399 | children = ( 400 | DC505AB018F0B505008229F7 /* en */, 401 | ); 402 | name = InfoPlist.strings; 403 | sourceTree = ""; 404 | }; 405 | /* End PBXVariantGroup section */ 406 | 407 | /* Begin XCBuildConfiguration section */ 408 | DC505AB418F0B505008229F7 /* Debug */ = { 409 | isa = XCBuildConfiguration; 410 | buildSettings = { 411 | ALWAYS_SEARCH_USER_PATHS = NO; 412 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 413 | CLANG_CXX_LIBRARY = "libc++"; 414 | CLANG_ENABLE_MODULES = YES; 415 | CLANG_ENABLE_OBJC_ARC = YES; 416 | CLANG_WARN_BOOL_CONVERSION = YES; 417 | CLANG_WARN_CONSTANT_CONVERSION = YES; 418 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 419 | CLANG_WARN_EMPTY_BODY = YES; 420 | CLANG_WARN_ENUM_CONVERSION = YES; 421 | CLANG_WARN_INT_CONVERSION = YES; 422 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 423 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 424 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 425 | COPY_PHASE_STRIP = NO; 426 | GCC_C_LANGUAGE_STANDARD = gnu99; 427 | GCC_DYNAMIC_NO_PIC = NO; 428 | GCC_OPTIMIZATION_LEVEL = 0; 429 | GCC_PREPROCESSOR_DEFINITIONS = ( 430 | "DEBUG=1", 431 | "$(inherited)", 432 | ); 433 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 434 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 435 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 436 | GCC_WARN_UNDECLARED_SELECTOR = YES; 437 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 438 | GCC_WARN_UNUSED_FUNCTION = YES; 439 | GCC_WARN_UNUSED_VARIABLE = YES; 440 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 441 | ONLY_ACTIVE_ARCH = YES; 442 | SDKROOT = iphoneos; 443 | TARGETED_DEVICE_FAMILY = "1,2"; 444 | }; 445 | name = Debug; 446 | }; 447 | DC505AB518F0B505008229F7 /* Release */ = { 448 | isa = XCBuildConfiguration; 449 | buildSettings = { 450 | ALWAYS_SEARCH_USER_PATHS = NO; 451 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 452 | CLANG_CXX_LIBRARY = "libc++"; 453 | CLANG_ENABLE_MODULES = YES; 454 | CLANG_ENABLE_OBJC_ARC = YES; 455 | CLANG_WARN_BOOL_CONVERSION = YES; 456 | CLANG_WARN_CONSTANT_CONVERSION = YES; 457 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 458 | CLANG_WARN_EMPTY_BODY = YES; 459 | CLANG_WARN_ENUM_CONVERSION = YES; 460 | CLANG_WARN_INT_CONVERSION = YES; 461 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 462 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 463 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 464 | COPY_PHASE_STRIP = YES; 465 | ENABLE_NS_ASSERTIONS = NO; 466 | GCC_C_LANGUAGE_STANDARD = gnu99; 467 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 468 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 469 | GCC_WARN_UNDECLARED_SELECTOR = YES; 470 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 471 | GCC_WARN_UNUSED_FUNCTION = YES; 472 | GCC_WARN_UNUSED_VARIABLE = YES; 473 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 474 | SDKROOT = iphoneos; 475 | TARGETED_DEVICE_FAMILY = "1,2"; 476 | VALIDATE_PRODUCT = YES; 477 | }; 478 | name = Release; 479 | }; 480 | DC505AB718F0B505008229F7 /* Debug */ = { 481 | isa = XCBuildConfiguration; 482 | baseConfigurationReference = 07747994D3D1DB6F5D31E65D /* Pods.debug.xcconfig */; 483 | buildSettings = { 484 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 485 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 486 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 487 | GCC_PREFIX_HEADER = "AnnotationClustering/AnnotationClustering-Prefix.pch"; 488 | INFOPLIST_FILE = "AnnotationClustering/AnnotationClustering-Info.plist"; 489 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 490 | PRODUCT_NAME = "$(TARGET_NAME)"; 491 | WRAPPER_EXTENSION = app; 492 | }; 493 | name = Debug; 494 | }; 495 | DC505AB818F0B505008229F7 /* Release */ = { 496 | isa = XCBuildConfiguration; 497 | baseConfigurationReference = AD84D55ACD714A4191C3DDAF /* Pods.release.xcconfig */; 498 | buildSettings = { 499 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 500 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 501 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 502 | GCC_PREFIX_HEADER = "AnnotationClustering/AnnotationClustering-Prefix.pch"; 503 | INFOPLIST_FILE = "AnnotationClustering/AnnotationClustering-Info.plist"; 504 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 505 | PRODUCT_NAME = "$(TARGET_NAME)"; 506 | WRAPPER_EXTENSION = app; 507 | }; 508 | name = Release; 509 | }; 510 | DC505ABA18F0B505008229F7 /* Debug */ = { 511 | isa = XCBuildConfiguration; 512 | buildSettings = { 513 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/AnnotationClustering.app/AnnotationClustering"; 514 | FRAMEWORK_SEARCH_PATHS = ( 515 | "$(SDKROOT)/Developer/Library/Frameworks", 516 | "$(inherited)", 517 | "$(DEVELOPER_FRAMEWORKS_DIR)", 518 | ); 519 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 520 | GCC_PREFIX_HEADER = "AnnotationClustering/AnnotationClustering-Prefix.pch"; 521 | GCC_PREPROCESSOR_DEFINITIONS = ( 522 | "DEBUG=1", 523 | "$(inherited)", 524 | ); 525 | INFOPLIST_FILE = "AnnotationClusteringTests/AnnotationClusteringTests-Info.plist"; 526 | PRODUCT_NAME = "$(TARGET_NAME)"; 527 | TEST_HOST = "$(BUNDLE_LOADER)"; 528 | WRAPPER_EXTENSION = xctest; 529 | }; 530 | name = Debug; 531 | }; 532 | DC505ABB18F0B505008229F7 /* Release */ = { 533 | isa = XCBuildConfiguration; 534 | buildSettings = { 535 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/AnnotationClustering.app/AnnotationClustering"; 536 | FRAMEWORK_SEARCH_PATHS = ( 537 | "$(SDKROOT)/Developer/Library/Frameworks", 538 | "$(inherited)", 539 | "$(DEVELOPER_FRAMEWORKS_DIR)", 540 | ); 541 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 542 | GCC_PREFIX_HEADER = "AnnotationClustering/AnnotationClustering-Prefix.pch"; 543 | INFOPLIST_FILE = "AnnotationClusteringTests/AnnotationClusteringTests-Info.plist"; 544 | PRODUCT_NAME = "$(TARGET_NAME)"; 545 | TEST_HOST = "$(BUNDLE_LOADER)"; 546 | WRAPPER_EXTENSION = xctest; 547 | }; 548 | name = Release; 549 | }; 550 | /* End XCBuildConfiguration section */ 551 | 552 | /* Begin XCConfigurationList section */ 553 | DC505A7C18F0B505008229F7 /* Build configuration list for PBXProject "AnnotationClustering" */ = { 554 | isa = XCConfigurationList; 555 | buildConfigurations = ( 556 | DC505AB418F0B505008229F7 /* Debug */, 557 | DC505AB518F0B505008229F7 /* Release */, 558 | ); 559 | defaultConfigurationIsVisible = 0; 560 | defaultConfigurationName = Release; 561 | }; 562 | DC505AB618F0B505008229F7 /* Build configuration list for PBXNativeTarget "AnnotationClustering" */ = { 563 | isa = XCConfigurationList; 564 | buildConfigurations = ( 565 | DC505AB718F0B505008229F7 /* Debug */, 566 | DC505AB818F0B505008229F7 /* Release */, 567 | ); 568 | defaultConfigurationIsVisible = 0; 569 | defaultConfigurationName = Release; 570 | }; 571 | DC505AB918F0B505008229F7 /* Build configuration list for PBXNativeTarget "AnnotationClusteringTests" */ = { 572 | isa = XCConfigurationList; 573 | buildConfigurations = ( 574 | DC505ABA18F0B505008229F7 /* Debug */, 575 | DC505ABB18F0B505008229F7 /* Release */, 576 | ); 577 | defaultConfigurationIsVisible = 0; 578 | defaultConfigurationName = Release; 579 | }; 580 | /* End XCConfigurationList section */ 581 | }; 582 | rootObject = DC505A7918F0B505008229F7 /* Project object */; 583 | } 584 | --------------------------------------------------------------------------------