├── Tests ├── .gitignore ├── OSMKit │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── OSMKTestImportViewController.h │ ├── OSMKAppDelegate.h │ ├── main.m │ ├── OSMKit-Prefix.pch │ ├── main.mm │ ├── OSMKTestResult.m │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── OSMKTestResult.h │ ├── OSMKit-Info.plist │ ├── OSMKAppDelegate.m │ └── OSMKTestImportViewController.m ├── OSMKitTests │ ├── en.lproj │ │ └── InfoPlist.strings │ ├── Data │ │ ├── note.json │ │ └── user.osm │ ├── OSMKitTests-Info.plist │ ├── OSMKTestData.h │ ├── OSMKImporterTests.m │ ├── OSMKAPITests.m │ ├── OSMKTestData.m │ ├── OSMKParserTests.m │ └── OSMKStorageTests.m ├── OSMKit.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ └── david.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ └── xcshareddata │ │ └── OSMKit.xccheckout ├── OSMKit.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcuserdata │ │ │ └── david.xcuserdatad │ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcshareddata │ │ │ └── OSMKit.xccheckout │ ├── xcuserdata │ │ └── david.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ ├── xcshareddata │ │ ├── xcbaselines │ │ │ └── 632C3CB918FDE815001E8C69.xcbaseline │ │ │ │ ├── Info.plist │ │ │ │ └── 54F0840A-F1C9-418C-942D-662974703964.plist │ │ └── xcschemes │ │ │ └── OSMKit.xcscheme │ └── project.pbxproj └── Podfile ├── .gitmodules ├── .travis.yml ├── OSMKit ├── Model │ ├── OSMKRelation.h │ ├── OSMKWay.h │ ├── OSMKRelationMember.h │ ├── OSMKNode.h │ ├── OSMKBoundingBox.h │ ├── OSMKComment.h │ ├── OSMKChangeset.h │ ├── OSMKBoundingBox.m │ ├── OSMKRelationMember.m │ ├── OSMKNote.h │ ├── OSMKUser.h │ ├── OSMKWay.m │ ├── OSMKRelation.m │ ├── OSMKComment.m │ ├── OSMKUser.m │ ├── OSMKNode.m │ ├── OSMKObject.h │ ├── OSMKChangeset.m │ ├── OSMKNote.m │ └── OSMKObject.m ├── Parser │ ├── OSMKParser.h │ ├── OSMKTBXMLParser.h │ ├── OSMKNSJSONSerialization.h │ ├── OSMKParseOperation.m │ ├── TBXML+OSMKit.h │ ├── OSMKParseOperation.h │ ├── OSMKNSJSONSerialization.m │ ├── TBXML+OSMKit.m │ └── OSMKTBXMLParser.m ├── Utilities │ ├── OSMKit.h │ ├── OSMKConstants.h │ └── OSMKConstants.m ├── Storage │ ├── OSMKImporter.h │ ├── OSMKSpatiaLiteStorage.h │ ├── FMDatabase+OSMKitSpatiaLite.h │ ├── OSMKSpatiaLiteStorage.m │ ├── OSMKImporter.m │ └── FMDatabase+OSMKitSpatiaLite.m └── API │ ├── OSMKRequestSerializer.h │ ├── OSMKRequestSerializer.m │ ├── OSMKAPIClient.h │ └── OSMKAPIClient.m ├── OSMKit.podspec └── README.md /Tests/.gitignore: -------------------------------------------------------------------------------- 1 | Pods/ -------------------------------------------------------------------------------- /Tests/OSMKit/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Tests/OSMKitTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Tests/OSMKitTests/Submodules"] 2 | path = Tests/OSMKitTests/Submodules 3 | url = git@github.com:travisjeffery/TRVSMonitor.git 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | podfile: Tests/Podfile 3 | 4 | script: 5 | - cd Tests 6 | - xctool -workspace OSMKit.xcworkspace -scheme OSMKit -sdk iphonesimulator -arch i386 test -------------------------------------------------------------------------------- /Tests/OSMKit.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Tests/OSMKit.xcworkspace/xcuserdata/david.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidchiles/OSMKit/HEAD/Tests/OSMKit.xcworkspace/xcuserdata/david.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Tests/OSMKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Tests/OSMKit.xcodeproj/project.xcworkspace/xcuserdata/david.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidchiles/OSMKit/HEAD/Tests/OSMKit.xcodeproj/project.xcworkspace/xcuserdata/david.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Tests/OSMKit/OSMKTestImportViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKTestImportViewController.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 1/15/15. 6 | // Copyright (c) 2015 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface OSMKTestImportViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKRelation.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKRelation.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKObject.h" 10 | 11 | 12 | @interface OSMKRelation : OSMKObject 13 | 14 | @property (nonatomic,strong)NSArray* members; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKWay.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKWay.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKObject.h" 10 | 11 | @interface OSMKWay : OSMKObject 12 | 13 | //list of node ids 14 | @property (nonatomic, strong) NSArray *nodes; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /OSMKit/Parser/OSMKParser.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKParser.h 3 | // Pods 4 | // 5 | // Created by David Chiles on 12/28/14. 6 | // 7 | // 8 | 9 | @protocol OSMKParserProtocol 10 | 11 | - (NSArray *)parseNodes; 12 | - (NSArray *)parseWays; 13 | - (NSArray *)parseRelations; 14 | 15 | - (NSArray *)parseUsers; 16 | - (NSArray *)parseNotes; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Tests/OSMKit/OSMKAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKAppDelegate.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface OSMKAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /OSMKit/Parser/OSMKTBXMLParser.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKTBXMLParser.h 3 | // Pods 4 | // 5 | // Created by David Chiles on 12/28/14. 6 | // 7 | // 8 | 9 | #import 10 | 11 | #import "OSMKParser.h" 12 | 13 | @interface OSMKTBXMLParser : NSObject 14 | 15 | - (instancetype)initWithData:(NSData *)data error:(NSError **)error; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /OSMKit/Utilities/OSMKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKit.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 12/2/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKNode.h" 10 | #import "OSMKWay.h" 11 | #import "OSMKRelation.h" 12 | #import "OSMKRelationMember.h" 13 | #import "OSMKUser.h" 14 | #import "OSMKNote.h" 15 | #import "OSMKComment.h" 16 | 17 | 18 | -------------------------------------------------------------------------------- /Tests/OSMKit/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 12/2/14. 6 | // Copyright (c) 2014 David Chiles. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Tests/OSMKit/OSMKit-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_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /Tests/OSMKit/main.mm: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "OSMKAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([OSMKAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Tests/OSMKit.xcworkspace/xcuserdata/david.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /OSMKit/Parser/OSMKNSJSONSerialization.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKNSJSONSerializationParser.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/21/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKParser.h" 10 | 11 | @interface OSMKNSJSONSerialization : NSObject 12 | 13 | - (instancetype)initWithData:(NSData *)data; 14 | - (instancetype)initWithStream:(NSInputStream *)inputStream; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /OSMKit/Storage/OSMKImporter.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKImporter.h 3 | // Pods 4 | // 5 | // Created by David Chiles on 1/13/15. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface OSMKImporter : NSObject 12 | 13 | - (BOOL)setupDatbaseWithPath:(NSString *)path overwrite:(BOOL)overwrite; 14 | 15 | - (void)importXMLData:(NSData *)xmlData completion:(void (^)(void))completion completionQueue:(dispatch_queue_t)completionQueue; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Tests/OSMKit/OSMKTestResult.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKTestResult.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 1/15/15. 6 | // Copyright (c) 2015 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKTestResult.h" 10 | 11 | @implementation OSMKTestResult 12 | 13 | - (NSTimeInterval)averageDuration 14 | { 15 | if (self.iterations > 0) { 16 | return self.duration / self.iterations; 17 | } 18 | return 0; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /OSMKit/Parser/OSMKParseOperation.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKParseOperation.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 11/30/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKParseOperation.h" 10 | 11 | @implementation OSMKParseOperation 12 | 13 | - (instancetype)initWithData:(NSData *)data 14 | { 15 | if (self = [self init]) { 16 | _data = data; 17 | } 18 | return self; 19 | } 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Tests/OSMKit/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 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Tests/OSMKit/OSMKTestResult.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKTestResult.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 1/15/15. 6 | // Copyright (c) 2015 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface OSMKTestResult : NSObject 12 | 13 | @property (nonatomic, strong) NSString *testName; 14 | @property (nonatomic) NSUInteger iterations; 15 | @property (nonatomic) NSTimeInterval duration; 16 | 17 | - (NSTimeInterval)averageDuration; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /OSMKit/Parser/TBXML+OSMKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // TBXML+OSMKit.h 3 | // Pods 4 | // 5 | // Created by David Chiles on 12/11/14. 6 | // 7 | // 8 | 9 | #import "TBXML.h" 10 | 11 | @interface TBXML (OSMKit) 12 | 13 | + (NSDictionary *)osmk_attributesDictionaryWithElement:(TBXMLElement *)element; 14 | 15 | + (NSDictionary *)osmk_tagsDictioanryWithElement:(TBXMLElement *)element; 16 | 17 | + (NSArray *)osmk_wayNodesWithElement:(TBXMLElement *)element; 18 | 19 | + (NSArray *)osmk_relationMembersWithElement:(TBXMLElement *)element; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /OSMKit/API/OSMKRequestSerializer.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKRequestSerializer.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 6/9/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "AFURLRequestSerialization.h" 10 | 11 | @interface OSMKRequestSerializer : AFHTTPRequestSerializer 12 | 13 | - (instancetype)initWithConsumerKey:(NSString *)consumerKey 14 | privateKey:(NSString *)privateKey 15 | token:(NSString *)token 16 | tokenSecret:(NSString *)tokenSecret; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKRelationMember.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKRelationMember.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "OSMKObject.h" 12 | 13 | @interface OSMKRelationMember : NSObject 14 | 15 | @property (nonatomic) OSMKElementType type; 16 | @property (nonatomic) int64_t ref; 17 | @property (nonatomic, strong) NSString *role; 18 | 19 | - (instancetype)initWithAttributesDictionary:(NSDictionary *)dictionary; 20 | 21 | 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKNode.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKObject.h" 10 | #import 11 | 12 | @interface OSMKNode : OSMKObject 13 | 14 | /** This node latitude. (WGS 84 - SRID 4326) */ 15 | @property (nonatomic, readonly)double latitude; 16 | /** This node longitude. (WGS 84 - SRID 4326) */ 17 | @property (nonatomic, readonly)double longitude; 18 | 19 | @property (nonatomic) CLLocationCoordinate2D coordinate; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Tests/OSMKit/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 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Tests/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '7.0' 2 | inhibit_all_warnings! 3 | 4 | link_with 'OSMKit', 'OSMKitTests' 5 | 6 | pod "OSMKit", :path => "../" 7 | pod "SpatialDBKit", :git => 'https://github.com/davidchiles/SpatialDBKit' , :branch => 'master' 8 | 9 | pre_install do |installer_representation| 10 | path = Pathname(installer_representation.sandbox.pod_dir("spatialite"))+"src/spatialite/spatialite.c" 11 | 12 | text = File.read(path) 13 | new_text = text.gsub(/#include /, "#include ") 14 | 15 | File.open(path, "w") {|file| file.puts new_text } 16 | 17 | end -------------------------------------------------------------------------------- /OSMKit/Model/OSMKBoundingBox.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKBoundingBox.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 6/9/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface OSMKBoundingBox : NSObject 13 | 14 | @property (nonatomic) double left; 15 | @property (nonatomic) double right; 16 | @property (nonatomic) double top; 17 | @property (nonatomic) double bottom; 18 | 19 | + (instancetype)boundingBoxWithCornersSW:(CLLocationCoordinate2D)southWest NE:(CLLocationCoordinate2D)northEast; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /OSMKit/Parser/OSMKParseOperation.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKParseOperation.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 11/30/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OSMKit.h" 11 | 12 | @interface OSMKParseOperation : NSOperation 13 | 14 | @property (nonatomic, strong, readonly) NSData *data; 15 | 16 | /** 17 | The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used. 18 | */ 19 | @property (nonatomic, strong) dispatch_queue_t completionQueue; 20 | 21 | - (instancetype)initWithData:(NSData *)data; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Tests/OSMKitTests/Data/note.json: -------------------------------------------------------------------------------- 1 | {"type":"Feature","geometry":{"type":"Point","coordinates":[18.685078,45.5556731]},"properties":{"id":55,"url":"http://api.openstreetmap.org/api/0.6/notes/55.json","reopen_url":"http://api.openstreetmap.org/api/0.6/notes/55/reopen.json","date_created":"2013-04-24 10:57:44 UTC","status":"closed","closed_at":"2013-08-06 12:59:32 UTC","comments":[{"date":"2013-04-24 10:57:44 UTC","action":"opened","text":"Iskon","html":"\u003Cp\u003EIskon\u003C/p\u003E"},{"date":"2013-08-06 12:59:32 UTC","uid":55724,"user":"Valent Turkovic","user_url":"http://www.openstreetmap.org/user/Valent%20Turkovic","action":"closed","text":"","html":"\u003Cp\u003E\u003C/p\u003E"}]}} -------------------------------------------------------------------------------- /OSMKit/Utilities/OSMKConstants.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKitConstants.h 3 | // Pods 4 | // 5 | // Created by David Chiles on 12/11/14. 6 | // 7 | // 8 | 9 | #import 10 | 11 | extern NSString *const OSMKNodeElementName; 12 | extern NSString *const OSMKWayElementName; 13 | extern NSString *const OSMKRelationElementName; 14 | extern NSString *const OSMKTagElementName; 15 | extern NSString *const OSMKWayNodeElementName; 16 | extern NSString *const OSMKRelationMemberElementName; 17 | extern NSString *const OSMKUserElementName; 18 | extern NSString *const OSMKNoteElementName; 19 | extern NSString *const OSMKUserRolesElementName; 20 | extern NSString *const OSMKNoteCommentsElementName; 21 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKComment.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKComment.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface OSMKComment : NSObject 12 | 13 | @property (nonatomic) int64_t noteId; 14 | @property (nonatomic) int64_t userId; 15 | @property (nonatomic,strong) NSString *user; 16 | @property (nonatomic,strong) NSDate *date; 17 | @property (nonatomic,strong) NSString *text; 18 | @property (nonatomic,strong) NSString *action; 19 | 20 | - (id)initWithDictionary:(NSDictionary *)dictionary; 21 | 22 | + (instancetype)commentWithDictionary:(NSDictionary *)dictionary; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /OSMKit/Utilities/OSMKConstants.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKitConstants.m 3 | // Pods 4 | // 5 | // Created by David Chiles on 12/11/14. 6 | // 7 | // 8 | 9 | #import "OSMKConstants.h" 10 | 11 | NSString *const OSMKNodeElementName = @"node"; 12 | NSString *const OSMKWayElementName = @"way"; 13 | NSString *const OSMKRelationElementName = @"relation"; 14 | NSString *const OSMKTagElementName = @"tag"; 15 | NSString *const OSMKWayNodeElementName = @"nd"; 16 | NSString *const OSMKRelationMemberElementName = @"member"; 17 | NSString *const OSMKUserElementName = @"user"; 18 | NSString *const OSMKUserRolesElementName = @"roles"; 19 | NSString *const OSMKNoteElementName = @"note"; 20 | NSString *const OSMKNoteCommentsElementName = @"comments"; 21 | -------------------------------------------------------------------------------- /Tests/OSMKit.xcodeproj/xcuserdata/david.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | OSMKit.xcscheme_^#shared#^_ 8 | 9 | isShown 10 | 11 | orderHint 12 | 0 13 | 14 | 15 | SuppressBuildableAutocreation 16 | 17 | 632C3C9E18FDE815001E8C69 18 | 19 | primary 20 | 21 | 22 | 632C3CB918FDE815001E8C69 23 | 24 | primary 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /Tests/OSMKitTests/OSMKitTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.david.chiles.${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 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKChangeset.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKChangeset.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 6/9/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class OSMKObject; 12 | @class DDXMLElement; 13 | 14 | @interface OSMKChangeset : NSObject 15 | 16 | @property (nonatomic, strong, readonly) NSArray *nodes; 17 | @property (nonatomic, strong, readonly) NSArray *ways; 18 | @property (nonatomic, strong, readonly) NSArray *relations; 19 | @property (nonatomic) int64_t changesetID; 20 | @property (nonatomic, strong) NSDictionary *tags; 21 | 22 | - (instancetype)initWithTags:(NSDictionary *)tags; 23 | 24 | - (void)addElement:(OSMKObject *)element; 25 | - (void)addElements:(NSArray *)elements; 26 | 27 | - (DDXMLElement *)PUTXML; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKBoundingBox.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKBoundingBox.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 6/9/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKBoundingBox.h" 10 | 11 | @implementation OSMKBoundingBox 12 | 13 | - (NSString *)description 14 | { 15 | return [NSString stringWithFormat:@"Left: %f\nRight: %f\nTop: %f\nBottom: %f",self.left,self.right,self.top,self.bottom]; 16 | } 17 | + (id)boundingBoxWithCornersSW:(CLLocationCoordinate2D)southWest NE:(CLLocationCoordinate2D)northEast 18 | { 19 | OSMKBoundingBox * bbox = [[OSMKBoundingBox alloc] init]; 20 | bbox.left = southWest.longitude; 21 | bbox.bottom = southWest.latitude; 22 | bbox.right = northEast.longitude; 23 | bbox.top = northEast.latitude; 24 | return bbox; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /Tests/OSMKitTests/OSMKTestData.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKTestData.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 12/2/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface OSMKTestObject :NSObject 12 | 13 | @property (nonatomic, strong) NSData *data; 14 | @property (nonatomic) NSInteger nodeCount; 15 | @property (nonatomic) NSInteger wayCount; 16 | @property (nonatomic) NSInteger relationCount; 17 | @property (nonatomic) NSInteger noteCount; 18 | @property (nonatomic) NSInteger userCount; 19 | 20 | - (instancetype)initWithData:(NSData *)data; 21 | 22 | + (instancetype)testObjectWithData:(NSData *)data; 23 | 24 | @end 25 | 26 | @interface OSMKTestData : NSObject 27 | 28 | - (void)enumerateXMLDataSources:(void (^)(OSMKTestObject *testObject, BOOL *stop))block; 29 | - (void)enumerateJSONDataSources:(void (^)(OSMKTestObject *testObject, BOOL *stop))block; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /OSMKit.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'OSMKit' 3 | spec.version = '0.2' 4 | spec.license = { :type => 'MIT' } 5 | spec.homepage = 'https://github.com/davidchiles/OSMKit' 6 | spec.authors = { 'David Chiles' => 'dwalterc@gmail.com' } 7 | spec.summary = 'OpenStreetMap library for iOS and OS X' 8 | spec.source = { :git => 'https://github.com/davidchiles/OSMKit', :tag => '0.2' } 9 | spec.requires_arc = true 10 | 11 | spec.platform = :ios, "7.0" 12 | # spec.dependency "SpatialDBKit" 13 | spec.dependency 'AFNetworking', '~> 2.6' 14 | spec.dependency 'TBXML', '~> 1.5' 15 | spec.dependency 'gtm-oauth', '~> 0.0' 16 | spec.dependency 'KissXML', '~> 5.0' 17 | 18 | spec.xcconfig = { 'HEADER_SEARCH_PATHS' => '/usr/include/libxml2' } 19 | 20 | 21 | spec.source_files = 'OSMKit/*.{h,m}','OSMKit/**/*.{h,m}','OSMKit/**/**/*.{h,m}' 22 | spec.public_header_files = 'OSMKit/*.{h}', "OSMKit/**/*.{h}", "OSMKit/**/**/*.{h}" 23 | 24 | end 25 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKRelationMember.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKRelationMember.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKRelationMember.h" 10 | #import "OSMKObject.h" 11 | 12 | @implementation OSMKRelationMember 13 | 14 | 15 | - (instancetype)initWithAttributesDictionary:(NSDictionary *)dictionary 16 | { 17 | if (self = [super init]) { 18 | self.ref = [dictionary[@"ref"] longLongValue]; 19 | NSString *typeString = dictionary[@"type"]; 20 | 21 | self.type = [OSMKObject typeForString:typeString]; 22 | 23 | self.role= dictionary[@"role"]; 24 | } 25 | return self; 26 | } 27 | 28 | 29 | - (id)copyWithZone:(NSZone *)zone 30 | { 31 | OSMKRelationMember *member = [[[self class] allocWithZone:zone] init]; 32 | member.ref = self.ref; 33 | member.type = self.type; 34 | member.role = [self.role copyWithZone:zone]; 35 | 36 | return member; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKNote.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKNote.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import 12 | 13 | @interface OSMKNote : NSObject 14 | 15 | /** This node latitude. (WGS 84 - SRID 4326) */ 16 | @property (nonatomic, readonly)double latitude; 17 | /** This node longitude. (WGS 84 - SRID 4326) */ 18 | @property (nonatomic, readonly)double longitude; 19 | 20 | @property (nonatomic) int64_t osmId; 21 | @property (nonatomic) BOOL isOpen; 22 | @property (nonatomic) CLLocationCoordinate2D coordinate; 23 | @property (nonatomic,strong) NSArray *commentsArray; 24 | @property (nonatomic,strong) NSDate *dateCreated; 25 | @property (nonatomic,strong) NSDate *dateClosed; 26 | 27 | - (id)initWithJSONDictionary:(NSDictionary *)noteDictionary; 28 | 29 | + (instancetype)noteWithJSONDictionary:(NSDictionary *)jsonDictionary; 30 | 31 | + (NSDateFormatter *)defaultDateFormatter; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKUser.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKUser.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface OSMKUser : NSObject 12 | 13 | @property (nonatomic, readonly) int64_t osmId; 14 | @property (nonatomic, strong) NSString *displayName; 15 | @property (nonatomic, strong) NSDate *dateCreated; 16 | @property (nonatomic, strong) NSURL *imageUrl; 17 | @property (nonatomic, strong) NSString *userDescription; 18 | @property (nonatomic) BOOL termsAgreed; 19 | @property (nonatomic) NSInteger changesetCount; 20 | @property (nonatomic) NSInteger traceCount; 21 | @property (nonatomic, strong) NSSet *roles; 22 | 23 | @property (nonatomic) NSInteger receivedBlocks; 24 | @property (nonatomic) NSInteger activeReceivedBlocks; 25 | @property (nonatomic) NSInteger issuedBlocks; 26 | @property (nonatomic) NSInteger activeIssuedBlocks; 27 | 28 | - (instancetype)initWIthOsmId:(int64_t)osmId; 29 | - (instancetype)initWithAttributesDictionary:(NSDictionary *)attributes; 30 | 31 | 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /OSMKit/Storage/OSMKSpatiaLiteStorage.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKSpatialLiteStorage.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/11/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class OSMKObject, OSMKNode, OSMKWay, OSMKRelation, OSMKUser, OSMKNote; 12 | 13 | @interface OSMKSpatiaLiteStorage : NSObject 14 | 15 | @property (nonatomic, strong, readonly) NSString *filePath; 16 | 17 | - (instancetype)initWithFilePath:(NSString *)filePath 18 | overwrite:(BOOL)overwrite; 19 | 20 | - (void)nodeWithOsmId:(int64_t)osmId completion:(void (^)(OSMKNode *node, NSError *error))completionBlock; 21 | - (void)wayWithOsmId:(int64_t)osmId completion:(void (^)(OSMKWay *way, NSError *error))completionBlock; 22 | - (void)relationWithOsmId:(int64_t)osmId completion:(void (^)(OSMKRelation *relation, NSError *error))completionBlock; 23 | - (void)userWithOsmId:(int64_t)osmId completion:(void (^)(OSMKUser *user, NSError *error))completionBlock; 24 | - (void)noteWithOsmId:(int64_t)osmId completion:(void (^)(OSMKNote *note, NSError *error))completionBlock; 25 | 26 | + (instancetype)spatiaLiteStorageWithFilePath:(NSString *)filePath overwrite:(BOOL)overwrite; 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKWay.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKWay.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKWay.h" 10 | #import "DDXMLElement.h" 11 | #import "DDXMLElementAdditions.h" 12 | 13 | @implementation OSMKWay 14 | 15 | 16 | - (DDXMLElement *)DELETEEelentForChangeset:(NSNumber *)changeset 17 | { 18 | DDXMLElement *element = [super DELETEEelementForChangeset:changeset]; 19 | return [self addNodes:element]; 20 | } 21 | 22 | - (DDXMLElement *)PUTElementForChangeset:(NSNumber *)changeset 23 | { 24 | DDXMLElement *element = [super PUTElementForChangeset:changeset]; 25 | return [self addNodes:element]; 26 | } 27 | 28 | - (DDXMLElement *)addNodes:(DDXMLElement *)element; 29 | { 30 | for (NSNumber *nodeID in self.nodes) { 31 | DDXMLElement *nd = [DDXMLElement elementWithName:@"nd"]; 32 | [nd addAttributeWithName:@"ref" stringValue:[nodeID stringValue]]; 33 | [element addChild:nd]; 34 | } 35 | return element; 36 | } 37 | 38 | - (id)copyWithZone:(NSZone *)zone 39 | { 40 | OSMKWay *way = [super copyWithZone:zone]; 41 | way.nodes = [self.nodes copyWithZone:zone]; 42 | 43 | return way; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /OSMKit/Storage/FMDatabase+OSMKitSpatiaLite.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabase+OSMKit.h 3 | // Pods 4 | // 5 | // Created by David Chiles on 12/15/14. 6 | // 7 | // 8 | 9 | #import "FMDatabase.h" 10 | #import 11 | 12 | @class OSMKObject, OSMKNode, OSMKWay, OSMKRelation, OSMKUser, OSMKNote; 13 | 14 | @interface FMDatabase (OSMKitSpatiaLite) 15 | 16 | - (BOOL)osmk_setupDatabaseWithOverwrite:(BOOL)overwrite; 17 | 18 | - (BOOL)osmk_saveNode:(OSMKNode *)node error:(NSError **)error; 19 | - (BOOL)osmk_saveWay:(OSMKWay *)way error:(NSError **)error; 20 | - (BOOL)osmk_saveRelation:(OSMKRelation *)relation error:(NSError **)error; 21 | - (BOOL)osmk_saveUser:(OSMKUser *)user error:(NSError **)error; 22 | - (BOOL)osmk_saveNote:(OSMKNote *)note error:(NSError **)error; 23 | 24 | - (OSMKNode *)osmk_nodeWithOsmId:(int64_t)osmId; 25 | - (OSMKWay *)osmk_wayWithOsmId:(int64_t)osmId; 26 | - (OSMKRelation *)osmk_relationWithOsmId:(int64_t)osmId; 27 | - (OSMKUser *)osmk_userWithOsmId:(int64_t)osmId; 28 | - (OSMKNote *)osmk_noteWithOsmId:(int64_t)osmId; 29 | 30 | - (CLLocationCoordinate2D)osmk_coordinateOfNodeWithId:(int64_t)nodeId; 31 | 32 | + (NSString *)osmk_tableNameForObject:(id)object; 33 | + (NSString *)osmk_tagTableNameForObject:(OSMKObject *)object; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Tests/OSMKit/OSMKit-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.david.chiles.${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 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Tests/OSMKit.xcodeproj/xcshareddata/xcbaselines/632C3CB918FDE815001E8C69.xcbaseline/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | runDestinationsByUUID 6 | 7 | 54F0840A-F1C9-418C-942D-662974703964 8 | 9 | localComputer 10 | 11 | busSpeedInMHz 12 | 100 13 | cpuCount 14 | 1 15 | cpuKind 16 | Intel Core i5 17 | cpuSpeedInMHz 18 | 1700 19 | logicalCPUCoresPerPackage 20 | 4 21 | modelCode 22 | MacBookAir4,2 23 | physicalCPUCoresPerPackage 24 | 2 25 | platformIdentifier 26 | com.apple.platform.macosx 27 | 28 | targetArchitecture 29 | x86_64 30 | targetDevice 31 | 32 | modelCode 33 | iPhone7,2 34 | platformIdentifier 35 | com.apple.platform.iphonesimulator 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /OSMKit/API/OSMKRequestSerializer.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKRequestSerializer.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 6/9/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKRequestSerializer.h" 10 | 11 | #import "GTMOAuthAuthentication.h" 12 | 13 | @interface OSMKRequestSerializer () 14 | 15 | @property (nonatomic, strong) GTMOAuthAuthentication *token; 16 | 17 | @end 18 | 19 | @implementation OSMKRequestSerializer 20 | 21 | - (instancetype)initWithConsumerKey:(NSString *)consumerKey privateKey:(NSString *)privateKey token:(NSString *)token tokenSecret:(NSString *)tokenSecret; 22 | { 23 | if (self = [self init]) { 24 | self.token = [[GTMOAuthAuthentication alloc] initWithSignatureMethod:kGTMOAuthSignatureMethodHMAC_SHA1 consumerKey:consumerKey privateKey:privateKey]; 25 | self.token.token = token; 26 | self.token.tokenSecret = tokenSecret; 27 | } 28 | return self; 29 | } 30 | 31 | - (NSMutableURLRequest *)requestWithMethod:(NSString *)method URLString:(NSString *)URLString parameters:(NSDictionary *)parameters error:(NSError *__autoreleasing *)error 32 | { 33 | NSMutableURLRequest * request = [super requestWithMethod:method URLString:URLString parameters:parameters error:error]; 34 | 35 | if (self.token) { 36 | [self.token authorizeRequest:request]; 37 | } 38 | 39 | return request; 40 | } 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /Tests/OSMKitTests/Data/user.osm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | I consider my "home" area for mapping to be New Westminster and the adjoining parts of Burnaby, as well as UBC and Surrey. I have high resolution imagery sources for Surrey, so if you're interested in mapping there and want them, let me know. 5 | 6 | I maintain [ogr2osm](https://github.com/pnorman/ogr2osm), a program to convert data to .osm format and tags. 7 | 8 | I'm a member of the Data Working Group and deal mainly with imports. I can help with reverting imports or mistakes. 9 | 10 | ## Other accounts 11 | My other accounts are [pnorman_imports](http://www.openstreetmap.org/user/pnorman_imports) and [pnorman redaction revert](http://www.openstreetmap.org/user/pnorman%20redaction%20revert) 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKRelation.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKRelation.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKRelation.h" 10 | #import "OSMKRelationMember.h" 11 | #import "DDXMLElement.h" 12 | #import "DDXMLElementAdditions.h" 13 | 14 | @implementation OSMKRelation 15 | 16 | - (DDXMLElement *)DELETEEelentForChangeset:(NSNumber *)changeset 17 | { 18 | DDXMLElement *element = [super DELETEEelementForChangeset:changeset]; 19 | return [self addMembers:element]; 20 | } 21 | 22 | - (DDXMLElement *)PUTElementForChangeset:(NSNumber *)changeset 23 | { 24 | DDXMLElement *element = [super PUTElementForChangeset:changeset]; 25 | return [self addMembers:element]; 26 | } 27 | 28 | - (DDXMLElement *)addMembers:(DDXMLElement *)element 29 | { 30 | for (OSMKRelationMember *member in self.members) { 31 | DDXMLElement *element = [DDXMLElement elementWithName:@"member"]; 32 | 33 | if ([member.role length]) { 34 | [element addAttributeWithName:@"role" stringValue:member.role]; 35 | } 36 | [element addAttributeWithName:@"type" stringValue:[OSMKObject stringForType:member.type]]; 37 | [element addAttributeWithName:@"ref" stringValue:[@(member.ref) stringValue]]; 38 | } 39 | return element; 40 | } 41 | 42 | - (id)copyWithZone:(NSZone *)zone 43 | { 44 | OSMKRelation *relation = [super copyWithZone:zone]; 45 | relation.members = [self.members copyWithZone:zone]; 46 | 47 | return relation; 48 | } 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Tests/OSMKit.xcworkspace/xcshareddata/OSMKit.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | D2F202E4-AA3D-4987-A384-B0B2792F9502 9 | IDESourceControlProjectName 10 | OSMKit 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | A0D85EFD5F6D959650F1A7F38845945241955B3C 14 | github.com:davidchiles/OSMKit.git 15 | 16 | IDESourceControlProjectPath 17 | Tests/OSMKit.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | A0D85EFD5F6D959650F1A7F38845945241955B3C 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | github.com:davidchiles/OSMKit.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | A0D85EFD5F6D959650F1A7F38845945241955B3C 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | A0D85EFD5F6D959650F1A7F38845945241955B3C 36 | IDESourceControlWCCName 37 | OSMKit 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKComment.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKComment.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKComment.h" 10 | #import "OSMKNote.h" 11 | 12 | @implementation OSMKComment 13 | 14 | - (id)initWithDictionary:(NSDictionary *)dictionary 15 | { 16 | if (self = [self init]) { 17 | NSString *user = dictionary[@"user"]; 18 | if ([user length]) { 19 | self.user = user; 20 | self.userId = [dictionary[@"uid"] longLongValue]; 21 | } 22 | self.text = dictionary[@"text"]; 23 | self.date = [[OSMKNote defaultDateFormatter] dateFromString:dictionary[@"date"]]; 24 | self.action = dictionary[@"action"]; 25 | } 26 | return self; 27 | } 28 | 29 | - (NSDictionary *)jsonDictionary 30 | { 31 | NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; 32 | dictionary[@"user"] = self.user; 33 | dictionary[@"uid"] = @(self.userId); 34 | dictionary[@"text"] = self.text; 35 | dictionary[@"date"] = [[OSMKNote defaultDateFormatter] stringFromDate:self.date]; 36 | 37 | if ([self.action length]) { 38 | dictionary[@"action"] = self.action; 39 | } 40 | 41 | return [dictionary copy]; 42 | } 43 | 44 | #pragma - mark NSCopying 45 | 46 | - (id)copyWithZone:(NSZone *)zone 47 | { 48 | return [[OSMKComment alloc] initWithDictionary:[self jsonDictionary]]; 49 | } 50 | 51 | #pragma - mark Class Methods 52 | 53 | 54 | 55 | + (instancetype)commentWithDictionary:(NSDictionary *)dictionary 56 | { 57 | return [[OSMKComment alloc] initWithDictionary:dictionary]; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /Tests/OSMKit.xcodeproj/project.xcworkspace/xcshareddata/OSMKit.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 9342246B-432E-41D9-AAFA-73F489061B59 9 | IDESourceControlProjectName 10 | OSMKit 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 26D23247-369A-4DEA-B83B-96CA1A03D1AE 14 | ssh://github.com/davidchiles/OSMKit.git 15 | 16 | IDESourceControlProjectPath 17 | Tests/OSMKit.xcodeproj/project.xcworkspace 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 26D23247-369A-4DEA-B83B-96CA1A03D1AE 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | ssh://github.com/davidchiles/OSMKit.git 25 | IDESourceControlProjectVersion 26 | 110 27 | IDESourceControlProjectWCCIdentifier 28 | 26D23247-369A-4DEA-B83B-96CA1A03D1AE 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 26D23247-369A-4DEA-B83B-96CA1A03D1AE 36 | IDESourceControlWCCName 37 | OSMKit 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OSMKit 2 | OSMKit is helpful library for parsing and storing [OpenStreetMap](https://openstreetmpa.org) data in a [spatialite](http://www.gaia-gis.it/gaia-sins/) databse. OSMKit supports nodes, ways, relations, users and notes objects. 3 | 4 | ##How to Get Started 5 | 6 | ###Install 7 | Add it to your Podfile. 8 | 9 | ```ruby 10 | pod 'OSMKit', :git => 'https://github.com/davidchiles/OSMKit' , :tag => '0.2' 11 | ``` 12 | 13 | For Now you'll also have to add: 14 | ```ruby 15 | pod "SpatialDBKit", :git => 'https://github.com/davidchiles/SpatialDBKit' , :branch => 'master' 16 | 17 | pre_install do |installer_representation| 18 | path = Pathname(installer_representation.sandbox.pod_dir("spatialite"))+"src/spatialite/spatialite.c" 19 | 20 | text = File.read(path) 21 | new_text = text.gsub(/#include /, "#include ") 22 | 23 | File.open(path, "w") {|file| file.puts new_text } 24 | 25 | end 26 | ``` 27 | 28 | Then run `pod install`. 29 | 30 | ### Usage 31 | 32 | 33 | ####Parsing 34 | ```objective-c 35 | OSMKTBXMLParser *parser = [[OSMKTBXMLParser alloc] initWithData:data error:&error]; 36 | NSArray *nodes = [parser parseNodes]; 37 | NSArray *ways = [parser parseWays]; 38 | NSArray *relations = [parser parseRelations]; 39 | NSArray *users = [parser parseUsers]; 40 | NSArray *notes = [parser parseNotes]; 41 | ``` 42 | 43 | ####Parsing + Storage 44 | ```objective-c 45 | OSMKImporter *importer = [[OSMKImporter alloc] init]; 46 | [importer setupDatbaseWithPath:path overwrite:YES]; 47 | [importer importXMLData:testObject.data 48 | completion:^{ 49 | NSLog(@"all done"); 50 | } 51 | completionQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)]; 52 | ``` 53 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKUser.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKUser.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKUser.h" 10 | #import "OSMKObject.h" 11 | 12 | @interface OSMKUser () 13 | 14 | @property (nonatomic) int64_t osmId; 15 | 16 | @end 17 | 18 | @implementation OSMKUser 19 | 20 | - (instancetype)initWIthOsmId:(int64_t)osmId 21 | { 22 | if (self = [self init]) { 23 | self.osmId = osmId; 24 | } 25 | return self; 26 | } 27 | 28 | - (instancetype)initWithAttributesDictionary:(NSDictionary *)attributes 29 | { 30 | if (self = [self initWIthOsmId:[attributes[@"id"] longLongValue]]) { 31 | self.displayName = attributes[@"display_name"]; 32 | NSString *timeString = attributes[@"account_created"]; 33 | if ([timeString length]) { 34 | self.dateCreated = [[OSMKObject defaultDateFormatter] dateFromString:timeString]; 35 | } 36 | } 37 | return self; 38 | } 39 | 40 | #pragma - mark NSCopying 41 | 42 | - (id)copyWithZone:(NSZone *)zone 43 | { 44 | OSMKUser *user = [[[self class] allocWithZone:zone] init]; 45 | user.osmId = self.osmId; 46 | user.displayName = [self.displayName copyWithZone:zone]; 47 | user.dateCreated = [self.dateCreated copyWithZone:zone]; 48 | user.imageUrl = [self.imageUrl copyWithZone:zone]; 49 | user.userDescription = [self.userDescription copyWithZone:zone]; 50 | user.termsAgreed = self.termsAgreed; 51 | user.changesetCount = self.changesetCount; 52 | user.traceCount = self.traceCount; 53 | user.roles = [self.roles copyWithZone:zone]; 54 | user.receivedBlocks = self.receivedBlocks; 55 | user.activeReceivedBlocks = self.activeReceivedBlocks; 56 | user.issuedBlocks = self.issuedBlocks; 57 | user.activeIssuedBlocks = self.activeIssuedBlocks; 58 | 59 | return user; 60 | 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKNode.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKNode.h" 10 | 11 | #import "DDXMLElement.h" 12 | #import "DDXMLElementAdditions.h" 13 | 14 | @implementation OSMKNode 15 | 16 | - (instancetype)initWithAttributesDictionary:(NSDictionary *)attributes 17 | { 18 | if (self = [super initWithAttributesDictionary:attributes]) { 19 | double lat = [attributes[@"lat"] doubleValue]; 20 | double lon = [attributes[@"lon"] doubleValue]; 21 | self.coordinate = CLLocationCoordinate2DMake(lat, lon); 22 | 23 | } 24 | return self; 25 | } 26 | 27 | -(NSString*) description { 28 | return [NSString stringWithFormat:@"Node(%lli)%f,%f", self.osmId, self.latitude, self.longitude]; 29 | } 30 | 31 | - (double)latitude 32 | { 33 | return self.coordinate.latitude; 34 | } 35 | 36 | - (double)longitude 37 | { 38 | return self.coordinate.longitude; 39 | } 40 | 41 | - (DDXMLElement *)DELETEEelentForChangeset:(NSNumber *)changeset 42 | { 43 | DDXMLElement *nodeXML = [super DELETEEelementForChangeset:changeset]; 44 | return [self addLatLon:nodeXML]; 45 | } 46 | 47 | - (DDXMLElement *)PUTElementForChangeset:(NSNumber *)changeset 48 | { 49 | DDXMLElement *nodeXML = [super PUTElementForChangeset:changeset]; 50 | return [self addLatLon:nodeXML]; 51 | } 52 | 53 | - (DDXMLElement *)addLatLon:(DDXMLElement *)nodeXML 54 | { 55 | [nodeXML addAttributeWithName:@"lat" stringValue:[@(self.latitude) stringValue]]; 56 | [nodeXML addAttributeWithName:@"lon" stringValue:[@(self.longitude) stringValue]]; 57 | return nodeXML; 58 | } 59 | 60 | #pragma NSCopying Methods 61 | 62 | - (id)copyWithZone:(NSZone *)zone 63 | { 64 | OSMKNode *node = [super copyWithZone:zone]; 65 | node.coordinate = self.coordinate; 66 | 67 | return node; 68 | } 69 | 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKObject.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKObject.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class DDXMLElement; 12 | 13 | typedef NS_ENUM(int, OSMKElementType) { 14 | OSMKElementTypeNone = 0, 15 | OSMKElementTypeNode = 1, 16 | OSMKElementTypeWay = 2, 17 | OSMKElementTypeRelation = 3 18 | }; 19 | 20 | typedef NS_ENUM(NSInteger, OSMKElementAction) { 21 | OSMKElementActionNone = 0, 22 | OSMKElementActionNew = 1, 23 | OSMKElementActionModified = 2, 24 | OSMKElementActionDelete = 3 25 | }; 26 | 27 | @interface OSMKObject : NSObject 28 | 29 | @property (nonatomic) int64_t osmId; 30 | @property (nonatomic) int version; 31 | @property (nonatomic) int64_t changeset; 32 | @property (nonatomic) int64_t userId; 33 | @property (nonatomic, getter = isVisible) BOOL visible; 34 | @property (nonatomic) OSMKElementAction action; 35 | 36 | @property (nonatomic, strong) NSDictionary *tags; 37 | @property (nonatomic, strong) NSString *user; 38 | 39 | //Use NSString to set and will be parsed upon getting from the timeStamp and stored 40 | //Improves parsing time significantly because the cost of NSDateFormatter 41 | @property (nonatomic, strong) NSString *timeStampString; 42 | @property (nonatomic, strong, readonly) NSDate *timeStamp; 43 | 44 | - (instancetype)initWithId:(int64_t)osmId; 45 | - (instancetype)initWithAttributesDictionary:(NSDictionary *)attributes; 46 | 47 | - (DDXMLElement *)PUTElementForChangeset:(NSNumber *)changeset; 48 | - (DDXMLElement *)DELETEEelementForChangeset:(NSNumber *)changeset; 49 | 50 | + (NSArray *)tagXML:(NSDictionary *)tags; 51 | 52 | + (NSDateFormatter *)defaultDateFormatter; 53 | 54 | + (instancetype)objectForType:(OSMKElementType)type elementId:(int64_t)elementId; 55 | 56 | + (NSString *)stringForType:(OSMKElementType)type; 57 | + (OSMKElementType)typeForString:(NSString *)string; 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /Tests/OSMKit.xcodeproj/xcshareddata/xcbaselines/632C3CB918FDE815001E8C69.xcbaseline/54F0840A-F1C9-418C-942D-662974703964.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | classNames 6 | 7 | OSMKImporterTests 8 | 9 | testPerformanceExample 10 | 11 | com.apple.XCTPerformanceMetric_WallClockTime 12 | 13 | baselineAverage 14 | 1.6 15 | baselineIntegrationDisplayName 16 | Local Baseline 17 | 18 | 19 | 20 | OSMKParserTests 21 | 22 | testTBXMLPerformance 23 | 24 | com.apple.XCTPerformanceMetric_WallClockTime 25 | 26 | baselineAverage 27 | 3.34 28 | baselineIntegrationDisplayName 29 | Local Baseline 30 | 31 | 32 | 33 | OSMKitTests 34 | 35 | testNSJSONPerformance 36 | 37 | com.apple.XCTPerformanceMetric_WallClockTime 38 | 39 | baselineAverage 40 | 0.03 41 | baselineIntegrationDisplayName 42 | Local Baseline 43 | 44 | 45 | testNSXMLPerformance 46 | 47 | com.apple.XCTPerformanceMetric_WallClockTime 48 | 49 | baselineAverage 50 | 7.66 51 | baselineIntegrationDisplayName 52 | Local Baseline 53 | 54 | 55 | testTBXMLPerformance 56 | 57 | com.apple.XCTPerformanceMetric_WallClockTime 58 | 59 | baselineAverage 60 | 7.37 61 | baselineIntegrationDisplayName 62 | Local Baseline 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKChangeset.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKChangeset.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 6/9/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKChangeset.h" 10 | 11 | #import "OSMKObject.h" 12 | #import "OSMKNode.h" 13 | #import "OSMKWay.h" 14 | #import "OSMKRelation.h" 15 | #import "DDXML.h" 16 | 17 | @interface OSMKChangeset () 18 | 19 | @property (nonatomic, strong) NSArray *nodes; 20 | @property (nonatomic, strong) NSArray *ways; 21 | @property (nonatomic, strong) NSArray *relations; 22 | 23 | @end 24 | 25 | @implementation OSMKChangeset 26 | 27 | - (instancetype)initWithTags:(NSDictionary *)tags 28 | { 29 | if (self = [self init]) { 30 | self.tags = tags; 31 | } 32 | return self; 33 | } 34 | 35 | - (NSArray *)nodes 36 | { 37 | if (!_nodes) { 38 | _nodes = [NSArray array]; 39 | } 40 | return _nodes; 41 | } 42 | 43 | - (NSArray *)ways 44 | { 45 | if (!_ways) { 46 | _ways = [NSArray array]; 47 | } 48 | return _ways; 49 | } 50 | 51 | - (NSArray *)relations 52 | { 53 | if (!_relations) { 54 | _relations = [NSArray array]; 55 | } 56 | return _relations; 57 | } 58 | 59 | - (void)addElement:(OSMKObject *)element 60 | { 61 | if (!element) { 62 | return; 63 | } 64 | 65 | if ([element isKindOfClass:[OSMKNode class]]) { 66 | self.nodes = [self.nodes arrayByAddingObject:element]; 67 | } 68 | else if ([element isKindOfClass:[OSMKWay class]]) { 69 | self.ways = [self.ways arrayByAddingObject:element]; 70 | } 71 | else if ([element isKindOfClass:[OSMKRelation class]]) { 72 | self.relations = [self.relations arrayByAddingObject:element]; 73 | } 74 | } 75 | 76 | - (void)addElements:(NSArray *)elements 77 | { 78 | [elements enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 79 | [self addElement:obj]; 80 | }]; 81 | } 82 | 83 | - (DDXMLElement *)PUTXML { 84 | DDXMLElement *element = [[DDXMLElement alloc] initWithName:@"changeset"]; 85 | [element setChildren:[OSMKObject tagXML:self.tags]]; 86 | return element; 87 | } 88 | 89 | @end 90 | -------------------------------------------------------------------------------- /OSMKit/Parser/OSMKNSJSONSerialization.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKNSJSONSerializationParser.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/21/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKNSJSONSerialization.h" 10 | #import "OSMKNote.h" 11 | 12 | @interface OSMKNSJSONSerialization () 13 | 14 | @property (nonatomic, strong) NSData *data; 15 | @property (nonatomic, strong) NSInputStream *inputStream; 16 | 17 | @property (nonatomic, strong) NSDictionary *serializedDictionary; 18 | 19 | @end 20 | 21 | @implementation OSMKNSJSONSerialization 22 | - (instancetype)initWithData:(NSData *)data 23 | { 24 | if (self = [self init]) { 25 | self.data = data; 26 | } 27 | return self; 28 | } 29 | 30 | - (id)initWithStream:(NSInputStream *)inputStream { 31 | if (self = [self init]) { 32 | self.inputStream = inputStream; 33 | } 34 | return self; 35 | } 36 | 37 | - (NSDictionary *)serializedDictionary 38 | { 39 | if (!_serializedDictionary) { 40 | if (self.inputStream) { 41 | _serializedDictionary = [NSJSONSerialization JSONObjectWithStream:self.inputStream options:0 error:nil]; 42 | } 43 | else { 44 | _serializedDictionary = [NSJSONSerialization JSONObjectWithData:self.data options:0 error:nil]; 45 | } 46 | } 47 | return _serializedDictionary; 48 | } 49 | 50 | - (NSArray *)parseNotes 51 | { 52 | NSMutableArray *foundNotes = [NSMutableArray new]; 53 | if ([self.serializedDictionary[@"type"] isEqualToString:@"FeatureCollection"]) { 54 | NSArray * notes = self.serializedDictionary[@"features"]; 55 | [notes enumerateObjectsUsingBlock:^(NSDictionary *noteDictionary, NSUInteger idx, BOOL *stop) { 56 | 57 | OSMKNote *note = [OSMKNote noteWithJSONDictionary:noteDictionary]; 58 | [foundNotes addObject:note]; 59 | }]; 60 | } 61 | else if ([self.serializedDictionary[@"type"] isEqualToString:@"Feature"]) 62 | { 63 | OSMKNote *note = [OSMKNote noteWithJSONDictionary:self.serializedDictionary]; 64 | [foundNotes addObject:note]; 65 | } 66 | 67 | if (![foundNotes count]) { 68 | foundNotes = nil; 69 | } 70 | return foundNotes; 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Tests/OSMKitTests/OSMKImporterTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKImporterTests.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 1/13/15. 6 | // Copyright (c) 2015 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OSMKTestData.h" 11 | #import "OSMKImporter.h" 12 | 13 | @interface OSMKImporterTests : XCTestCase 14 | 15 | @property (nonatomic, strong) OSMKTestData *testData; 16 | @property (nonatomic, strong) dispatch_queue_t completionQueue; 17 | 18 | @property (nonatomic, strong) NSString *documentsPath; 19 | 20 | @end 21 | 22 | @implementation OSMKImporterTests 23 | 24 | - (void)setUp { 25 | [super setUp]; 26 | NSString *queueLabel = [NSString stringWithFormat:@"%@-completion",NSStringFromClass([self class])]; 27 | self.completionQueue = dispatch_queue_create([queueLabel UTF8String], 0); 28 | self.testData = [[OSMKTestData alloc] init]; 29 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 30 | self.documentsPath = [paths firstObject]; 31 | } 32 | 33 | - (void)tearDown { 34 | // Put teardown code here. This method is called after the invocation of each test method in the class. 35 | [super tearDown]; 36 | } 37 | 38 | - (void)testImport { 39 | 40 | __block int count = 0; 41 | [self.testData enumerateXMLDataSources:^(OSMKTestObject *testObject, BOOL *stop) { 42 | XCTestExpectation *expectation = [self expectationWithDescription:[NSString stringWithFormat:@"import-%@",testObject]]; 43 | OSMKImporter *importer = [[OSMKImporter alloc] init]; 44 | NSString *path = [self.documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"db%d.sqlite",count]]; 45 | [importer setupDatbaseWithPath:path overwrite:YES]; 46 | [importer importXMLData:testObject.data 47 | completion:^{ 48 | NSLog(@"all done"); 49 | [expectation fulfill]; 50 | } 51 | completionQueue:self.completionQueue]; 52 | count++; 53 | }]; 54 | 55 | 56 | 57 | [self waitForExpectationsWithTimeout:1000000 handler:^(NSError *error) { 58 | NSLog(@"Timeout Error: %@",error); 59 | }]; 60 | } 61 | 62 | - (void)testPerformanceExample { 63 | // This is an example of a performance test case. 64 | [self measureBlock:^{ 65 | [self testImport]; 66 | }]; 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Tests/OSMKit/OSMKAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKAppDelegate.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKAppDelegate.h" 10 | #import "OSMKTestImportViewController.h" 11 | 12 | @implementation OSMKAppDelegate 13 | 14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 15 | { 16 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 17 | 18 | OSMKTestImportViewController *viewController = [[OSMKTestImportViewController alloc] init]; 19 | UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController]; 20 | 21 | 22 | self.window.rootViewController = navController; 23 | self.window.backgroundColor = [UIColor whiteColor]; 24 | [self.window makeKeyAndVisible]; 25 | return YES; 26 | } 27 | 28 | - (void)applicationWillResignActive:(UIApplication *)application 29 | { 30 | // 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. 31 | // 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. 32 | } 33 | 34 | - (void)applicationDidEnterBackground:(UIApplication *)application 35 | { 36 | // 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. 37 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 38 | } 39 | 40 | - (void)applicationWillEnterForeground:(UIApplication *)application 41 | { 42 | // 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. 43 | } 44 | 45 | - (void)applicationDidBecomeActive:(UIApplication *)application 46 | { 47 | // 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. 48 | } 49 | 50 | - (void)applicationWillTerminate:(UIApplication *)application 51 | { 52 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /OSMKit/Parser/TBXML+OSMKit.m: -------------------------------------------------------------------------------- 1 | // 2 | // TBXML+OSMKit.m 3 | // Pods 4 | // 5 | // Created by David Chiles on 12/11/14. 6 | // 7 | // 8 | 9 | #import "TBXML+OSMKit.h" 10 | #import "OSMKConstants.h" 11 | #import "OSMKRelationMember.h" 12 | 13 | @implementation TBXML (OSMKit) 14 | 15 | + (NSDictionary *)osmk_attributesDictionaryWithElement:(TBXMLElement *)element 16 | { 17 | NSMutableDictionary *elementDict = [[NSMutableDictionary alloc] init]; 18 | 19 | TBXMLAttribute *attribute = element->firstAttribute; 20 | while (attribute) { 21 | [elementDict setObject:[TBXML attributeValue:attribute] forKey:[TBXML attributeName:attribute]]; 22 | attribute = attribute->next; 23 | } 24 | return elementDict; 25 | } 26 | 27 | + (NSDictionary *)osmk_tagsDictioanryWithElement:(TBXMLElement *)element 28 | { 29 | TBXMLElement* tagElement = [TBXML childElementNamed:@"tag" parentElement:element]; 30 | NSMutableDictionary * dictionary = [NSMutableDictionary dictionary]; 31 | 32 | while (tagElement) 33 | { 34 | NSString* key = [TBXML valueOfAttributeNamed:@"k" forElement:tagElement]; 35 | NSString* value = [TBXML valueOfAttributeNamed:@"v" forElement:tagElement]; 36 | 37 | [dictionary setObject:value forKey:key]; 38 | tagElement = [TBXML nextSiblingNamed:@"tag" searchFromElement:tagElement]; 39 | } 40 | 41 | return dictionary; 42 | } 43 | 44 | + (NSArray *)osmk_wayNodesWithElement:(TBXMLElement *)element 45 | { 46 | TBXMLElement *ndElement = [TBXML childElementNamed:@"nd" parentElement:element]; 47 | NSMutableArray *mutableArray = [NSMutableArray array]; 48 | 49 | while (ndElement) { 50 | 51 | NSNumber *ref = @([[TBXML valueOfAttributeNamed:@"ref" forElement:ndElement] longLongValue]); 52 | [mutableArray addObject:ref]; 53 | 54 | 55 | ndElement = [TBXML nextSiblingNamed:@"nd" searchFromElement:ndElement]; 56 | } 57 | return mutableArray; 58 | } 59 | 60 | + (NSArray *)osmk_relationMembersWithElement:(TBXMLElement *)element 61 | { 62 | TBXMLElement *memberElement = [TBXML childElementNamed:OSMKRelationMemberElementName parentElement:element]; 63 | NSMutableArray *mutableArray = [NSMutableArray array]; 64 | 65 | while (memberElement) { 66 | OSMKRelationMember *member = [[OSMKRelationMember alloc] initWithAttributesDictionary:[self osmk_attributesDictionaryWithElement:memberElement]]; 67 | if (member) { 68 | [mutableArray addObject:member]; 69 | } 70 | memberElement = [TBXML nextSiblingNamed:OSMKRelationMemberElementName searchFromElement:memberElement]; 71 | } 72 | return mutableArray; 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /OSMKit/API/OSMKAPIClient.h: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKAPIClient.h 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 6/9/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "AFNetworking.h" 12 | 13 | @class OSMKChangeset; 14 | @class OSMKObject; 15 | @class OSMKNote; 16 | @class OSMKComment; 17 | @class DDXMLElement; 18 | @class OSMKUser; 19 | 20 | extern NSString *const OSMKBaseURLString; 21 | extern NSString *const OSMKTestBaseURLString; 22 | 23 | @interface OSMKAPIClient : AFHTTPRequestOperationManager 24 | 25 | /** 26 | * 27 | * 28 | */ 29 | - (instancetype)initWithConsumerKey:(NSString *)consumerKey privateKey:(NSString *)privateKey token:(NSString *)token tokenSecret:(NSString *)tokenSecret; 30 | 31 | ////// Download ////// 32 | 33 | -(void)downloadDataWithSW:(CLLocationCoordinate2D)southWest NE:(CLLocationCoordinate2D)northEast 34 | success:(void (^)(NSXMLParser* xmlParser))success 35 | failure:(void (^)(NSError *error))failure; 36 | 37 | -(void)downloadNotesWithSW:(CLLocationCoordinate2D)southWest NE:(CLLocationCoordinate2D)northEast 38 | success:(void (^)(id response))success 39 | failure:(void (^)(NSError *error))failure; 40 | 41 | 42 | ////// Upload ////// 43 | 44 | - (void)openChangeset:(OSMKChangeset *)changeset 45 | success:(void (^)(int64_t changesetID))success 46 | failure: (void (^)(NSError * error))failure; 47 | 48 | - (void)uploadChangeset:(OSMKChangeset *)changeset 49 | success:(void (^)(NSArray *completedNodes, NSArray *completedWays, NSArray *completedRelations))success 50 | failure:(void (^)(OSMKObject * element, NSError * error))failure; 51 | 52 | -(void)closeChangeset:(int64_t) changesetNumber 53 | success:(void (^)(id response))success 54 | failure:(void (^)(NSError * error))failure; 55 | 56 | ////// Notes ////// 57 | 58 | -(void)createNewNote:(OSMKNote *)note 59 | success:(void (^)(NSData * response))success 60 | failure:(void (^)(NSError *error))failure; 61 | 62 | -(void)createNewComment:(OSMKComment *)comment 63 | withNote:(OSMKNote *)note 64 | success:(void (^)(id JSON))success 65 | failure:(void (^)(NSError *error))failure; 66 | 67 | -(void)closeNote:(OSMKNote *)note 68 | withComment:(OSMKComment *)comment 69 | success:(void (^)(id JSON))success 70 | failure:(void (^)(NSError *error))failure; 71 | 72 | -(void)reopenNote:(OSMKNote *)note 73 | withComment:(OSMKComment *)comment 74 | success:(void (^)(NSData * response))success 75 | failure:(void (^)(NSError *error))failure; 76 | 77 | 78 | ////////// User ////////////// 79 | - (void)fetchCurrentUserWithComletion:(void (^)(id response,NSError *error))completionBlock; 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /Tests/OSMKitTests/OSMKAPITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKAPITests.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 6/9/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OSMKAPIClient.h" 11 | #import 12 | #import "OSMKChangeset.h" 13 | #import "DDXML.h" 14 | 15 | @interface OSMKAPITests : XCTestCase 16 | 17 | @property (nonatomic, strong) OSMKAPIClient *apiClient; 18 | 19 | @end 20 | 21 | @implementation OSMKAPITests 22 | 23 | - (void)setUp 24 | { 25 | [super setUp]; 26 | self.apiClient = [[OSMKAPIClient alloc] init]; 27 | } 28 | 29 | - (void)tearDown 30 | { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | self.apiClient = nil; 34 | } 35 | /* 36 | - (void)testDownloadData 37 | { 38 | TRVSMonitor *monitor = [[TRVSMonitor alloc] init]; 39 | CLLocationCoordinate2D southWest = CLLocationCoordinate2DMake(37.87128, -122.26965); 40 | CLLocationCoordinate2D northEast = CLLocationCoordinate2DMake(37.87282, -122.26688); 41 | 42 | __block NSError *error = nil; 43 | __block NSXMLParser *xmlParser = nil; 44 | 45 | [self.apiClient downloadDataWithSW:southWest NE:northEast success:^(NSXMLParser *parser) { 46 | 47 | xmlParser = parser; 48 | [monitor signal]; 49 | 50 | } failure:^(NSError *error) { 51 | 52 | error = error; 53 | [monitor signal]; 54 | }]; 55 | 56 | [monitor waitWithTimeout:100.0]; 57 | 58 | XCTAssertNotNil(xmlParser, @"Could not download data"); 59 | XCTAssertNil(error, @"Found Error %@",error); 60 | } 61 | 62 | - (void)testDownloadNotes 63 | { 64 | TRVSMonitor *monitor = [[TRVSMonitor alloc] init]; 65 | CLLocationCoordinate2D southWest = CLLocationCoordinate2DMake(37.7668, -122.4374); 66 | CLLocationCoordinate2D northEast = CLLocationCoordinate2DMake(37.8132, -122.3485); 67 | 68 | 69 | __block id responseObject = nil; 70 | __block NSError *responseError = nil; 71 | [self.apiClient downloadNotesWithSW:southWest NE:northEast success:^(id response) { 72 | responseObject = response; 73 | [monitor signal]; 74 | } failure:^(NSError *error) { 75 | responseError = error; 76 | [monitor signal]; 77 | }]; 78 | 79 | [monitor waitWithTimeout:100.0]; 80 | 81 | XCTAssertNil(responseError, @"Error fetching notes %@",responseError); 82 | XCTAssertNotNil(responseObject, @"Could not find data"); 83 | } 84 | 85 | - (void)testChangesetXML 86 | { 87 | OSMKChangeset *changeset = [[OSMKChangeset alloc] initWithTags:@{@"created_by":@"me",@"comment":@"hello bob ēį"}]; 88 | DDXMLElement *element = [changeset PUTXML]; 89 | NSString *string = [element XMLStringWithOptions:DDXMLNodeCompactEmptyElement]; 90 | 91 | XCTAssert([string length] > 0, @"No element created"); 92 | } 93 | */ 94 | 95 | @end 96 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKNote.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKNote.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKNote.h" 10 | #import "OSMKObject.h" 11 | #import "OSMKComment.h" 12 | 13 | @implementation OSMKNote 14 | 15 | 16 | - (id)initWithJSONDictionary:(NSDictionary *)noteDictionary 17 | { 18 | if (self = [self init]) { 19 | if ([noteDictionary count]) { 20 | 21 | NSDictionary * propertiesDictionary = noteDictionary[@"properties"]; 22 | self.osmId = [propertiesDictionary[@"id"] longLongValue]; 23 | NSArray *coordinatesArray = noteDictionary[@"geometry"][@"coordinates"]; 24 | if ([coordinatesArray count] == 2) { 25 | self.coordinate = CLLocationCoordinate2DMake([coordinatesArray[1] doubleValue], [coordinatesArray[0] doubleValue]); 26 | } 27 | 28 | NSString * statusString = (NSString *)propertiesDictionary[@"status"]; 29 | self.isOpen = [statusString isEqualToString:@"open"]; 30 | self.dateCreated = [[OSMKNote defaultDateFormatter] dateFromString:propertiesDictionary[@"date_created"]]; 31 | self.dateClosed = [[OSMKNote defaultDateFormatter] dateFromString:propertiesDictionary[@"closed_at"]]; 32 | 33 | __block NSMutableArray * newComments = [NSMutableArray array]; 34 | NSArray * comments = (NSArray *)propertiesDictionary[@"comments"]; 35 | [comments enumerateObjectsUsingBlock:^(NSDictionary *dictionary, NSUInteger idx, BOOL *stop) { 36 | OSMKComment *comment = [[OSMKComment alloc] initWithDictionary:dictionary]; 37 | 38 | [newComments addObject:comment]; 39 | }]; 40 | self.commentsArray = newComments; 41 | } 42 | } 43 | return self; 44 | } 45 | 46 | - (double)latitude 47 | { 48 | return self.coordinate.latitude; 49 | } 50 | 51 | - (double)longitude 52 | { 53 | return self.coordinate.longitude; 54 | } 55 | 56 | #pragma - mark NSCopying 57 | 58 | - (id)copyWithZone:(NSZone *)zone 59 | { 60 | OSMKNote *note = [[OSMKNote allocWithZone:zone] init]; 61 | note.coordinate = self.coordinate; 62 | note.osmId = self.osmId; 63 | note.isOpen = self.isOpen; 64 | note.dateCreated = [self.dateCreated copyWithZone:zone]; 65 | note.dateClosed = [self.dateClosed copyWithZone:zone]; 66 | note.commentsArray = [self.commentsArray copyWithZone:zone]; 67 | 68 | return note; 69 | } 70 | 71 | #pragma - mark Class Methods 72 | 73 | + (instancetype)noteWithJSONDictionary:(NSDictionary *)noteDictionary 74 | { 75 | return [[OSMKNote alloc] initWithJSONDictionary:noteDictionary]; 76 | } 77 | 78 | + (NSDateFormatter *)defaultDateFormatter 79 | { 80 | static NSDateFormatter *dateFormatter = nil; 81 | 82 | static dispatch_once_t onceToken; 83 | dispatch_once(&onceToken, ^{ 84 | dateFormatter = [[NSDateFormatter alloc] init]; 85 | [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss z"]; 86 | }); 87 | 88 | return dateFormatter; 89 | } 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /Tests/OSMKit/OSMKTestImportViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKTestImportViewController.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 1/15/15. 6 | // Copyright (c) 2015 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKTestImportViewController.h" 10 | #import "OSMKImporter.h" 11 | #import "OSMKTestResult.h" 12 | 13 | @interface OSMKTestImportViewController () 14 | 15 | @property (nonatomic, strong) OSMKImporter *importer; 16 | @property (nonatomic, strong) NSArray *results; 17 | @property (nonatomic, strong) UITableView *tableView; 18 | 19 | @end 20 | 21 | @implementation OSMKTestImportViewController 22 | 23 | - (void)viewDidLoad 24 | { 25 | [super viewDidLoad]; 26 | 27 | UIBarButtonItem *runTestBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Run Test" style:UIBarButtonItemStylePlain target:self action:@selector(runTestImport:)]; 28 | self.navigationItem.rightBarButtonItem = runTestBarButtonItem; 29 | 30 | self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; 31 | self.tableView.delegate = self; 32 | self.tableView.dataSource = self; 33 | 34 | [self.view addSubview:self.tableView]; 35 | 36 | self.importer = [[OSMKImporter alloc] init]; 37 | NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 38 | NSString *documentsPath = [paths firstObject]; 39 | NSString *databasePath = [documentsPath stringByAppendingPathComponent:@"db.sqlite"]; 40 | [self.importer setupDatbaseWithPath:databasePath overwrite:YES]; 41 | 42 | } 43 | 44 | - (NSArray *)results 45 | { 46 | if (!_results) { 47 | _results = @[]; 48 | } 49 | return _results; 50 | } 51 | 52 | - (void)runTestImport:(id)sender 53 | { 54 | NSString *path = [[NSBundle mainBundle] pathForResource:@"berkeley" ofType:@"osm"]; 55 | NSData *xmlData = [NSData dataWithContentsOfFile:path]; 56 | NSDate *startDate = [NSDate date]; 57 | 58 | [self.importer importXMLData:xmlData completion:^{ 59 | NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:startDate]; 60 | 61 | OSMKTestResult *testResult = [[OSMKTestResult alloc] init]; 62 | testResult.iterations = 1; 63 | testResult.duration = duration; 64 | testResult.testName = @"Import"; 65 | 66 | self.results = [self.results arrayByAddingObject:testResult]; 67 | [self.tableView reloadData]; 68 | 69 | 70 | } completionQueue:dispatch_get_main_queue()]; 71 | } 72 | 73 | #pragma - mark UITableViewDataSource Methods 74 | 75 | ////// Required ////// 76 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 77 | { 78 | return [self.results count]; 79 | } 80 | 81 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 82 | { 83 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; 84 | if (!cell) { 85 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"cell"]; 86 | } 87 | 88 | OSMKTestResult *result = self.results[indexPath.row]; 89 | 90 | cell.textLabel.text = result.testName; 91 | cell.detailTextLabel.text = [NSString stringWithFormat:@"%f",result.duration]; 92 | 93 | cell.selectionStyle = UITableViewCellSelectionStyleNone; 94 | 95 | return cell; 96 | } 97 | 98 | @end 99 | -------------------------------------------------------------------------------- /Tests/OSMKitTests/OSMKTestData.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKTestData.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 12/2/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKTestData.h" 10 | 11 | @implementation OSMKTestObject 12 | 13 | - (instancetype)init 14 | { 15 | if (self = [super init]) { 16 | self.nodeCount = 0; 17 | self.wayCount = 0; 18 | self.relationCount = 0; 19 | self.userCount = 0; 20 | self.noteCount = 0; 21 | } 22 | return self; 23 | } 24 | 25 | - (instancetype)initWithData:(NSData *)data 26 | { 27 | if (self = [self init]) { 28 | self.data = data; 29 | } 30 | return self; 31 | } 32 | 33 | + (instancetype)testObjectWithData:(NSData *)data 34 | { 35 | NSAssert([data length] > 0, @"Data cannote be empty"); 36 | return [[self alloc] initWithData:data]; 37 | } 38 | 39 | @end 40 | 41 | @interface OSMKTestData () 42 | 43 | @property (nonatomic, strong) NSArray *xmlDataArray; 44 | @property (nonatomic, strong) NSArray *jsonDataArray; 45 | 46 | @end 47 | 48 | @implementation OSMKTestData 49 | 50 | - (instancetype)init 51 | { 52 | if (self = [super init]) { 53 | 54 | self.xmlDataArray = @[]; 55 | self.jsonDataArray = @[]; 56 | 57 | OSMKTestObject *testObject = [OSMKTestObject testObjectWithData:[self dataForResource:@"berkeley" ofType:@"osm"]]; 58 | testObject.nodeCount = 51654; 59 | testObject.wayCount = 6594; 60 | testObject.relationCount = 231; 61 | 62 | self.xmlDataArray = [self.xmlDataArray arrayByAddingObject:testObject]; 63 | 64 | testObject = [OSMKTestObject testObjectWithData:[self dataForResource:@"small_berkeley" ofType:@"osm"]]; 65 | testObject.nodeCount = 1625; 66 | testObject.wayCount = 254; 67 | testObject.relationCount = 70; 68 | 69 | self.xmlDataArray = [self.xmlDataArray arrayByAddingObject:testObject]; 70 | 71 | testObject = [OSMKTestObject testObjectWithData:[self dataForResource:@"user" ofType:@"osm"]]; 72 | testObject.userCount = 1; 73 | 74 | self.xmlDataArray = [self.xmlDataArray arrayByAddingObject:testObject]; 75 | 76 | testObject = [OSMKTestObject testObjectWithData:[self dataForResource:@"notes" ofType:@"xml"]]; 77 | testObject.noteCount = 100; 78 | 79 | self.xmlDataArray = [self.xmlDataArray arrayByAddingObject:testObject]; 80 | 81 | //JSON 82 | testObject = [OSMKTestObject testObjectWithData:[self dataForResource:@"notes" ofType:@"json"]]; 83 | testObject.noteCount = 100; 84 | 85 | self.jsonDataArray = [self.jsonDataArray arrayByAddingObject:testObject]; 86 | 87 | testObject = [OSMKTestObject testObjectWithData:[self dataForResource:@"note" ofType:@"json"]]; 88 | testObject.noteCount = 1; 89 | 90 | self.jsonDataArray = [self.jsonDataArray arrayByAddingObject:testObject]; 91 | } 92 | return self; 93 | } 94 | 95 | - (NSData *)dataForResource:(NSString *)resource ofType:(NSString *)type 96 | { 97 | NSString *path = [[NSBundle mainBundle] pathForResource:resource ofType:type]; 98 | if (path) { 99 | NSData *data = [NSData dataWithContentsOfFile:path]; 100 | return data; 101 | } 102 | return nil; 103 | } 104 | 105 | - (void)addPathForResource:(NSString *)resource ofType:(NSString *)type 106 | { 107 | NSString *path = [[NSBundle mainBundle] pathForResource:resource ofType:type]; 108 | if (path) { 109 | NSData *data = [NSData dataWithContentsOfFile:path]; 110 | if (data) { 111 | if ([type isEqualToString:@"json"]) { 112 | self.jsonDataArray = [self.jsonDataArray arrayByAddingObject:data]; 113 | } 114 | else { 115 | self.xmlDataArray = [self.xmlDataArray arrayByAddingObject:data]; 116 | } 117 | } 118 | } 119 | } 120 | - (void)enumerateJSONDataSources:(void (^)(OSMKTestObject *, BOOL *))block 121 | { 122 | if (!block) { 123 | return; 124 | } 125 | 126 | [self.jsonDataArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 127 | if ([obj isKindOfClass:[OSMKTestObject class]]) { 128 | block(obj,stop); 129 | } 130 | }]; 131 | } 132 | 133 | - (void)enumerateXMLDataSources:(void (^)(OSMKTestObject *, BOOL *))block 134 | { 135 | if (!block) { 136 | return; 137 | } 138 | 139 | [self.xmlDataArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 140 | if ([obj isKindOfClass:[OSMKTestObject class]]) { 141 | block(obj,stop); 142 | } 143 | }]; 144 | } 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /Tests/OSMKitTests/OSMKParserTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKitTests.m 3 | // OSMKitTests 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OSMKNSJSONSerialization.h" 11 | #import "FMDB.h" 12 | #import "OSMKTBXMLParser.h" 13 | #import "OSMKTestData.h" 14 | 15 | @interface OSMKParserTests : XCTestCase 16 | 17 | @property (nonatomic, strong) OSMKTestData *testData; 18 | 19 | @end 20 | 21 | @implementation OSMKParserTests 22 | 23 | - (void)setUp 24 | { 25 | [super setUp]; 26 | 27 | self.testData = [[OSMKTestData alloc] init]; 28 | } 29 | 30 | - (void)testTBXMLParser 31 | { 32 | [self.testData enumerateXMLDataSources:^(OSMKTestObject *testObject, BOOL *stop) { 33 | [self testTBXMLParseNodesWithTestObject:testObject]; 34 | [self testTBXMLParseWaysWithTestObject:testObject]; 35 | [self testTBXMLParseRelationsWithTestObject:testObject]; 36 | [self testTBXMLParseNotesWithTestObject:testObject]; 37 | [self testTBXMLParseUsersWithTestObject:testObject]; 38 | }]; 39 | } 40 | 41 | - (void)testTBXMLParseNodesWithTestObject:(OSMKTestObject *)testObject 42 | { 43 | NSError *error = nil; 44 | OSMKTBXMLParser *parser = [[OSMKTBXMLParser alloc] initWithData:testObject.data error:&error]; 45 | NSArray *nodes = [parser parseNodes]; 46 | XCTAssertEqual([nodes count], testObject.nodeCount, @"Node not equal"); 47 | XCTAssertNil(error,@"Found Error"); 48 | } 49 | 50 | - (void)testTBXMLParseWaysWithTestObject:(OSMKTestObject *)testObject 51 | { 52 | NSError *error = nil; 53 | OSMKTBXMLParser *parser = [[OSMKTBXMLParser alloc] initWithData:testObject.data error:&error]; 54 | NSArray *ways = [parser parseWays]; 55 | XCTAssertEqual([ways count], testObject.wayCount, @"Way count not equal"); 56 | XCTAssertNil(error,@"Found Error"); 57 | } 58 | 59 | - (void)testTBXMLParseRelationsWithTestObject:(OSMKTestObject *)testObject 60 | { 61 | NSError *error = nil; 62 | OSMKTBXMLParser *parser = [[OSMKTBXMLParser alloc] initWithData:testObject.data error:&error]; 63 | NSArray *relations = [parser parseRelations]; 64 | 65 | XCTAssertEqual([relations count], testObject.relationCount, @"Relations count not equal"); 66 | XCTAssertNil(error,@"Found Error"); 67 | } 68 | 69 | - (void)testTBXMLParseUsersWithTestObject:(OSMKTestObject *)testObject 70 | { 71 | NSError *error = nil; 72 | OSMKTBXMLParser *parser = [[OSMKTBXMLParser alloc] initWithData:testObject.data error:&error]; 73 | NSArray *users = [parser parseUsers]; 74 | 75 | XCTAssertEqual([users count], testObject.userCount, @"Relations count not equal"); 76 | XCTAssertNil(error,@"Found Error"); 77 | } 78 | 79 | - (void)testTBXMLParseNotesWithTestObject:(OSMKTestObject *)testObject 80 | { 81 | NSError *error = nil; 82 | OSMKTBXMLParser *parser = [[OSMKTBXMLParser alloc] initWithData:testObject.data error:&error]; 83 | 84 | NSArray *notes = [parser parseNotes]; 85 | XCTAssertEqual([notes count], testObject.noteCount, @"Relations count not equal"); 86 | XCTAssertNil(error,@"Found Error"); 87 | } 88 | 89 | - (void)testTBXMLPerformance { 90 | [self measureBlock:^{ 91 | [self.testData enumerateXMLDataSources:^(OSMKTestObject *testObject, BOOL *stop) { 92 | OSMKTBXMLParser *parser = [[OSMKTBXMLParser alloc] initWithData:testObject.data error:nil]; 93 | NSArray *nodes = [parser parseNodes]; 94 | NSArray *ways = [parser parseWays]; 95 | NSArray *relations = [parser parseRelations]; 96 | NSArray *notes = [parser parseNotes]; 97 | NSArray *users = [parser parseUsers]; 98 | 99 | XCTAssertEqual([nodes count], testObject.nodeCount, @"Node count not equal"); 100 | XCTAssertEqual([ways count], testObject.wayCount, @"Way count not equal"); 101 | XCTAssertEqual([relations count], testObject.relationCount, @"Relation count not equal"); 102 | XCTAssertEqual([users count], testObject.userCount, @"User count not equal"); 103 | XCTAssertEqual([notes count], testObject.noteCount, @"Note count not equal"); 104 | }]; 105 | 106 | 107 | }]; 108 | } 109 | 110 | - (void)testNSJSONSerializationParser 111 | { 112 | [self.testData enumerateJSONDataSources:^(OSMKTestObject *testObject, BOOL *stop) { 113 | OSMKNSJSONSerialization *serializer = [[OSMKNSJSONSerialization alloc] initWithData:testObject.data]; 114 | NSArray *notes = [serializer parseNotes]; 115 | XCTAssertEqual([notes count],testObject.noteCount); 116 | }]; 117 | } 118 | 119 | - (void)testNSJSONPerformance { 120 | [self measureBlock:^{ 121 | [self testNSJSONSerializationParser]; 122 | }]; 123 | 124 | } 125 | 126 | - (void)tearDown 127 | { 128 | // Put teardown code here. This method is called after the invocation of each test method in the class. 129 | [super tearDown]; 130 | } 131 | 132 | @end 133 | -------------------------------------------------------------------------------- /OSMKit/Storage/OSMKSpatiaLiteStorage.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKSpatialLiteStorage.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/11/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKSpatiaLiteStorage.h" 10 | #import "FMDatabaseQueue.h" 11 | #import 12 | #import 13 | 14 | #import "OSMKNode.h" 15 | #import "OSMKWay.h" 16 | #import "OSMKRelation.h" 17 | #import "OSMKRelationMember.h" 18 | #import "OSMKNote.h" 19 | #import "OSMKComment.h" 20 | #import "OSMKUser.h" 21 | #import "OSMKConstants.h" 22 | #import "FMDatabase+OSMKitSpatiaLite.h" 23 | #import "ShapeKitGeometry.h" 24 | 25 | @interface OSMKSpatiaLiteStorage () 26 | 27 | @property (nonatomic, strong) SpatialDatabaseQueue *databaseQueue; 28 | 29 | @property (nonatomic) dispatch_queue_t storageQueue; 30 | 31 | @end 32 | 33 | @implementation OSMKSpatiaLiteStorage 34 | 35 | - (instancetype)initWithFilePath:(NSString *)filePath 36 | overwrite:(BOOL)overwrite 37 | { 38 | if (self = [self init]) { 39 | _filePath = filePath; 40 | self.databaseQueue = [SpatialDatabaseQueue databaseQueueWithPath:self.filePath]; 41 | 42 | [self setupDatabaseWithOverwrite:overwrite]; 43 | } 44 | return self; 45 | } 46 | 47 | - (void)setupDatabaseWithOverwrite:(BOOL)overwrite 48 | { 49 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 50 | ////// Remove Tables ////// 51 | 52 | 53 | 54 | ////// Indexes ////// 55 | // sucess = [db executeUpdate:@"CREATE INDEX way_nodes_way_id ON way_nodes ( way_id );"]; 56 | //sucess = [db executeUpdate:@"CREATE INDEX way_nodes_node_id ON way_nodes ( node_id )"]; 57 | 58 | }]; 59 | 60 | } 61 | 62 | #pragma - mark Public Fetching Methods 63 | 64 | - (OSMKNode *)nodeWithOsmId:(int64_t)osmId 65 | { 66 | __block OSMKNode *node = nil; 67 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 68 | node = [db osmk_nodeWithOsmId:osmId]; 69 | }]; 70 | return node; 71 | } 72 | 73 | - (void)nodeWithOsmId:(int64_t)osmId completion:(void (^)(OSMKNode *node, NSError *error))completionBlock 74 | { 75 | dispatch_async(self.storageQueue, ^{ 76 | OSMKNode *node =[self nodeWithOsmId:osmId]; 77 | if (completionBlock) { 78 | dispatch_async(dispatch_get_main_queue(), ^{ 79 | completionBlock(node,nil); 80 | }); 81 | } 82 | }); 83 | } 84 | 85 | - (OSMKWay *)wayWithOsmId:(int64_t)osmId 86 | { 87 | __block OSMKWay *way = nil; 88 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 89 | way = [db osmk_wayWithOsmId:osmId]; 90 | }]; 91 | return way; 92 | } 93 | 94 | - (void)wayWithOsmId:(int64_t)osmId completion:(void (^)(OSMKWay *way, NSError *error))completionBlock 95 | { 96 | dispatch_async(self.storageQueue, ^{ 97 | OSMKWay *way =[self wayWithOsmId:osmId]; 98 | if (completionBlock) { 99 | dispatch_async(dispatch_get_main_queue(), ^{ 100 | completionBlock(way,nil); 101 | }); 102 | } 103 | }); 104 | } 105 | 106 | - (OSMKRelation *)relationWithOsmId:(int64_t)osmId 107 | { 108 | __block OSMKRelation *relation = nil; 109 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 110 | relation = [db osmk_relationWithOsmId:osmId]; 111 | }]; 112 | return relation; 113 | } 114 | 115 | - (void)relationWithOsmId:(int64_t)osmId completion:(void (^)(OSMKRelation *relation, NSError *error))completionBlock 116 | { 117 | dispatch_async(self.storageQueue, ^{ 118 | OSMKRelation *relation =[self relationWithOsmId:osmId]; 119 | if (completionBlock) { 120 | dispatch_async(dispatch_get_main_queue(), ^{ 121 | completionBlock(relation,nil); 122 | }); 123 | } 124 | }); 125 | } 126 | 127 | - (void)userWithOsmId:(int64_t)osmId completion:(void (^)(OSMKUser *user, NSError *error))completionBlock 128 | { 129 | dispatch_async(self.storageQueue, ^{ 130 | __block OSMKUser *user = nil; 131 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 132 | user = [db osmk_userWithOsmId:osmId]; 133 | }]; 134 | if (completionBlock) { 135 | dispatch_async(dispatch_get_main_queue(), ^{ 136 | completionBlock(user,nil); 137 | }); 138 | } 139 | }); 140 | } 141 | 142 | - (void)noteWithOsmId:(int64_t)osmId completion:(void (^)(OSMKNote *note, NSError *error))completionBlock 143 | { 144 | dispatch_async(self.storageQueue, ^{ 145 | __block OSMKNote *note = nil; 146 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 147 | note = [db osmk_noteWithOsmId:osmId]; 148 | }]; 149 | if (completionBlock) { 150 | dispatch_async(dispatch_get_main_queue(), ^{ 151 | completionBlock(note,nil); 152 | }); 153 | } 154 | }); 155 | } 156 | 157 | #pragma - mark Class Methods 158 | + (instancetype)spatiaLiteStorageWithFilePath:(NSString *)filePath overwrite:(BOOL)overwrite 159 | { 160 | return [[self alloc] initWithFilePath:filePath overwrite:overwrite]; 161 | } 162 | 163 | @end 164 | -------------------------------------------------------------------------------- /OSMKit/Storage/OSMKImporter.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKImporter.m 3 | // Pods 4 | // 5 | // Created by David Chiles on 1/13/15. 6 | // 7 | // 8 | 9 | #import "OSMKImporter.h" 10 | #import "FMDatabase+OSMKitSpatiaLite.h" 11 | #import 12 | #import "FMDB.h" 13 | #import "OSMKTBXMLParser.h" 14 | 15 | @interface OSMKImporter () 16 | 17 | @property (nonatomic, strong) FMDatabaseQueue *databaseQueue; 18 | 19 | @property (nonatomic, strong) dispatch_queue_t serialWorkQueue; 20 | 21 | @end 22 | 23 | @implementation OSMKImporter 24 | 25 | - (id)init 26 | { 27 | if (self = [super init]) { 28 | 29 | NSString *queueString = [NSString stringWithFormat:@"%@-work",NSStringFromClass([self class])]; 30 | self.serialWorkQueue = dispatch_queue_create([queueString UTF8String], 0); 31 | } 32 | return self; 33 | } 34 | 35 | - (BOOL)setupDatbaseWithPath:(NSString *)path overwrite:(BOOL)overwrite 36 | { 37 | if ([path length]) { 38 | self.databaseQueue = [[SpatialDatabaseQueue alloc] initWithPath:path]; 39 | __block BOOL success = NO; 40 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 41 | success = [db osmk_setupDatabaseWithOverwrite:overwrite]; 42 | }]; 43 | } 44 | } 45 | 46 | - (void)asyncSetupDatbaseWithPath:(NSString *)path overwrite:(BOOL)overwrite completion:(void (^)(BOOL success))completionBlock completionQueue:(dispatch_queue_t)completionQueue; 47 | { 48 | if (!completionQueue) { 49 | __block completionQueue = dispatch_get_main_queue(); 50 | } 51 | __weak typeof(self)weakSelf = self; 52 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 53 | __strong typeof(weakSelf)strongSelf = weakSelf; 54 | __block BOOL success = [strongSelf setupDatbaseWithPath:path overwrite:overwrite]; 55 | if (completionBlock) { 56 | dispatch_sync(completionQueue, ^{ 57 | completionBlock(success); 58 | }); 59 | } 60 | }); 61 | } 62 | 63 | #pragma - mark Import Methods 64 | 65 | - (void)importXMLData:(NSData *)xmlData completion:(void (^)(void))completionBlock completionQueue:(dispatch_queue_t)completionQueue; 66 | { 67 | dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 68 | 69 | 70 | dispatch_async(concurrentQueue, ^{ 71 | dispatch_group_t nodeGroup = dispatch_group_create(); 72 | dispatch_group_t wayGroup = dispatch_group_create(); 73 | __block NSArray *parsedWays = nil; 74 | __block NSArray *parsedRelations = nil; 75 | 76 | dispatch_group_enter(wayGroup); 77 | 78 | __block OSMKTBXMLParser *parser = [[OSMKTBXMLParser alloc] initWithData:xmlData error:nil]; 79 | 80 | dispatch_group_async(nodeGroup, concurrentQueue, ^{ 81 | //Parse all nodes 82 | NSLog(@"Start Parsing Nodes"); 83 | NSArray *nodes = [parser parseNodes]; 84 | //Store all nodes 85 | NSLog(@"Finished Parsing Nodes"); 86 | NSLog(@"Start Saving Nodes"); 87 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 88 | [nodes enumerateObjectsUsingBlock:^(OSMKNode *node, NSUInteger idx, BOOL *stop) { 89 | [db osmk_saveNode:node error:nil]; 90 | }]; 91 | }]; 92 | NSLog(@"Finished Saving Nodes"); 93 | }); 94 | 95 | dispatch_group_async(nodeGroup, concurrentQueue, ^{ 96 | //Parse all ways 97 | NSLog(@"Start Parsing Ways"); 98 | parsedWays = [parser parseWays]; 99 | NSLog(@"Fnished Parsing Ways"); 100 | }); 101 | 102 | dispatch_group_notify(nodeGroup, concurrentQueue, ^{ 103 | //Once nodes have been stored & ways have been parsed 104 | //Save ways 105 | dispatch_group_async(wayGroup, concurrentQueue, ^{ 106 | NSLog(@"Start Saving Ways"); 107 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 108 | [parsedWays enumerateObjectsUsingBlock:^(OSMKWay *way, NSUInteger idx, BOOL *stop) { 109 | [db osmk_saveWay:way error:nil]; 110 | }]; 111 | }]; 112 | dispatch_group_leave(wayGroup); 113 | NSLog(@"Finished Saving Ways"); 114 | }); 115 | 116 | }); 117 | 118 | dispatch_group_async(wayGroup, concurrentQueue, ^{ 119 | NSLog(@"Start Parsing Relations"); 120 | parsedRelations = [parser parseRelations]; 121 | NSLog(@"Finished Parsing Relations"); 122 | }); 123 | 124 | dispatch_group_notify(wayGroup, concurrentQueue, ^{ 125 | //Once ways have been stored & relatoins parsed 126 | //Save relations 127 | NSLog(@"Start Saving Relations"); 128 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 129 | [parsedRelations enumerateObjectsUsingBlock:^(OSMKRelation *relation, NSUInteger idx, BOOL *stop) { 130 | [db osmk_saveRelation:relation error:nil]; 131 | }]; 132 | }]; 133 | NSLog(@"Finished Saving Relations"); 134 | 135 | if (completionBlock) { 136 | dispatch_async(completionQueue, completionBlock); 137 | } 138 | }); 139 | }); 140 | 141 | 142 | } 143 | 144 | @end 145 | -------------------------------------------------------------------------------- /Tests/OSMKit.xcworkspace/xcuserdata/david.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 34 | 35 | 36 | 38 | 50 | 51 | 52 | 54 | 66 | 67 | 68 | 70 | 82 | 83 | 97 | 98 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /Tests/OSMKitTests/OSMKStorageTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKStorageTests.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 12/2/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "OSMKSpatiaLiteStorage.h" 11 | #import "OSMKTestData.h" 12 | #import "FMDB.h" 13 | #import "FMDatabase+OSMKitSpatiaLite.h" 14 | #import "SpatialDatabaseQueue.h" 15 | #import "OSMKTBXMLParser.h" 16 | 17 | @interface OSMKStorageTests : XCTestCase 18 | 19 | @property (nonatomic, strong) NSOperationQueue *operationQueue; 20 | @property (nonatomic, strong) NSString *filePath; 21 | @property (nonatomic, strong) OSMKTestData *testData; 22 | 23 | @property (nonatomic, strong) OSMKSpatiaLiteStorage *database; 24 | @property (nonatomic, strong) SpatialDatabaseQueue *databaseQueue; 25 | 26 | @end 27 | 28 | @implementation OSMKStorageTests 29 | 30 | - (void)setUp { 31 | [super setUp]; 32 | 33 | self.filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"db.sqlite"]; 34 | if ([[NSFileManager defaultManager] fileExistsAtPath:self.filePath]) { 35 | [[NSFileManager defaultManager] removeItemAtPath:self.filePath error:nil]; 36 | } 37 | 38 | NSLog(@"File Path: %@",self.filePath); 39 | 40 | self.database = [OSMKSpatiaLiteStorage spatiaLiteStorageWithFilePath:self.filePath overwrite:NO]; 41 | self.databaseQueue = [[SpatialDatabaseQueue alloc] initWithPath:self.filePath]; 42 | 43 | self.testData = [[OSMKTestData alloc] init]; 44 | 45 | } 46 | 47 | - (void)tearDown { 48 | [super tearDown]; 49 | } 50 | 51 | - (void)testSpatiaLiteStorage { 52 | 53 | [self.testData enumerateXMLDataSources:^(OSMKTestObject *testObject, BOOL *stop) { 54 | NSError *error = nil; 55 | OSMKTBXMLParser *parser = [[OSMKTBXMLParser alloc] initWithData:testObject.data error:&error]; 56 | XCTAssertNil(error,@"Error parsing"); 57 | 58 | __block NSArray *nodes = [parser parseNodes]; 59 | 60 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 61 | [nodes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 62 | NSError *dbError = nil; 63 | BOOL result = [db osmk_saveNode:obj error:&dbError]; 64 | XCTAssertTrue(result == YES,@"Error Saving Node %@",obj); 65 | XCTAssertNil(dbError,@"Error saving Node"); 66 | }]; 67 | }]; 68 | 69 | __block NSArray *ways = [parser parseWays]; 70 | 71 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 72 | [ways enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 73 | NSError *dbError = nil; 74 | BOOL result = [db osmk_saveWay:obj error:&dbError]; 75 | XCTAssertTrue(result == YES,@"Error Saving way %@",obj); 76 | XCTAssertNil(dbError,@"Error saving way"); 77 | }]; 78 | }]; 79 | 80 | __block NSArray *relations = [parser parseRelations]; 81 | 82 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 83 | [relations enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 84 | NSError *dbError = nil; 85 | BOOL result = [db osmk_saveRelation:obj error:&dbError]; 86 | XCTAssertTrue(result == YES,@"Error Saving Relation %@",obj); 87 | XCTAssertNil(dbError,@"Error saving Relation"); 88 | }]; 89 | }]; 90 | 91 | __block NSArray *notes = [parser parseNotes]; 92 | 93 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 94 | [notes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 95 | NSError *dbError = nil; 96 | BOOL result = [db osmk_saveNote:obj error:&dbError]; 97 | XCTAssertTrue(result == YES,@"Error Saving Note %@",obj); 98 | XCTAssertNil(dbError,@"Error saving Note"); 99 | }]; 100 | }]; 101 | 102 | __block NSArray *users = [parser parseUsers]; 103 | 104 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 105 | [users enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 106 | NSError *dbError = nil; 107 | BOOL result = [db osmk_saveUser:obj error:&dbError]; 108 | XCTAssertTrue(result == YES,@"Error Saving User %@",obj); 109 | XCTAssertNil(dbError,@"Error saving User"); 110 | }]; 111 | }]; 112 | }]; 113 | 114 | } 115 | 116 | //Test that all ways have geometry 117 | 118 | - (void)testwayNodeUnique 119 | { 120 | NSString *tagInsertString = [NSString stringWithFormat:@"INSERT INTO way_node (way_id, node_id, local_order) VALUES (?,?,?)"]; 121 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 122 | 123 | BOOL result = [db executeUpdate:tagInsertString,@(1),@(11),@(0)]; 124 | result = [db executeUpdate:tagInsertString,@(1),@(11),@(0)]; 125 | result = [db executeUpdate:tagInsertString,@(1),@(12),@(1)]; 126 | result = [db executeUpdate:tagInsertString,@(1),@(12),@(1)]; 127 | }]; 128 | 129 | [self.databaseQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 130 | FMResultSet *result = [db executeQuery:@"SELECT * FROM way_node"]; 131 | 132 | int count = 0; 133 | 134 | while ([result next]){ 135 | NSDictionary *resultDictionary = [result resultDictionary]; 136 | XCTAssertTrue([resultDictionary[@"way_id"] intValue] == 1); 137 | XCTAssertTrue([resultDictionary[@"node_id"] intValue] == 11+count); 138 | XCTAssertTrue([resultDictionary[@"local_order"] intValue] == count); 139 | count++; 140 | } 141 | 142 | XCTAssertTrue(count == 2, @"Too many"); 143 | }]; 144 | } 145 | 146 | @end 147 | -------------------------------------------------------------------------------- /OSMKit/Model/OSMKObject.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKObject.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 4/10/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKObject.h" 10 | 11 | #import "OSMKNode.h" 12 | #import "OSMKWay.h" 13 | #import "OSMKRelation.h" 14 | 15 | #import "DDXMLElement.h" 16 | #import "DDXMLElementAdditions.h" 17 | 18 | @interface OSMKObject () 19 | 20 | @property (nonatomic, strong) NSDate *timeStamp; 21 | 22 | @end 23 | 24 | @implementation OSMKObject 25 | 26 | 27 | - (instancetype)initWithId:(int64_t)osmId 28 | { 29 | if (self = [super init]) { 30 | self.osmId = osmId; 31 | } 32 | return self; 33 | } 34 | 35 | - (instancetype)initWithAttributesDictionary:(NSDictionary *)attributes 36 | { 37 | if (self = [super init]) { 38 | self.osmId = [attributes[@"id"] longLongValue]; 39 | self.version = [attributes[@"version"] intValue]; 40 | self.changeset = [attributes[@"changeset"] longLongValue]; 41 | self.userId = [attributes[@"uid"] longLongValue]; 42 | self.visible = [attributes[@"visible"] isEqualToString:@"true"]; 43 | self.user = attributes[@"user"]; 44 | self.timeStampString = attributes[@"timestamp"]; 45 | } 46 | return self; 47 | } 48 | 49 | - (void)setTimeStampString:(NSString *)timeStampString 50 | { 51 | _timeStampString = timeStampString; 52 | _timeStamp = nil; 53 | } 54 | 55 | - (NSDate *)timeStamp 56 | { 57 | if (_timeStamp) { 58 | return _timeStamp; 59 | } 60 | 61 | if ([self.timeStampString length]) { 62 | _timeStamp = [[OSMKObject defaultDateFormatter] dateFromString:self.timeStampString]; 63 | } 64 | else { 65 | _timeStamp = nil; 66 | } 67 | 68 | return _timeStamp; 69 | } 70 | 71 | #pragma - mark XML 72 | 73 | - (NSString *)xmlName 74 | { 75 | if ([self isKindOfClass:[OSMKNode class]]) { 76 | return @"node"; 77 | } 78 | else if ([self isKindOfClass:[OSMKWay class]]) { 79 | return @"way"; 80 | } 81 | else if ([self isKindOfClass:[OSMKRelation class]]) { 82 | return @"relation"; 83 | } 84 | return nil; 85 | } 86 | 87 | - (DDXMLElement *)DELETEEelementForChangeset:(NSNumber *)changeset 88 | { 89 | DDXMLElement *objectXML = [[DDXMLElement alloc] initWithName:[self xmlName]]; 90 | if (self.osmId > 0) { 91 | [objectXML addAttributeWithName:@"id" stringValue:[@(self.osmId) stringValue]]; 92 | [objectXML addAttributeWithName:@"version" stringValue:[@(self.version) stringValue]]; 93 | } 94 | [objectXML addAttributeWithName:@"changeset" stringValue:[changeset stringValue]]; 95 | return objectXML; 96 | } 97 | 98 | - (DDXMLElement *)PUTElementForChangeset:(NSNumber *)changeset 99 | { 100 | DDXMLElement *objectXML = [self PUTElementForChangeset:changeset]; 101 | [objectXML setAttributes:[OSMKObject tagXML:self.tags]]; 102 | return objectXML; 103 | } 104 | 105 | + (NSArray *)tagXML:(NSDictionary *)tags 106 | { 107 | NSMutableArray *array = [NSMutableArray arrayWithCapacity:[tags.allKeys count]]; 108 | [tags enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, BOOL *stop) { 109 | DDXMLElement *tagElement = [DDXMLElement elementWithName:@"tag"]; 110 | DDXMLNode *keyNode = [DDXMLNode attributeWithName:@"k" stringValue:key]; 111 | DDXMLNode *valueNode = [DDXMLNode attributeWithName:@"v" stringValue:value]; 112 | [tagElement setAttributes:@[keyNode,valueNode]]; 113 | [array addObject:tagElement]; 114 | }]; 115 | return [array copy]; 116 | } 117 | 118 | 119 | #pragma NSCopying Methods 120 | 121 | - (id)copyWithZone:(NSZone *)zone 122 | { 123 | OSMKObject *object = [[[self class] allocWithZone:zone] initWithId:self.osmId]; 124 | object.version = self.version; 125 | object.changeset = self.changeset; 126 | object.userId = self.userId; 127 | object.visible = self.visible; 128 | object.tags = [self.tags copyWithZone:zone]; 129 | object.user = [self.user copyWithZone:zone]; 130 | object.action = self.action; 131 | object.timeStampString = [self.timeStampString copyWithZone:zone]; 132 | 133 | return object; 134 | } 135 | 136 | #pragma - mark Class Methods 137 | 138 | + (NSDateFormatter *)defaultDateFormatter 139 | { 140 | static NSDateFormatter *dateFormatter = nil; 141 | 142 | static dispatch_once_t onceToken; 143 | dispatch_once(&onceToken, ^{ 144 | dateFormatter = [[NSDateFormatter alloc] init]; 145 | [dateFormatter setDateFormat:@"YYYY-MM-dd'T'HH:mm:ssZ"]; 146 | }); 147 | 148 | return dateFormatter; 149 | } 150 | 151 | + (NSString *)stringForType:(OSMKElementType)type 152 | { 153 | NSString *string = nil; 154 | if (type == OSMKElementTypeNode) { 155 | string = @"node"; 156 | } 157 | else if (type == OSMKElementTypeWay) { 158 | string = @"way"; 159 | } 160 | else if (type == OSMKElementTypeRelation) { 161 | string = @"relation"; 162 | } 163 | 164 | return string; 165 | } 166 | 167 | + (OSMKElementType)typeForString:(NSString *)string 168 | { 169 | OSMKElementType type = OSMKElementTypeNone; 170 | if ([string isEqualToString:@"node"]) { 171 | type = OSMKElementTypeNode; 172 | } 173 | else if ([string isEqualToString:@"way"]) { 174 | type = OSMKElementTypeWay; 175 | } 176 | else if ([string isEqualToString:@"relation"]) { 177 | type = OSMKElementTypeRelation; 178 | } 179 | 180 | return type; 181 | } 182 | 183 | + (instancetype)objectForType:(OSMKElementType)type elementId:(int64_t)elementId 184 | { 185 | id element = nil; 186 | switch (type) { 187 | case OSMKElementTypeNode: 188 | element = [[OSMKNode alloc] initWithId:elementId]; 189 | break; 190 | case OSMKElementTypeWay: 191 | element = [[OSMKWay alloc] initWithId:elementId]; 192 | break; 193 | case OSMKElementTypeRelation: 194 | element = [[OSMKRelation alloc] initWithId:elementId]; 195 | break; 196 | default: 197 | break; 198 | } 199 | return element; 200 | } 201 | 202 | @end 203 | -------------------------------------------------------------------------------- /OSMKit/Parser/OSMKTBXMLParser.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKTBXMLParser.m 3 | // Pods 4 | // 5 | // Created by David Chiles on 12/28/14. 6 | // 7 | // 8 | 9 | #import "OSMKTBXMLParser.h" 10 | #import "TBXML+OSMKit.h" 11 | #import "OSMKConstants.h" 12 | 13 | #import "OSMKNode.h" 14 | #import "OSMKWay.h" 15 | #import "OSMKRelation.h" 16 | #import "OSMKUser.h" 17 | #import "OSMKNote.h" 18 | #import "OSMKComment.h" 19 | 20 | @interface OSMKTBXMLParser () 21 | 22 | @property (nonatomic, strong) TBXML *parser; 23 | 24 | @end 25 | 26 | @implementation OSMKTBXMLParser 27 | 28 | - (instancetype)initWithData:(NSData *)data error:(NSError *__autoreleasing *)error 29 | { 30 | if (self = [self init]) { 31 | if ([data length]) { 32 | self.parser = [[TBXML alloc] initWithXMLData:data error:error]; 33 | } 34 | } 35 | return self; 36 | } 37 | 38 | - (NSArray *)parseNodes 39 | { 40 | NSMutableArray *nodes = [[NSMutableArray alloc] init]; 41 | TBXMLElement * nodeXML = [TBXML childElementNamed:OSMKNodeElementName parentElement:self.parser.rootXMLElement]; 42 | while (nodeXML) { 43 | OSMKNode *node = [[OSMKNode alloc] initWithAttributesDictionary:[TBXML osmk_attributesDictionaryWithElement:nodeXML]]; 44 | node.tags = [TBXML osmk_tagsDictioanryWithElement:nodeXML]; 45 | if (node) { 46 | [nodes addObject:node]; 47 | } 48 | nodeXML = [TBXML nextSiblingNamed:OSMKNodeElementName searchFromElement:nodeXML]; 49 | } 50 | 51 | if (![nodes count]) { 52 | nodes = nil; 53 | } 54 | 55 | return nodes; 56 | } 57 | 58 | - (NSArray *)parseWays 59 | { 60 | NSMutableArray *ways = [NSMutableArray new]; 61 | TBXMLElement *wayXML = [TBXML childElementNamed:OSMKWayElementName parentElement:self.parser.rootXMLElement]; 62 | while (wayXML) { 63 | 64 | OSMKWay *way = [[OSMKWay alloc] initWithAttributesDictionary:[TBXML osmk_attributesDictionaryWithElement:wayXML]]; 65 | way.tags = [TBXML osmk_tagsDictioanryWithElement:wayXML]; 66 | way.nodes = [TBXML osmk_wayNodesWithElement:wayXML]; 67 | 68 | if (way) { 69 | [ways addObject:way]; 70 | } 71 | 72 | wayXML = [TBXML nextSiblingNamed:OSMKWayElementName searchFromElement:wayXML]; 73 | } 74 | if (![ways count]) { 75 | ways = nil; 76 | } 77 | return ways; 78 | } 79 | 80 | - (NSArray *)parseRelations 81 | { 82 | NSMutableArray *relations = [NSMutableArray new]; 83 | TBXMLElement *relationXML = [TBXML childElementNamed:OSMKRelationElementName parentElement:self.parser.rootXMLElement]; 84 | while (relationXML) { 85 | OSMKRelation *relation = [[OSMKRelation alloc] initWithAttributesDictionary:[TBXML osmk_attributesDictionaryWithElement:relationXML]]; 86 | relation.tags = [TBXML osmk_tagsDictioanryWithElement:relationXML]; 87 | relation.members = [TBXML osmk_relationMembersWithElement:relationXML]; 88 | 89 | if (relation) { 90 | [relations addObject:relation]; 91 | } 92 | relationXML = [TBXML nextSiblingNamed:OSMKRelationElementName searchFromElement:relationXML]; 93 | } 94 | 95 | if (![relations count]) { 96 | relations = nil; 97 | } 98 | return relations; 99 | } 100 | 101 | - (NSArray *)parseUsers 102 | { 103 | NSMutableArray *users = [NSMutableArray new]; 104 | TBXMLElement *userXML = [TBXML childElementNamed:OSMKUserElementName parentElement:self.parser.rootXMLElement]; 105 | while (userXML) { 106 | OSMKUser *user = [[OSMKUser alloc] initWithAttributesDictionary:[TBXML osmk_attributesDictionaryWithElement:userXML]]; 107 | user.userDescription = [TBXML textForElement:[TBXML childElementNamed:@"description" parentElement:userXML]]; 108 | 109 | NSString *agreed = [TBXML valueOfAttributeNamed:@"agreed" forElement:[TBXML childElementNamed:@"contributor-terms" parentElement:userXML]]; 110 | if ([agreed isEqualToString:@"true"]) { 111 | user.termsAgreed = YES; 112 | } 113 | else { 114 | user.termsAgreed = NO; 115 | } 116 | 117 | NSString *urlString =[ TBXML valueOfAttributeNamed:@"href" forElement:[TBXML childElementNamed:@"img" parentElement:userXML]]; 118 | if ([urlString length]) { 119 | user.imageUrl = [NSURL URLWithString:urlString]; 120 | } 121 | 122 | TBXMLElement *rolesXML = [TBXML childElementNamed:OSMKUserRolesElementName parentElement:userXML]; 123 | TBXMLElement *role = rolesXML->firstChild; 124 | NSMutableSet *roleSet = [NSMutableSet set]; 125 | 126 | while (role) { 127 | NSString *name = [TBXML elementName:role]; 128 | if ([name length]) { 129 | [roleSet addObject:name]; 130 | } 131 | 132 | role = role->nextSibling; 133 | } 134 | 135 | user.roles = roleSet; 136 | 137 | user.changesetCount = [[TBXML valueOfAttributeNamed:@"count" forElement:[TBXML childElementNamed:@"changesets" parentElement:userXML]]integerValue]; 138 | user.traceCount = [[TBXML valueOfAttributeNamed:@"count" forElement:[TBXML childElementNamed:@"traces" parentElement:userXML]] integerValue]; 139 | 140 | 141 | user.receivedBlocks = [[TBXML valueOfAttributeNamed:@"count" forElement:[TBXML childElementNamed:@"received" parentElement:[TBXML childElementNamed:@"blocks" parentElement:userXML]]] integerValue]; 142 | user.activeReceivedBlocks = [[TBXML valueOfAttributeNamed:@"active" forElement:[TBXML childElementNamed:@"received" parentElement:[TBXML childElementNamed:@"blocks" parentElement:userXML]]] integerValue]; 143 | user.issuedBlocks = [[TBXML valueOfAttributeNamed:@"count" forElement:[TBXML childElementNamed:@"issued" parentElement:[TBXML childElementNamed:@"blocks" parentElement:userXML]]] integerValue]; 144 | user.activeIssuedBlocks = [[TBXML valueOfAttributeNamed:@"active" forElement:[TBXML childElementNamed:@"issued" parentElement:[TBXML childElementNamed:@"blocks" parentElement:userXML]]] integerValue]; 145 | 146 | if (user) { 147 | [users addObject:user]; 148 | } 149 | 150 | 151 | userXML = [TBXML nextSiblingNamed:OSMKUserElementName searchFromElement:userXML]; 152 | } 153 | 154 | if (![users count]) { 155 | users = nil; 156 | } 157 | 158 | return users; 159 | } 160 | 161 | - (NSArray *)parseNotes 162 | { 163 | NSMutableArray *notes = [NSMutableArray new]; 164 | TBXMLElement *noteXML = [TBXML childElementNamed:OSMKNoteElementName parentElement:self.parser.rootXMLElement]; 165 | while (noteXML) { 166 | OSMKNote *note = [[OSMKNote alloc] init]; 167 | double lat = [[TBXML valueOfAttributeNamed:@"lat" forElement:noteXML] doubleValue]; 168 | double lon = [[TBXML valueOfAttributeNamed:@"lon" forElement:noteXML] doubleValue]; 169 | note.coordinate = CLLocationCoordinate2DMake(lat, lon); 170 | note.osmId = [[TBXML textForElement:[TBXML childElementNamed:@"id" parentElement:noteXML]] longLongValue]; 171 | note.dateCreated = [[OSMKNote defaultDateFormatter] dateFromString:[TBXML textForElement:[TBXML childElementNamed:@"date_created" parentElement:noteXML]]]; 172 | 173 | TBXMLElement *dateClosedElement = [TBXML childElementNamed:@"date_closed" parentElement:noteXML]; 174 | if (dateClosedElement) { 175 | note.dateClosed = [[OSMKNote defaultDateFormatter] dateFromString:[TBXML textForElement:dateClosedElement]]; 176 | } 177 | 178 | note.isOpen = [[TBXML textForElement:[TBXML childElementNamed:@"status" parentElement:noteXML]] isEqualToString:@"open"]; 179 | 180 | NSMutableArray *comments = [NSMutableArray array]; 181 | TBXMLElement *commentXML = [TBXML childElementNamed:OSMKNoteCommentsElementName parentElement:noteXML]->firstChild; 182 | while (commentXML) { 183 | OSMKComment *comment = [[OSMKComment alloc] init]; 184 | comment.date = [[OSMKNote defaultDateFormatter] dateFromString:[TBXML textForElement:[TBXML childElementNamed:@"date" parentElement:commentXML]]]; 185 | comment.action =[TBXML textForElement:[TBXML childElementNamed:@"action" parentElement:commentXML]]; 186 | comment.text = [TBXML textForElement:[TBXML childElementNamed:@"text" parentElement:commentXML]]; 187 | 188 | TBXMLElement *userElement = [TBXML childElementNamed:@"user" parentElement:commentXML]; 189 | TBXMLElement *userIdElement = [TBXML childElementNamed:@"uid" parentElement:commentXML]; 190 | if (userElement) 191 | { 192 | comment.user = [TBXML textForElement:userElement]; 193 | } 194 | 195 | if (userIdElement) { 196 | comment.userId = [[TBXML textForElement:userElement] longLongValue]; 197 | } 198 | 199 | 200 | comment.userId = [[TBXML textForElement:[TBXML childElementNamed:@"date" parentElement:commentXML]] longLongValue]; 201 | 202 | [comments addObject:comment]; 203 | 204 | commentXML = commentXML->nextSibling; 205 | } 206 | 207 | note.commentsArray = [comments copy]; 208 | 209 | if (note) { 210 | [notes addObject:note]; 211 | } 212 | 213 | noteXML = [TBXML nextSiblingNamed:OSMKNoteElementName searchFromElement:noteXML]; 214 | } 215 | 216 | if (![notes count]) { 217 | notes = nil; 218 | } 219 | 220 | return notes; 221 | } 222 | 223 | @end 224 | -------------------------------------------------------------------------------- /Tests/OSMKit.xcodeproj/xcshareddata/xcschemes/OSMKit.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 43 | 49 | 50 | 51 | 57 | 63 | 64 | 65 | 71 | 77 | 78 | 79 | 85 | 91 | 92 | 93 | 99 | 105 | 106 | 107 | 113 | 119 | 120 | 121 | 127 | 133 | 134 | 135 | 141 | 147 | 148 | 149 | 150 | 151 | 156 | 157 | 159 | 165 | 166 | 167 | 168 | 169 | 175 | 176 | 177 | 178 | 187 | 188 | 194 | 195 | 196 | 197 | 198 | 199 | 205 | 206 | 212 | 213 | 214 | 215 | 217 | 218 | 221 | 222 | 223 | -------------------------------------------------------------------------------- /OSMKit/API/OSMKAPIClient.m: -------------------------------------------------------------------------------- 1 | // 2 | // OSMKAPIClient.m 3 | // OSMKit 4 | // 5 | // Created by David Chiles on 6/9/14. 6 | // Copyright (c) 2014 davidchiles. All rights reserved. 7 | // 8 | 9 | #import "OSMKAPIClient.h" 10 | 11 | #import "AFNetworking.h" 12 | #import "OSMKRequestSerializer.h" 13 | #import "OSMKBoundingBox.h" 14 | #import "OSMKChangeset.h" 15 | #import "OSMKNode.h" 16 | #import "OSMKWay.h" 17 | #import "OSMKRelation.h" 18 | #import "OSMKRelationMember.h" 19 | 20 | #import "DDXMLElement.h" 21 | #import "DDXMLNode.h" 22 | #import "DDXMLDocument.h" 23 | #import "DDXMLElementAdditions.h" 24 | #import "OSMKNote.h" 25 | #import "OSMKComment.h" 26 | 27 | NSString *const OSMKBaseURLString = @"https://api.openstreetmap.org/api/0.6/"; 28 | NSString *const OSMKTestBaseURLString = @"http://api06.dev.openstreetmap.org/api/0.6/"; 29 | 30 | static NSString *const OSMKContentType = @"application/osm3s+xml"; 31 | 32 | @implementation OSMKAPIClient 33 | 34 | - (instancetype)init 35 | { 36 | return [self initWithBaseURL:[NSURL URLWithString:OSMKBaseURLString]]; 37 | } 38 | 39 | - (instancetype)initWithBaseURL:(NSURL *)url 40 | { 41 | if (self = [super initWithBaseURL:url]) { 42 | AFXMLParserResponseSerializer * xmlParserResponseSerializer = [AFXMLParserResponseSerializer serializer]; 43 | NSMutableSet * contentTypes = [xmlParserResponseSerializer.acceptableContentTypes mutableCopy]; 44 | [contentTypes addObject:@"application/osm3s+xml"]; 45 | xmlParserResponseSerializer.acceptableContentTypes = contentTypes; 46 | self.responseSerializer = [AFCompoundResponseSerializer compoundSerializerWithResponseSerializers:@[[AFJSONResponseSerializer serializer],xmlParserResponseSerializer]]; 47 | } 48 | return self; 49 | } 50 | 51 | - (instancetype)initWithConsumerKey:(NSString *)consumerKey privateKey:(NSString *)privateKey token:(NSString *)token tokenSecret:(NSString *)tokenSecret 52 | { 53 | if (self = [self init]) { 54 | OSMKRequestSerializer *requestSerializer = [[OSMKRequestSerializer alloc] initWithConsumerKey:consumerKey privateKey:privateKey token:token tokenSecret:tokenSecret]; 55 | self.requestSerializer = requestSerializer; 56 | } 57 | return self; 58 | } 59 | 60 | ////// Download ////// 61 | 62 | -(void)downloadDataWithSW:(CLLocationCoordinate2D)southWest NE:(CLLocationCoordinate2D)northEast 63 | success:(void (^)(NSData * response))success 64 | failure:(void (^)(NSError *error))failure 65 | { 66 | 67 | OSMKBoundingBox * bbox = [OSMKBoundingBox boundingBoxWithCornersSW:southWest NE:northEast]; 68 | NSString * bboxString = [NSString stringWithFormat:@"%f,%f,%f,%f",bbox.left,bbox.bottom,bbox.right,bbox.top]; 69 | NSDictionary * parametersDictionary = @{@"bbox": bboxString}; 70 | AFHTTPRequestOperation * httpRequestOperation = [self GET:@"map" parameters:parametersDictionary success:^(AFHTTPRequestOperation *operation, id responseObject) { 71 | if (success) { 72 | success(responseObject); 73 | } 74 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 75 | if (failure) 76 | { 77 | failure(error); 78 | } 79 | }]; 80 | [httpRequestOperation start]; 81 | 82 | } 83 | 84 | -(void)downloadNotesWithSW:(CLLocationCoordinate2D)southWest NE:(CLLocationCoordinate2D)northEast 85 | success:(void (^)(id response))success 86 | failure:(void (^)(NSError *error))failure 87 | { 88 | OSMKBoundingBox * bbox = [OSMKBoundingBox boundingBoxWithCornersSW:southWest NE:northEast]; 89 | NSString * bboxString = [NSString stringWithFormat:@"%f,%f,%f,%f",bbox.left,bbox.bottom,bbox.right,bbox.top]; 90 | NSDictionary * parametersDictionary = @{@"bbox": bboxString}; 91 | AFHTTPRequestOperation * httpRequestOperation = [self GET:@"notes.json" parameters:parametersDictionary success:^(AFHTTPRequestOperation *operation, id responseObject) { 92 | if (success) { 93 | success(responseObject); 94 | } 95 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 96 | if (failure) 97 | { 98 | failure(error); 99 | } 100 | }]; 101 | [httpRequestOperation start]; 102 | } 103 | 104 | 105 | ////// Upload ////// 106 | 107 | - (void)openChangeset:(OSMKChangeset *)changeset 108 | success:(void (^)(int64_t changesetID))success 109 | failure: (void (^)(NSError * error))failure 110 | { 111 | DDXMLElement *element = [self osmElement]; 112 | [element addChild:[changeset PUTXML]]; 113 | 114 | NSData *changesetData = [[element compactXMLString] dataUsingEncoding:NSUTF8StringEncoding]; 115 | 116 | AFHTTPRequestOperation *request = [self PUT:@"changeset/create" XML:changesetData success:^(AFHTTPRequestOperation *operation, id responseObject) { 117 | if (success) { 118 | success([[[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] longLongValue]); 119 | } 120 | } failure:^(AFHTTPRequestOperation *operation, NSError * error) { 121 | if (failure) { 122 | failure(error); 123 | } 124 | }]; 125 | [request start]; 126 | } 127 | 128 | - (void)uploadElement:(OSMKObject *)object 129 | changesetID:(NSNumber *)changesetID 130 | completion:(void (^)(OSMKObject *element, id response ,NSError *error))completion 131 | { 132 | void (^successBlock)(AFHTTPRequestOperation *operation, id response) = ^void(AFHTTPRequestOperation *operation, id response) { 133 | if (completion) { 134 | completion(object,response,nil); 135 | } 136 | }; 137 | void (^failureBlock)(AFHTTPRequestOperation *operation, NSError *failure) = ^void(AFHTTPRequestOperation *operation, NSError *error) { 138 | if (completion) { 139 | completion(object,nil,error); 140 | } 141 | 142 | }; 143 | 144 | NSString *path = nil; 145 | if ([object isKindOfClass:[OSMKNode class]]) { 146 | path = @"node"; 147 | } 148 | else if ([object isKindOfClass:[OSMKWay class]]) { 149 | path = @"way"; 150 | } 151 | else if ([object isKindOfClass:[OSMKRelation class]]) { 152 | path = @"relation"; 153 | } 154 | 155 | if ([path length] && object.osmId > 0) { 156 | path = [path stringByAppendingFormat:@"/%lld",object.osmId]; 157 | } 158 | else { 159 | return; 160 | } 161 | 162 | if (object.action == OSMKElementActionNew) { 163 | path = [path stringByAppendingString:@"/create"]; 164 | } 165 | 166 | AFHTTPRequestOperation *request = nil; 167 | 168 | switch (object.action) { 169 | case OSMKElementActionModified: 170 | case OSMKElementActionNew: 171 | { 172 | DDXMLElement *element = [self osmElement]; 173 | [element addChild:[object PUTElementForChangeset:changesetID]]; 174 | request = [self PUT:path XML:[[element compactXMLString] dataUsingEncoding:NSUTF8StringEncoding] success:successBlock failure:failureBlock]; 175 | break; 176 | } 177 | case OSMKElementActionDelete: 178 | { 179 | DDXMLElement *element = [self osmElement]; 180 | [element addChild:[object DELETEEelementForChangeset:changesetID]]; 181 | request = [self DELETE:path XML:[[element compactXMLString] dataUsingEncoding:NSUTF8StringEncoding] success:successBlock failure:failureBlock]; 182 | break; 183 | } 184 | 185 | 186 | default: 187 | if (completion) { 188 | completion(object,nil,[NSError errorWithDomain:@"" code:101 userInfo:nil]); 189 | } 190 | break; 191 | } 192 | 193 | } 194 | 195 | - (void)uploadElements:(NSArray *)elements 196 | changesetID:(NSNumber *)changesetID 197 | success:(void (^)(NSArray * completed))success 198 | failure:(void (^)(OSMKObject * element, NSError * error))failure 199 | { 200 | NSMutableArray *successfulElements = [NSMutableArray new]; 201 | 202 | [elements enumerateObjectsUsingBlock:^(OSMKObject *object, NSUInteger idx, BOOL *stop) { 203 | [self uploadElement:object changesetID:changesetID completion:^(OSMKObject *element, id response, NSError *error) { 204 | if (!error) { 205 | 206 | if (element.osmId > 0) { 207 | element.version = [response intValue]; 208 | } 209 | else { 210 | element.osmId = [response longLongValue]; 211 | } 212 | 213 | [successfulElements addObject:element]; 214 | if ([successfulElements count] == [elements count] && success) { 215 | success(successfulElements); 216 | } 217 | } 218 | else if(failure){ 219 | *stop = YES; 220 | failure(element,error); 221 | } 222 | 223 | }]; 224 | }]; 225 | } 226 | 227 | - (void)uploadChangeset:(OSMKChangeset *)changeset 228 | success:(void (^)(NSArray *completedNodes, NSArray *completedWays, NSArray *completedRelations))success 229 | failure:(void (^)(OSMKObject * element, NSError * error))failure; 230 | { 231 | __block NSArray *completedNodes = nil; 232 | __block NSArray *completedWays = nil; 233 | __block NSArray *completedRelations = nil; 234 | 235 | [self uploadElements:changeset.nodes changesetID:@(changeset.changesetID) success:^(NSArray *completed) { 236 | completedNodes = completed; 237 | [self uploadElements:changeset.ways changesetID:@(changeset.changesetID) success:^(NSArray *completed) { 238 | completedWays = completed; 239 | [self uploadElements:changeset.relations changesetID:@(changeset.changesetID) success:^(NSArray *completed) { 240 | completedRelations = completed; 241 | if (success) { 242 | success(completedNodes,completedWays,completedRelations); 243 | } 244 | } failure:failure]; 245 | } failure:failure]; 246 | } failure:failure]; 247 | 248 | } 249 | 250 | -(void)closeChangeset:(int64_t) changesetNumber 251 | success:(void (^)(id response))success 252 | failure:(void (^)(NSError * error))failure 253 | { 254 | NSString *path = [NSString stringWithFormat:@"changeset/%lld/close",changesetNumber]; 255 | 256 | AFHTTPRequestOperation *operation = [self PUT:path parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 257 | if (success) { 258 | success(responseObject); 259 | } 260 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 261 | if (failure) { 262 | failure(error); 263 | } 264 | }]; 265 | [operation start]; 266 | 267 | } 268 | 269 | ////// Notes ////// 270 | 271 | -(void)createNewNote:(OSMKNote *)note 272 | success:(void (^)(NSData * response))success 273 | failure:(void (^)(NSError *error))failure 274 | { 275 | OSMKComment *comment = [note.commentsArray firstObject]; 276 | if ([comment.text length]) { 277 | NSDictionary *parameters = @{@"lat":@(note.latitude),@"lon":@(note.longitude),@"text":comment.text}; 278 | [self POST:@"notes.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { 279 | if (success) { 280 | success(responseObject); 281 | } 282 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 283 | if (failure) { 284 | failure(error); 285 | } 286 | }]; 287 | } 288 | 289 | } 290 | 291 | -(void)createNewComment:(OSMKComment *)comment 292 | withNote:(OSMKNote *)note 293 | success:(void (^)(id JSON))success 294 | failure:(void (^)(NSError *error))failure 295 | { 296 | if ([comment.text length]) { 297 | NSString *path = [NSString stringWithFormat:@"notes/%lld/comment.json",note.osmId]; 298 | [self POST:path parameters:@{@"text":comment.text} success:^(AFHTTPRequestOperation *operation, id responseObject) { 299 | if (success) { 300 | success(responseObject); 301 | } 302 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 303 | if (failure) { 304 | failure(error); 305 | } 306 | }]; 307 | } 308 | 309 | 310 | } 311 | 312 | -(void)closeNote:(OSMKNote *)note 313 | withComment:(OSMKComment *)comment 314 | success:(void (^)(id JSON))success 315 | failure:(void (^)(NSError *error))failure 316 | { 317 | NSDictionary *parameters = nil; 318 | if ([comment.text length]) { 319 | parameters = @{@"text":comment.text}; 320 | } 321 | 322 | NSString *path = [NSString stringWithFormat:@"notes/%lld/close.json",note.osmId]; 323 | 324 | [self POST:path parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { 325 | if (success) { 326 | success(responseObject); 327 | } 328 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 329 | if (failure) { 330 | failure(error); 331 | } 332 | }]; 333 | } 334 | 335 | -(void)reopenNote:(OSMKNote *)note 336 | withComment:(OSMKComment *)comment 337 | success:(void (^)(NSData * response))success 338 | failure:(void (^)(NSError *error))failure 339 | { 340 | NSDictionary *parameters = nil; 341 | if ([comment.text length]) { 342 | parameters = @{@"text":comment.text}; 343 | } 344 | 345 | NSString *path = [NSString stringWithFormat:@"notes/%lld/reopen.json",note.osmId]; 346 | 347 | [self POST:path parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { 348 | if (success) { 349 | success(responseObject); 350 | } 351 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 352 | if (failure) { 353 | failure(error); 354 | } 355 | }]; 356 | } 357 | 358 | 359 | ////////// User ////////////// 360 | - (void)fetchCurrentUserWithComletion:(void (^)(id response,NSError *error))completionBlock; 361 | { 362 | [self GET:@"user/details" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 363 | if (completionBlock) { 364 | completionBlock(responseObject,nil); 365 | } 366 | } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 367 | if (completionBlock) { 368 | completionBlock(nil,error); 369 | } 370 | }]; 371 | } 372 | 373 | #pragma - mark XML Utility Methods 374 | 375 | - (DDXMLElement *)osmElement 376 | { 377 | DDXMLNode *osmVersion = [DDXMLNode elementWithName:@"version" stringValue:@"0.6"]; 378 | DDXMLNode *osmGenerator = [DDXMLNode elementWithName:@"generator" stringValue:@"OSMKit"]; 379 | DDXMLElement *osmElement = [DDXMLElement elementWithName:@"osm" children:nil attributes:@[osmVersion,osmGenerator]]; 380 | 381 | DDXMLNode *version = [DDXMLNode elementWithName:@"version" stringValue:@"1.0"]; 382 | DDXMLNode *encoding = [DDXMLNode elementWithName:@"encoding" stringValue:@"UTF-8"]; 383 | DDXMLElement *element = [DDXMLElement elementWithName:@"xml" children:@[osmElement] attributes:@[version,encoding]]; 384 | 385 | return element; 386 | } 387 | 388 | #pragma - mark HTTP mehtods 389 | 390 | - (AFHTTPRequestOperation *)PUT:(NSString *)URLString XML:(NSData *)xmlData success:(void (^)(AFHTTPRequestOperation *, id response))success failure:(void (^)(AFHTTPRequestOperation *, NSError *failure))failure 391 | { 392 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"PUT" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; 393 | request.HTTPBody = xmlData; 394 | [request setValue:OSMKContentType forHTTPHeaderField:@"Content-Type"]; 395 | AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; 396 | [self.operationQueue addOperation:operation]; 397 | 398 | return operation; 399 | } 400 | 401 | - (AFHTTPRequestOperation *)DELETE:(NSString *)URLString XML:(NSData *)xmlData success:(void (^)(AFHTTPRequestOperation *, id))success failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure 402 | { 403 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"DELETE" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:nil error:nil]; 404 | request.HTTPBody = xmlData; 405 | [request setValue:OSMKContentType forHTTPHeaderField:@"Content-Type"]; 406 | AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; 407 | [self.operationQueue addOperation:operation]; 408 | 409 | return operation; 410 | } 411 | 412 | @end 413 | -------------------------------------------------------------------------------- /OSMKit/Storage/FMDatabase+OSMKitSpatiaLite.m: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabase+OSMKit.m 3 | // Pods 4 | // 5 | // Created by David Chiles on 12/15/14. 6 | // 7 | // 8 | 9 | #import "FMDatabase+OSMKitSpatiaLite.h" 10 | 11 | #import "OSMKNode.h" 12 | #import "OSMKWay.h" 13 | #import "OSMKRelation.h" 14 | #import "OSMKUser.h" 15 | #import "OSMKNote.h" 16 | #import "OSMKConstants.h" 17 | #import "ShapeKit.h" 18 | #import "OSMKRelationMember.h" 19 | #import "OSMKComment.h" 20 | 21 | @implementation FMDatabase (OSMKitSpatiaLite) 22 | 23 | #pragma - mark Setup Method 24 | 25 | - (BOOL)osmk_setupDatabaseWithOverwrite:(BOOL)overwrite 26 | { 27 | BOOL sucess = YES; 28 | if (overwrite) { 29 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"DROP TABLE IF EXISTS %@",OSMKNodeElementName]]; 30 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"DROP TABLE IF EXISTS %@_%@",OSMKNodeElementName,OSMKTagElementName]]; 31 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"DROP TABLE IF EXISTS %@",OSMKWayElementName]]; 32 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"DROP TABLE IF EXISTS %@_%@",OSMKWayElementName,OSMKTagElementName]]; 33 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"DROP TABLE IF EXISTS %@_%@",OSMKWayElementName,OSMKNodeElementName]]; 34 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"DROP TABLE IF EXISTS %@",OSMKRelationElementName]]; 35 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"DROP TABLE IF EXISTS %@_%@",OSMKRelationElementName,OSMKTagElementName]]; 36 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"DROP TABLE IF EXISTS %@_%@",OSMKRelationElementName,OSMKRelationMemberElementName]]; 37 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"DROP TABLE IF EXISTS %@",OSMKNoteElementName]]; 38 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"DROP TABLE IF EXISTS %@_%@",OSMKNoteElementName,OSMKNoteCommentsElementName]]; 39 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"DROP TABLE IF EXISTS %@",OSMKUserElementName]]; 40 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"DROP TABLE IF EXISTS %@_%@",OSMKUserElementName,OSMKUserRolesElementName]]; 41 | } 42 | 43 | FMResultSet *resultSet = [self executeQuery:@"SELECT InitSpatialMetaData();"]; 44 | if ([resultSet next]) { 45 | NSLog(@"%@",[resultSet resultDictionary]); 46 | } 47 | 48 | ////// Nodes ////// 49 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@ (node_id INTEGER PRIMARY KEY NOT NULL,version INTEGER ,changeset INTEGER, user_id INTEGER, visible INTEGER,user TEXT,action TEXT, time_stamp TEXT)",OSMKNodeElementName]]; 50 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat: @"CREATE TABLE IF NOT EXISTS %@_%@ (node_id INTEGER REFERENCES %@ ( way_id ), key TEXT NOT NULL,value TEXT NOT NULL, UNIQUE ( node_id, key, value ))",OSMKNodeElementName,OSMKTagElementName,OSMKWayNodeElementName]]; 51 | 52 | resultSet = [self executeQueryWithFormat:[NSString stringWithFormat: @"SELECT AddGeometryColumn('%@', 'geom', 4326, 'POINT', 'XY')",OSMKNodeElementName]]; 53 | if ([resultSet next]) { 54 | NSArray *values = [[resultSet resultDictionary] allValues]; 55 | //sucess = [[values firstObject] boolValue]; 56 | } 57 | 58 | ////// Ways ////// 59 | if (sucess) sucess = [self executeUpdateWithFormat:[NSString stringWithFormat: @"CREATE TABLE IF NOT EXISTS %@ (way_id INTEGER PRIMARY KEY NOT NULL,version INTEGER ,changeset INTEGER, user_id INTEGER, visible INTEGER,user TEXT,action INTEGER, time_stamp TEXT)",OSMKWayElementName]]; 60 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat: @"CREATE TABLE IF NOT EXISTS %@_%@ (way_id INTEGER REFERENCES %@ ( way_id ), key TEXT NOT NULL,value TEXT NOT NULL, UNIQUE ( way_id, key, value ))",OSMKWayElementName,OSMKTagElementName,OSMKWayElementName]]; 61 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat: @"CREATE TABLE IF NOT EXISTS %@_%@ (way_id INTEGER REFERENCES %@ ( way_id ), node_id INTEGER REFERENCES %@ ( id ), local_order INTEGER, UNIQUE ( way_id, local_order ))",OSMKWayElementName,OSMKNodeElementName,OSMKWayElementName,OSMKNodeElementName]]; 62 | 63 | resultSet = [self executeQuery:[NSString stringWithFormat: @"SELECT AddGeometryColumn('%@', 'geom', 4326, 'LINESTRING', 2)",OSMKWayElementName]]; 64 | if ([resultSet next]) { 65 | NSArray *values = [[resultSet resultDictionary] allValues]; 66 | //sucess = [[values firstObject] boolValue]; 67 | } 68 | 69 | ////// Relations ////// 70 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat: @"CREATE TABLE IF NOT EXISTS %@ (relation_id INTEGER PRIMARY KEY NOT NULL,version INTEGER ,changeset INTEGER, user_id INTEGER, visible INTEGER,user TEXT,action INTEGER, time_stamp TEXT)",OSMKRelationElementName]]; 71 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS %@_%@ (relation_id INTEGER REFERENCES %@ ( relation_id ), key TEXT NOT NULL,value TEXT NOT NULL, UNIQUE ( relation_id, key, value ))",OSMKRelationElementName,OSMKTagElementName,OSMKRelationElementName]]; 72 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat: @"CREATE TABLE IF NOT EXISTS %@_%@ (relation_id INTEGER REFERENCES %@ ( relation_id ), type TEXT CHECK ( type IN (\"%@\", \"%@\", \"%@\")),ref INTEGER NOT NULL , role TEXT, local_order INTEGER,UNIQUE (relation_id,ref,local_order) )",OSMKRelationElementName,OSMKRelationMemberElementName,OSMKRelationElementName,OSMKNodeElementName,OSMKWayElementName,OSMKRelationElementName]]; 73 | 74 | ////// Notes ////// 75 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat: @"CREATE TABLE IF NOT EXISTS %@ (note_id INTEGER PRIMARY KEY NOT NULL, open INTEGER, date_created TEXT, date_closed TEXT)",OSMKNoteElementName]]; 76 | 77 | resultSet = [self executeQuery:[NSString stringWithFormat:@"SELECT AddGeometryColumn('%@', 'geom', 4326, 'POINT', 'XY')",OSMKNoteElementName]]; 78 | if ([resultSet next]) { 79 | NSArray *values = [[resultSet resultDictionary] allValues]; 80 | sucess = [[values firstObject] boolValue]; 81 | } 82 | 83 | ////// Comments ////// 84 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat: @"CREATE TABLE IF NOT EXISTS %@_%@ (note_id INTEGER REFERENCES %@ ( note_id ), user_id INTEGER,user TEXT, date TEXT, text TEXT, action TEXT, local_order INTEGER)",OSMKNoteElementName,OSMKNoteCommentsElementName,OSMKNoteElementName]]; 85 | 86 | ////// Users ////// 87 | 88 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat: @"CREATE TABLE IF NOT EXISTS %@ (user_id INTEGER, display_name TEXT, date_created TEXT, image_url TEXT, user_description TEXT, terms_agreed INTEGER, changeset_count INTEGER, trace_count INTEGER,received_blocks INTEGER, active_received_blocks INTEGER, issued_blocks INTEGER, active_issued_blocks INTEGER)",OSMKUserElementName]]; 89 | 90 | if (sucess) sucess = [self executeUpdate:[NSString stringWithFormat: @"CREATE TABLE IF NOT EXISTS %@_%@ (user_id INTEGER REFERENCES %@ (user_id), role TEXT)",OSMKUserElementName,OSMKUserRolesElementName,OSMKUserElementName]]; 91 | 92 | return sucess; 93 | } 94 | 95 | #pragma - mark Saving Methods 96 | 97 | - (BOOL)osmk_saveNode:(OSMKNode *)node error:(NSError **)error 98 | { 99 | BOOL result = NO; 100 | if ([node isKindOfClass:[OSMKNode class]]) { 101 | //INSERT or Replace in node table 102 | __block NSString *geomString = [NSString stringWithFormat:@"GeomFromText('POINT(%f %f)', 4326)",node.latitude,node.longitude]; 103 | __block NSString *updateString = [NSString stringWithFormat:@"INSERT OR REPLACE INTO %@ (node_id,version,changeset,user_id,visible,user,action,time_stamp,geom) VALUES (?,?,?,?,?,?,?,?,%@)",[[self class] osmk_tableNameForObject:node],geomString]; 104 | 105 | BOOL nodeResult = [self executeUpdate:updateString,@(node.osmId),@(node.version),@(node.changeset),@(node.userId),@(node.visible),node.user,@(node.action),node.timeStamp]; 106 | 107 | //Delete any existing tags 108 | NSString *sqlString =[NSString stringWithFormat:@"DELETE FROM %@ WHERE node_id = ?",[[self class] osmk_tagTableNameForObject:node]]; 109 | BOOL tagDeleteResult = [self executeUpdate:sqlString withArgumentsInArray:@[@(node.osmId)]]; 110 | 111 | //Insert tags 112 | __block BOOL tagInsertResult = YES; 113 | [node.tags enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 114 | NSString *tableName = [[self class] osmk_tagTableNameForObject:node]; 115 | NSString *insertString = [NSString stringWithFormat:@"INSERT INTO %@ (node_id, key, value) VALUES (?,?,?)",tableName]; 116 | tagInsertResult = [self executeUpdate:insertString,@(node.osmId),key,obj]; 117 | if (!tagInsertResult) { 118 | *stop = YES; 119 | } 120 | }]; 121 | 122 | result = nodeResult && tagDeleteResult && tagInsertResult; 123 | 124 | if (!result) { 125 | //FIXME error failed 126 | } 127 | } 128 | return result; 129 | } 130 | 131 | - (BOOL)osmk_saveWay:(OSMKWay *)way error:(NSError **)error 132 | { 133 | if ([way isKindOfClass:[OSMKWay class]]) { 134 | //FIXME check if version is good 135 | 136 | NSMutableArray *pointStringArray = [[NSMutableArray alloc] initWithCapacity:[way.nodes count]]; 137 | 138 | //DELETE all old ways_nodes that might be in the database 139 | NSString *deleteString = [NSString stringWithFormat:@"DELETE FROM way_node WHERE way_id == ?",[[self class] osmk_tagTableNameForObject:way]]; 140 | BOOL deleteNodesResult = [self executeUpdate:deleteString withArgumentsInArray:@[@(way.osmId)]]; 141 | __block BOOL nodeInsertResult = YES; 142 | 143 | [way.nodes enumerateObjectsUsingBlock:^(NSNumber *nodeId, NSUInteger idx, BOOL *stop) { 144 | // about 10% speed up if we don't have to go to the database to look up node coordinate 145 | CLLocationCoordinate2D nodeCenter = [self osmk_coordinateOfNodeWithId:[nodeId longLongValue]]; 146 | 147 | if (nodeCenter.latitude != DBL_MAX) { 148 | [pointStringArray addObject:[NSString stringWithFormat:@"%f %f",nodeCenter.latitude,nodeCenter.longitude]]; 149 | } 150 | 151 | //INSERT all the new way_nodes into the database 152 | nodeInsertResult = [self executeUpdate:@"INSERT INTO way_node (way_id,node_id,local_order) VALUES (?,?,?)",@(way.osmId),nodeId,@(idx)]; 153 | if (!nodeInsertResult) { 154 | *stop = YES; 155 | } 156 | 157 | }]; 158 | 159 | NSString *geomString = [NSString stringWithFormat:@"GeomFromText('LINESTRING( %@ )', 4326)",[pointStringArray componentsJoinedByString:@","]]; 160 | 161 | NSString *updateString = [NSString stringWithFormat:@"INSERT OR REPLACE INTO %@ (way_id,version,changeset,user_id,visible,user,action,time_stamp,geom) VALUES (?,?,?,?,?,?,?,?,%@)",[[self class] osmk_tableNameForObject:way],geomString]; 162 | 163 | //INSERT Way into database 164 | BOOL wayResult = [self executeUpdate:updateString,@(way.osmId),@(way.version),@(way.changeset),@(way.userId),@(way.visible),way.user,way.action,way.timeStamp]; 165 | 166 | //Delete Tags 167 | NSString *deleteTagString = [NSString stringWithFormat:@"DELETE FROM %@ WHERE way_id = ?",[[self class] osmk_tagTableNameForObject:way]]; 168 | BOOL tagDeleteResult = [self executeUpdate:deleteTagString withArgumentsInArray:@[@(way.osmId)]]; 169 | 170 | 171 | //INsert new tags 172 | __block BOOL tagInsertResult = YES; 173 | [way.tags enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 174 | NSString *insertString = [NSString stringWithFormat:@"INSERT INTO %@ (way_id, key, value) VALUES (?,?,?)",[[self class] osmk_tagTableNameForObject:way]]; 175 | tagInsertResult = [self executeUpdate:insertString,@(way.osmId),key,obj]; 176 | if (!tagInsertResult) { 177 | *stop = YES; 178 | } 179 | }]; 180 | 181 | if (!(tagDeleteResult && tagInsertResult && wayResult && nodeInsertResult && deleteNodesResult)) { 182 | //FIXME error 183 | } 184 | return YES; 185 | } 186 | return NO; 187 | } 188 | 189 | - (BOOL)osmk_saveRelation:(OSMKRelation *)relation error:(NSError **)error 190 | { 191 | if ([relation isKindOfClass:[OSMKRelation class]]) { 192 | 193 | NSString *insertString = [NSString stringWithFormat:@"INSERT OR REPLACE INTO %@ (relation_id,version,changeset,user_id,visible,user,action,time_stamp) VALUES (?,?,?,?,?,?,?,?)",[[self class] osmk_tableNameForObject:relation]]; 194 | BOOL insertRelationResult = [self executeUpdate:insertString,@(relation.osmId),@(relation.version),@(relation.changeset),@(relation.userId),@(relation.visible),relation.user,@(relation.action),relation.timeStamp]; 195 | 196 | BOOL deleteRelationMembersResults = [self executeUpdate:@"DELETE FROM relation_member WHERE relation_id = ?",@(relation.osmId)]; 197 | 198 | __block BOOL insertMembersResult = YES; 199 | [relation.members enumerateObjectsUsingBlock:^(OSMKRelationMember *member, NSUInteger idx, BOOL *stop) { 200 | 201 | insertMembersResult = [self executeUpdate:@"INSERT INTO relation_member (relation_id,type,ref,role,local_order) VALUES (?,?,?,?,?)",@(relation.osmId),[OSMKObject stringForType:member.type],@(member.ref),member.role,@(idx)]; 202 | 203 | }]; 204 | 205 | NSString *tagDeleteString = [NSString stringWithFormat:@"DELETE FROM %@ WHERE relation_id = ?",[[self class] osmk_tagTableNameForObject:relation]]; 206 | BOOL deleteTagsResult = [self executeUpdate:tagDeleteString,@(relation.osmId)]; 207 | 208 | __block BOOL tagInsertResult = YES; 209 | [relation.tags enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 210 | NSString *tagInsertString = [NSString stringWithFormat:@"INSERT INTO %@ (relation_id, key, value) VALUES (?,?,?)",[[self class] osmk_tagTableNameForObject:relation]]; 211 | tagInsertResult = [self executeUpdate:tagInsertString,@(relation.osmId),key,obj]; 212 | if (!tagInsertResult) { 213 | *stop = YES; 214 | } 215 | }]; 216 | 217 | if (!(deleteTagsResult && tagInsertResult && insertMembersResult && insertRelationResult &&deleteRelationMembersResults)) { 218 | //FIXME ERROR 219 | } 220 | return YES; 221 | } 222 | return NO; 223 | } 224 | 225 | - (BOOL)osmk_saveUser:(OSMKUser *)user error:(NSError **)error 226 | { 227 | BOOL result = NO; 228 | if (user) { 229 | BOOL insertResult = [self executeUpdateWithFormat:@"INSERT OR REPLACE INTO user (user_id,display_name,date_created,image_url,user_description,terms_agreed,changeset_count,trace_count,received_blocks,active_received_blocks,issued_blocks,active_issued_blocks) VALUES (%lld,%@,%@,%@,%@,%d,%d,%d,%d,%d,%d,%d)",user.osmId,user.displayName,user.dateCreated,user.imageUrl,user.userDescription,user.termsAgreed,user.changesetCount,user.traceCount,user.receivedBlocks,user.activeReceivedBlocks,user.issuedBlocks,user.activeIssuedBlocks]; 230 | 231 | BOOL deleteResult = [self executeUpdateWithFormat:@"DELETE FROM user_roles WHERE user_id = %lld",user.osmId]; 232 | 233 | 234 | __block BOOL updateRoles = YES; 235 | [user.roles enumerateObjectsUsingBlock:^(NSString *role, BOOL *stop) { 236 | updateRoles = [self executeUpdateWithFormat:@"INSERT INTO user_roles (user_id,role) VALUES (%lld,%@)",user.osmId,role]; 237 | 238 | if (!updateRoles) { 239 | *stop = YES; 240 | } 241 | }]; 242 | 243 | result = insertResult && deleteResult && updateRoles; 244 | } 245 | 246 | return result; 247 | } 248 | 249 | - (BOOL)osmk_saveNote:(OSMKNote *)note error:(NSError **)error 250 | { 251 | BOOL result = NO; 252 | 253 | if (note) { 254 | NSString *geomString = [NSString stringWithFormat:@"GeomFromText('POINT(%f %f)', 4326)",note.latitude, note.longitude]; 255 | NSString *updateString = [NSString stringWithFormat:@"INSERT OR REPLACE INTO %@ (note_id,open,date_created,date_closed,geom) VALUES (?,?,?,?,%@)",[[self class] osmk_tableNameForObject:note],geomString]; 256 | BOOL noteResult = [self executeUpdate:updateString,@(note.osmId),@(note.isOpen),note.dateCreated,note.dateClosed]; 257 | 258 | BOOL deleteCommentsResult = [self executeUpdateWithFormat:@"DELETE FROM note_comments WHERE note_id = %lld",note.osmId]; 259 | 260 | __block BOOL insertCommentsReults = YES; 261 | [note.commentsArray enumerateObjectsUsingBlock:^(OSMKComment *comment, NSUInteger idx, BOOL *stop) { 262 | 263 | insertCommentsReults = [self executeUpdateWithFormat:@"INSERT INTO note_comments (note_id,user_id,user,date,text,action,local_order) VALUES (%lld,%lld,%@,%@,%@,%@,%d)",note.osmId,comment.userId,comment.user,comment.date,comment.text,comment.action,idx]; 264 | 265 | if (!insertCommentsReults) { 266 | *stop = YES; 267 | } 268 | 269 | }]; 270 | 271 | result = noteResult && deleteCommentsResult && insertCommentsReults; 272 | } 273 | 274 | return result; 275 | } 276 | 277 | #pragma - mark Fetching Methods 278 | 279 | - (OSMKNode *)osmk_nodeWithOsmId:(int64_t)nodeId 280 | { 281 | OSMKNode *node = [self osmk_elementForType:OSMKElementTypeNode elementId:nodeId]; 282 | if (node) { 283 | node.tags = [self osmk_tagsForElementType:OSMKElementTypeNode elementId:node.osmId]; 284 | } 285 | 286 | return node; 287 | } 288 | 289 | - (OSMKWay *)osmk_wayWithOsmId:(int64_t)osmId 290 | { 291 | OSMKWay *way = [self osmk_elementForType:OSMKElementTypeWay elementId:osmId]; 292 | if (way) { 293 | way.tags = [self osmk_tagsForElementType:OSMKElementTypeWay elementId:osmId]; 294 | 295 | FMResultSet *resultSet = [self executeQuery:@"SELECT * FROM way_node WHERE way_id = ? ORDER BY local_order",@(osmId)]; 296 | 297 | NSMutableArray *nodeIds = [NSMutableArray array]; 298 | while ([resultSet next]) { 299 | int64_t nodeId = [resultSet longLongIntForColumn:@"node_id"]; 300 | if (nodeId) { 301 | [nodeIds addObject:@(nodeId)]; 302 | } 303 | } 304 | 305 | if ([nodeIds count]) { 306 | way.nodes = [nodeIds copy]; 307 | } 308 | } 309 | return way; 310 | } 311 | 312 | - (OSMKRelation *)osmk_relationWithOsmId:(int64_t)osmId 313 | { 314 | OSMKRelation *relation = [self osmk_elementForType:OSMKElementTypeRelation elementId:osmId]; 315 | if (relation) { 316 | relation.tags = [self osmk_tagsForElementType:OSMKElementTypeRelation elementId:osmId]; 317 | 318 | FMResultSet *resultSet = [self executeQuery:@"SELECT * FROM relation_member WHERE relation_id = ? ORDER BY local_order",@(osmId)]; 319 | 320 | NSMutableArray *membersMutable = [NSMutableArray array]; 321 | while ([resultSet next]) { 322 | OSMKRelationMember *relationMember = [[OSMKRelationMember alloc] initWithAttributesDictionary:[resultSet resultDictionary]]; 323 | 324 | if (relationMember) { 325 | [membersMutable addObject:relationMember]; 326 | } 327 | } 328 | relation.members = [membersMutable copy]; 329 | } 330 | return relation; 331 | } 332 | 333 | - (id)osmk_elementForType:(OSMKElementType)elementType elementId:(int64_t)elementId 334 | { 335 | NSString *tableName = [NSString stringWithFormat:@"%@s",[OSMKObject stringForType:elementType]]; 336 | NSString *idColumnName = [NSString stringWithFormat:@"%@_id",[OSMKObject stringForType:elementType]]; 337 | 338 | NSString *query = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ = %lld LIMIT 1",tableName,idColumnName,elementId]; 339 | 340 | FMResultSet *resultSet = [self executeQuery:query]; 341 | OSMKObject *object = nil; 342 | if (resultSet.next) { 343 | object = (OSMKObject *)[OSMKObject objectForType:elementType elementId:elementId]; 344 | 345 | object.action = [resultSet intForColumn:@"action"]; 346 | object.changeset = [resultSet longForColumn:@"changeset"]; 347 | //FIXME object.timeStamp = [resultSet dateForColumn:@"time_stamp"]; 348 | object.user = [resultSet stringForColumn:@"user"]; 349 | object.version = [resultSet intForColumn:@"version"]; 350 | object.visible = [resultSet boolForColumn:@"visible"]; 351 | object.userId = [resultSet longLongIntForColumn:@"user_id"]; 352 | if (elementType == OSMKElementTypeNode) { 353 | ShapeKitPoint *point = [resultSet objectForColumnName:@"geom"]; 354 | ((OSMKNode *)object).coordinate = point.coordinate; 355 | } 356 | } 357 | 358 | return object; 359 | } 360 | 361 | - (NSDictionary *)osmk_tagsForElementType:(OSMKElementType)elementType elementId:(int64_t)elementId 362 | { 363 | NSString *tableName = [NSString stringWithFormat:@"%@s_tags",[OSMKObject stringForType:elementType]]; 364 | NSString *idColumnName = [NSString stringWithFormat:@"%@_id",[OSMKObject stringForType:elementType]]; 365 | 366 | NSString *query = [NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@ = %lld",tableName,idColumnName,elementId]; 367 | FMResultSet *resultSet = [self executeQuery:query]; 368 | NSMutableDictionary *mutableTags = [NSMutableDictionary dictionary]; 369 | while (resultSet.next) { 370 | NSString *key = [resultSet stringForColumn:@"key"]; 371 | NSString *value = [resultSet stringForColumn:@"value"]; 372 | if (key && value) { 373 | mutableTags[key] = value; 374 | } 375 | } 376 | 377 | if ([mutableTags count]) { 378 | return [mutableTags copy]; 379 | } 380 | return nil; 381 | } 382 | 383 | - (OSMKUser *)osmk_userWithOsmId:(int64_t)osmId 384 | { 385 | OSMKUser *user = [[OSMKUser alloc] initWIthOsmId:osmId]; 386 | 387 | FMResultSet *resultsSet = [self executeQuery:[NSString stringWithFormat:@"SELECT * FROM %@ WHERE user_id = %lld LIMIT 1",[[self class] osmk_tableNameForObject:user],@(osmId)]]; 388 | if ([resultsSet next]) { 389 | user.displayName = [resultsSet stringForColumn:@"display_name"]; 390 | user.dateCreated = [resultsSet dateForColumn:@"date_created"]; 391 | user.imageUrl = [NSURL URLWithString:[resultsSet stringForColumn:@"image_url"]]; 392 | user.userDescription = [resultsSet stringForColumn:@"user_description"]; 393 | user.termsAgreed = [resultsSet boolForColumn:@"terms_agreed"]; 394 | user.changesetCount = [resultsSet intForColumn:@"changeset_count"]; 395 | user.traceCount = [resultsSet intForColumn:@"trace_count"]; 396 | user.receivedBlocks = [resultsSet intForColumn:@"received_blocks"]; 397 | user.activeReceivedBlocks = [resultsSet intForColumn:@"active_received_blocks"]; 398 | user.issuedBlocks = [resultsSet intForColumn:@"issued_blocks"]; 399 | user.activeReceivedBlocks = [resultsSet intForColumn:@"active_issued_blocks"]; 400 | } else { 401 | user = nil; 402 | } 403 | 404 | if (user) { 405 | FMResultSet *rolesResultSet = [self executeQuery:@"SELECT * FROM user_roles WHERE user_id = ?",@(osmId)]; 406 | 407 | NSMutableSet *roleMutableSet = [NSMutableSet set]; 408 | while ([rolesResultSet next]) { 409 | NSString *role = [rolesResultSet stringForColumn:@"role"]; 410 | if ([role length]) { 411 | [roleMutableSet addObject:role]; 412 | } 413 | } 414 | user.roles = [roleMutableSet copy]; 415 | } 416 | 417 | return user; 418 | } 419 | 420 | - (OSMKNote *)noteWithOsmId:(int64_t)osmId 421 | { 422 | __block OSMKNote *note = [[OSMKNote alloc] init];; 423 | 424 | FMResultSet *resultSet = [self executeQuery:[NSString stringWithFormat:@"SELECT * from %@ where note_id = ? LIMIT 1",[[self class] osmk_tableNameForObject:note],@(osmId)]]; 425 | 426 | if ([resultSet next]) { 427 | note.osmId = osmId; 428 | note.isOpen = [resultSet boolForColumn:@"open"]; 429 | note.dateCreated = [resultSet dateForColumn:@"date_created"]; 430 | note.dateClosed = [resultSet dateForColumn:@"date_closed"]; 431 | ShapeKitPoint *point = [resultSet objectForColumnName:@"geom"]; 432 | note.coordinate = point.coordinate; 433 | } 434 | else { 435 | note = nil; 436 | } 437 | 438 | if (note) { 439 | resultSet = [self executeQueryWithFormat:@"SELECT * FROM note_comment WHERE note_id = %lld ORDER BY local_order",osmId]; 440 | 441 | NSMutableArray *commentsMutableArray = [NSMutableArray array]; 442 | while ([resultSet next]) { 443 | OSMKComment *comment = [[OSMKComment alloc] init]; 444 | comment.noteId = osmId; 445 | comment.userId = [resultSet longLongIntForColumn:@"user_id"]; 446 | comment.user = [resultSet stringForColumn:@"user"]; 447 | comment.date = [resultSet dateForColumn:@"date"]; 448 | comment.text = [resultSet stringForColumn:@"text"]; 449 | comment.action = [resultSet stringForColumn:@"action"]; 450 | [commentsMutableArray addObject:comment]; 451 | } 452 | 453 | if ([commentsMutableArray count]) { 454 | note.commentsArray = [commentsMutableArray copy]; 455 | } 456 | } 457 | 458 | return note; 459 | } 460 | 461 | 462 | - (CLLocationCoordinate2D)osmk_coordinateOfNodeWithId:(int64_t)nodeId 463 | { 464 | NSString *queryString = [NSString stringWithFormat:@"SELECT geom FROM %@ WHERE node_id = ?",OSMKNodeElementName]; 465 | FMResultSet *resultSet = [self executeQuery:queryString,@(nodeId)]; 466 | 467 | if (resultSet.next) { 468 | ShapeKitPoint *point = [resultSet objectForColumnName:@"geom"]; 469 | return point.coordinate; 470 | } 471 | return CLLocationCoordinate2DMake(DBL_MAX, DBL_MAX); 472 | } 473 | 474 | #pragma - mark Class Methods 475 | 476 | + (NSString *)osmk_tableNameForObject:(id)object 477 | { 478 | if ([object isKindOfClass:[OSMKNode class]]) { 479 | return OSMKNodeElementName; 480 | } 481 | else if ([object isKindOfClass:[OSMKWay class]]) { 482 | return OSMKWayElementName; 483 | } 484 | else if ([object isKindOfClass:[OSMKRelation class]]) { 485 | return OSMKRelationElementName; 486 | } 487 | else if ([object isKindOfClass:[OSMKUser class]]) { 488 | return OSMKUserElementName; 489 | } 490 | else if ([object isKindOfClass:[OSMKNote class]]) { 491 | return OSMKNoteElementName; 492 | } 493 | 494 | return nil; 495 | } 496 | 497 | + (NSString *)osmk_tagTableNameForObject:(OSMKObject *)object 498 | { 499 | return [[self osmk_tableNameForObject:object] stringByAppendingFormat:@"_%@",OSMKTagElementName]; 500 | } 501 | 502 | @end 503 | -------------------------------------------------------------------------------- /Tests/OSMKit.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 251B397885CD48EA8EA69B3D /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C587BF532DF8444F97FEB157 /* libPods.a */; }; 11 | 4FE261B1DAD3428DADC84093 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C587BF532DF8444F97FEB157 /* libPods.a */; }; 12 | 6322F4E81A2EBEA800FA8F71 /* note.json in Resources */ = {isa = PBXBuildFile; fileRef = 6322F4DE1A2EBEA800FA8F71 /* note.json */; }; 13 | 6322F4E91A2EBEA800FA8F71 /* notes.json in Resources */ = {isa = PBXBuildFile; fileRef = 6322F4DF1A2EBEA800FA8F71 /* notes.json */; }; 14 | 6322F4EA1A2EBEA800FA8F71 /* notes.xml in Resources */ = {isa = PBXBuildFile; fileRef = 6322F4E01A2EBEA800FA8F71 /* notes.xml */; }; 15 | 6322F4EB1A2EBEA800FA8F71 /* small_berkeley.osm in Resources */ = {isa = PBXBuildFile; fileRef = 6322F4E11A2EBEA800FA8F71 /* small_berkeley.osm */; }; 16 | 6322F4EC1A2EBEA800FA8F71 /* user.osm in Resources */ = {isa = PBXBuildFile; fileRef = 6322F4E21A2EBEA800FA8F71 /* user.osm */; }; 17 | 6322F4ED1A2EBEA800FA8F71 /* OSMKParserTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6322F4E31A2EBEA800FA8F71 /* OSMKParserTests.m */; }; 18 | 6322F4EE1A2EBEA800FA8F71 /* OSMKStorageTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6322F4E41A2EBEA800FA8F71 /* OSMKStorageTests.m */; }; 19 | 6322F4EF1A2EBEA800FA8F71 /* OSMKTestData.m in Sources */ = {isa = PBXBuildFile; fileRef = 6322F4E61A2EBEA800FA8F71 /* OSMKTestData.m */; }; 20 | 632C3CA318FDE815001E8C69 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 632C3CA218FDE815001E8C69 /* Foundation.framework */; }; 21 | 632C3CA518FDE815001E8C69 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 632C3CA418FDE815001E8C69 /* CoreGraphics.framework */; }; 22 | 632C3CA718FDE815001E8C69 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 632C3CA618FDE815001E8C69 /* UIKit.framework */; }; 23 | 632C3CAD18FDE815001E8C69 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 632C3CAB18FDE815001E8C69 /* InfoPlist.strings */; }; 24 | 632C3CAF18FDE815001E8C69 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 632C3CAE18FDE815001E8C69 /* main.mm */; }; 25 | 632C3CB318FDE815001E8C69 /* OSMKAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 632C3CB218FDE815001E8C69 /* OSMKAppDelegate.m */; }; 26 | 632C3CB518FDE815001E8C69 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 632C3CB418FDE815001E8C69 /* Images.xcassets */; }; 27 | 632C3CBC18FDE815001E8C69 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 632C3CBB18FDE815001E8C69 /* XCTest.framework */; }; 28 | 632C3CBD18FDE815001E8C69 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 632C3CA218FDE815001E8C69 /* Foundation.framework */; }; 29 | 632C3CBE18FDE815001E8C69 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 632C3CA618FDE815001E8C69 /* UIKit.framework */; }; 30 | 632C3CC618FDE815001E8C69 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 632C3CC418FDE815001E8C69 /* InfoPlist.strings */; }; 31 | 635F4FD619469589006D2EF8 /* OSMKAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635F4FD519469589006D2EF8 /* OSMKAPITests.m */; }; 32 | 63A5E4551A68A68A0021EC67 /* OSMKTestImportViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63A5E4541A68A68A0021EC67 /* OSMKTestImportViewController.m */; }; 33 | 63A5E4581A68AB2D0021EC67 /* OSMKTestResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 63A5E4571A68AB2D0021EC67 /* OSMKTestResult.m */; }; 34 | 63C6D5381A2EC66D009FB1B0 /* note.json in Resources */ = {isa = PBXBuildFile; fileRef = 6322F4DE1A2EBEA800FA8F71 /* note.json */; }; 35 | 63C6D5391A2EC672009FB1B0 /* notes.json in Resources */ = {isa = PBXBuildFile; fileRef = 6322F4DF1A2EBEA800FA8F71 /* notes.json */; }; 36 | 63C6D53A1A2EC674009FB1B0 /* notes.xml in Resources */ = {isa = PBXBuildFile; fileRef = 6322F4E01A2EBEA800FA8F71 /* notes.xml */; }; 37 | 63C6D53B1A2EC679009FB1B0 /* small_berkeley.osm in Resources */ = {isa = PBXBuildFile; fileRef = 6322F4E11A2EBEA800FA8F71 /* small_berkeley.osm */; }; 38 | 63C6D53C1A2EC67C009FB1B0 /* user.osm in Resources */ = {isa = PBXBuildFile; fileRef = 6322F4E21A2EBEA800FA8F71 /* user.osm */; }; 39 | 63E409871A2EC6F700C7B5E1 /* berkeley.osm in Resources */ = {isa = PBXBuildFile; fileRef = 63E409861A2EC6F700C7B5E1 /* berkeley.osm */; }; 40 | 63E409881A2EC6F700C7B5E1 /* berkeley.osm in Resources */ = {isa = PBXBuildFile; fileRef = 63E409861A2EC6F700C7B5E1 /* berkeley.osm */; }; 41 | 63F7F7DA1A65FE4B0010D9D5 /* OSMKImporterTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63F7F7D91A65FE4B0010D9D5 /* OSMKImporterTests.m */; }; 42 | /* End PBXBuildFile section */ 43 | 44 | /* Begin PBXContainerItemProxy section */ 45 | 632C3CBF18FDE815001E8C69 /* PBXContainerItemProxy */ = { 46 | isa = PBXContainerItemProxy; 47 | containerPortal = 632C3C9718FDE814001E8C69 /* Project object */; 48 | proxyType = 1; 49 | remoteGlobalIDString = 632C3C9E18FDE815001E8C69; 50 | remoteInfo = OSMKit; 51 | }; 52 | /* End PBXContainerItemProxy section */ 53 | 54 | /* Begin PBXFileReference section */ 55 | 6322F4DE1A2EBEA800FA8F71 /* note.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = note.json; sourceTree = ""; }; 56 | 6322F4DF1A2EBEA800FA8F71 /* notes.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = notes.json; sourceTree = ""; }; 57 | 6322F4E01A2EBEA800FA8F71 /* notes.xml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = notes.xml; sourceTree = ""; }; 58 | 6322F4E11A2EBEA800FA8F71 /* small_berkeley.osm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = small_berkeley.osm; sourceTree = ""; }; 59 | 6322F4E21A2EBEA800FA8F71 /* user.osm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = user.osm; sourceTree = ""; }; 60 | 6322F4E31A2EBEA800FA8F71 /* OSMKParserTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSMKParserTests.m; sourceTree = ""; }; 61 | 6322F4E41A2EBEA800FA8F71 /* OSMKStorageTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSMKStorageTests.m; sourceTree = ""; }; 62 | 6322F4E51A2EBEA800FA8F71 /* OSMKTestData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSMKTestData.h; sourceTree = ""; }; 63 | 6322F4E61A2EBEA800FA8F71 /* OSMKTestData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSMKTestData.m; sourceTree = ""; }; 64 | 632C3C9F18FDE815001E8C69 /* OSMKit.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OSMKit.app; sourceTree = BUILT_PRODUCTS_DIR; }; 65 | 632C3CA218FDE815001E8C69 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 66 | 632C3CA418FDE815001E8C69 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 67 | 632C3CA618FDE815001E8C69 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 68 | 632C3CAA18FDE815001E8C69 /* OSMKit-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "OSMKit-Info.plist"; sourceTree = ""; }; 69 | 632C3CAC18FDE815001E8C69 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 70 | 632C3CAE18FDE815001E8C69 /* main.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; 71 | 632C3CB018FDE815001E8C69 /* OSMKit-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OSMKit-Prefix.pch"; sourceTree = ""; }; 72 | 632C3CB118FDE815001E8C69 /* OSMKAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSMKAppDelegate.h; sourceTree = ""; }; 73 | 632C3CB218FDE815001E8C69 /* OSMKAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OSMKAppDelegate.m; sourceTree = ""; }; 74 | 632C3CB418FDE815001E8C69 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 75 | 632C3CBA18FDE815001E8C69 /* OSMKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OSMKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 76 | 632C3CBB18FDE815001E8C69 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 77 | 632C3CC318FDE815001E8C69 /* OSMKitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "OSMKitTests-Info.plist"; sourceTree = ""; }; 78 | 632C3CC518FDE815001E8C69 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 79 | 635F4FD519469589006D2EF8 /* OSMKAPITests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSMKAPITests.m; sourceTree = ""; }; 80 | 63A5E4531A68A68A0021EC67 /* OSMKTestImportViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSMKTestImportViewController.h; sourceTree = ""; }; 81 | 63A5E4541A68A68A0021EC67 /* OSMKTestImportViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSMKTestImportViewController.m; sourceTree = ""; }; 82 | 63A5E4561A68AB2D0021EC67 /* OSMKTestResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSMKTestResult.h; sourceTree = ""; }; 83 | 63A5E4571A68AB2D0021EC67 /* OSMKTestResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSMKTestResult.m; sourceTree = ""; }; 84 | 63E409861A2EC6F700C7B5E1 /* berkeley.osm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = berkeley.osm; sourceTree = ""; }; 85 | 63F7F7D91A65FE4B0010D9D5 /* OSMKImporterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSMKImporterTests.m; sourceTree = ""; }; 86 | 6D3E5B0C9150F393546435EE /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; 87 | 86E8BF54C163D8B1BD08CA15 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 88 | C587BF532DF8444F97FEB157 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 89 | C9BB6CBA6BAF3C622D98E372 /* libPods-OSMKitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-OSMKitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 90 | /* End PBXFileReference section */ 91 | 92 | /* Begin PBXFrameworksBuildPhase section */ 93 | 632C3C9C18FDE815001E8C69 /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | 632C3CA518FDE815001E8C69 /* CoreGraphics.framework in Frameworks */, 98 | 632C3CA718FDE815001E8C69 /* UIKit.framework in Frameworks */, 99 | 632C3CA318FDE815001E8C69 /* Foundation.framework in Frameworks */, 100 | 4FE261B1DAD3428DADC84093 /* libPods.a in Frameworks */, 101 | ); 102 | runOnlyForDeploymentPostprocessing = 0; 103 | }; 104 | 632C3CB718FDE815001E8C69 /* Frameworks */ = { 105 | isa = PBXFrameworksBuildPhase; 106 | buildActionMask = 2147483647; 107 | files = ( 108 | 632C3CBC18FDE815001E8C69 /* XCTest.framework in Frameworks */, 109 | 632C3CBE18FDE815001E8C69 /* UIKit.framework in Frameworks */, 110 | 632C3CBD18FDE815001E8C69 /* Foundation.framework in Frameworks */, 111 | 251B397885CD48EA8EA69B3D /* libPods.a in Frameworks */, 112 | ); 113 | runOnlyForDeploymentPostprocessing = 0; 114 | }; 115 | /* End PBXFrameworksBuildPhase section */ 116 | 117 | /* Begin PBXGroup section */ 118 | 6322F4DC1A2EBEA800FA8F71 /* Data */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 63E409861A2EC6F700C7B5E1 /* berkeley.osm */, 122 | 6322F4DE1A2EBEA800FA8F71 /* note.json */, 123 | 6322F4DF1A2EBEA800FA8F71 /* notes.json */, 124 | 6322F4E01A2EBEA800FA8F71 /* notes.xml */, 125 | 6322F4E11A2EBEA800FA8F71 /* small_berkeley.osm */, 126 | 6322F4E21A2EBEA800FA8F71 /* user.osm */, 127 | ); 128 | path = Data; 129 | sourceTree = ""; 130 | }; 131 | 632C3C9618FDE814001E8C69 = { 132 | isa = PBXGroup; 133 | children = ( 134 | 632C3CA818FDE815001E8C69 /* OSMKit */, 135 | 632C3CC118FDE815001E8C69 /* OSMKitTests */, 136 | 632C3CA118FDE815001E8C69 /* Frameworks */, 137 | 632C3CA018FDE815001E8C69 /* Products */, 138 | 7940AB360BBB652887495829 /* Pods */, 139 | ); 140 | sourceTree = ""; 141 | }; 142 | 632C3CA018FDE815001E8C69 /* Products */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 632C3C9F18FDE815001E8C69 /* OSMKit.app */, 146 | 632C3CBA18FDE815001E8C69 /* OSMKitTests.xctest */, 147 | ); 148 | name = Products; 149 | sourceTree = ""; 150 | }; 151 | 632C3CA118FDE815001E8C69 /* Frameworks */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 632C3CA218FDE815001E8C69 /* Foundation.framework */, 155 | 632C3CA418FDE815001E8C69 /* CoreGraphics.framework */, 156 | 632C3CA618FDE815001E8C69 /* UIKit.framework */, 157 | 632C3CBB18FDE815001E8C69 /* XCTest.framework */, 158 | C587BF532DF8444F97FEB157 /* libPods.a */, 159 | C9BB6CBA6BAF3C622D98E372 /* libPods-OSMKitTests.a */, 160 | ); 161 | name = Frameworks; 162 | sourceTree = ""; 163 | }; 164 | 632C3CA818FDE815001E8C69 /* OSMKit */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | 632C3CB118FDE815001E8C69 /* OSMKAppDelegate.h */, 168 | 632C3CB218FDE815001E8C69 /* OSMKAppDelegate.m */, 169 | 63A5E4531A68A68A0021EC67 /* OSMKTestImportViewController.h */, 170 | 63A5E4541A68A68A0021EC67 /* OSMKTestImportViewController.m */, 171 | 63A5E4561A68AB2D0021EC67 /* OSMKTestResult.h */, 172 | 63A5E4571A68AB2D0021EC67 /* OSMKTestResult.m */, 173 | 632C3CB418FDE815001E8C69 /* Images.xcassets */, 174 | 632C3CA918FDE815001E8C69 /* Supporting Files */, 175 | ); 176 | path = OSMKit; 177 | sourceTree = ""; 178 | }; 179 | 632C3CA918FDE815001E8C69 /* Supporting Files */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 632C3CAA18FDE815001E8C69 /* OSMKit-Info.plist */, 183 | 632C3CAB18FDE815001E8C69 /* InfoPlist.strings */, 184 | 632C3CAE18FDE815001E8C69 /* main.mm */, 185 | 632C3CB018FDE815001E8C69 /* OSMKit-Prefix.pch */, 186 | ); 187 | name = "Supporting Files"; 188 | sourceTree = ""; 189 | }; 190 | 632C3CC118FDE815001E8C69 /* OSMKitTests */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 6322F4E31A2EBEA800FA8F71 /* OSMKParserTests.m */, 194 | 63F7F7D91A65FE4B0010D9D5 /* OSMKImporterTests.m */, 195 | 6322F4E41A2EBEA800FA8F71 /* OSMKStorageTests.m */, 196 | 635F4FD519469589006D2EF8 /* OSMKAPITests.m */, 197 | 6322F4E51A2EBEA800FA8F71 /* OSMKTestData.h */, 198 | 6322F4E61A2EBEA800FA8F71 /* OSMKTestData.m */, 199 | 6322F4DC1A2EBEA800FA8F71 /* Data */, 200 | 632C3CC218FDE815001E8C69 /* Supporting Files */, 201 | ); 202 | path = OSMKitTests; 203 | sourceTree = ""; 204 | }; 205 | 632C3CC218FDE815001E8C69 /* Supporting Files */ = { 206 | isa = PBXGroup; 207 | children = ( 208 | 632C3CC318FDE815001E8C69 /* OSMKitTests-Info.plist */, 209 | 632C3CC418FDE815001E8C69 /* InfoPlist.strings */, 210 | ); 211 | name = "Supporting Files"; 212 | sourceTree = ""; 213 | }; 214 | 7940AB360BBB652887495829 /* Pods */ = { 215 | isa = PBXGroup; 216 | children = ( 217 | 6D3E5B0C9150F393546435EE /* Pods.debug.xcconfig */, 218 | 86E8BF54C163D8B1BD08CA15 /* Pods.release.xcconfig */, 219 | ); 220 | name = Pods; 221 | sourceTree = ""; 222 | }; 223 | /* End PBXGroup section */ 224 | 225 | /* Begin PBXNativeTarget section */ 226 | 632C3C9E18FDE815001E8C69 /* OSMKit */ = { 227 | isa = PBXNativeTarget; 228 | buildConfigurationList = 632C3CCB18FDE815001E8C69 /* Build configuration list for PBXNativeTarget "OSMKit" */; 229 | buildPhases = ( 230 | F76AA410EFEF48178FB8A1D3 /* Check Pods Manifest.lock */, 231 | 632C3C9B18FDE815001E8C69 /* Sources */, 232 | 632C3C9C18FDE815001E8C69 /* Frameworks */, 233 | 632C3C9D18FDE815001E8C69 /* Resources */, 234 | B19C28EF369E464FB0CD78AD /* Copy Pods Resources */, 235 | ); 236 | buildRules = ( 237 | ); 238 | dependencies = ( 239 | ); 240 | name = OSMKit; 241 | productName = OSMKit; 242 | productReference = 632C3C9F18FDE815001E8C69 /* OSMKit.app */; 243 | productType = "com.apple.product-type.application"; 244 | }; 245 | 632C3CB918FDE815001E8C69 /* OSMKitTests */ = { 246 | isa = PBXNativeTarget; 247 | buildConfigurationList = 632C3CCE18FDE815001E8C69 /* Build configuration list for PBXNativeTarget "OSMKitTests" */; 248 | buildPhases = ( 249 | 5AE6B5120C004514A2572A4C /* Check Pods Manifest.lock */, 250 | 632C3CB618FDE815001E8C69 /* Sources */, 251 | 632C3CB718FDE815001E8C69 /* Frameworks */, 252 | 632C3CB818FDE815001E8C69 /* Resources */, 253 | 83822B81243F4C19AF8DCFAD /* Copy Pods Resources */, 254 | ); 255 | buildRules = ( 256 | ); 257 | dependencies = ( 258 | 632C3CC018FDE815001E8C69 /* PBXTargetDependency */, 259 | ); 260 | name = OSMKitTests; 261 | productName = OSMKitTests; 262 | productReference = 632C3CBA18FDE815001E8C69 /* OSMKitTests.xctest */; 263 | productType = "com.apple.product-type.bundle.unit-test"; 264 | }; 265 | /* End PBXNativeTarget section */ 266 | 267 | /* Begin PBXProject section */ 268 | 632C3C9718FDE814001E8C69 /* Project object */ = { 269 | isa = PBXProject; 270 | attributes = { 271 | CLASSPREFIX = OSMK; 272 | LastUpgradeCheck = 0510; 273 | ORGANIZATIONNAME = davidchiles; 274 | TargetAttributes = { 275 | 632C3C9E18FDE815001E8C69 = { 276 | DevelopmentTeam = SF3NXKQQ64; 277 | }; 278 | 632C3CB918FDE815001E8C69 = { 279 | TestTargetID = 632C3C9E18FDE815001E8C69; 280 | }; 281 | }; 282 | }; 283 | buildConfigurationList = 632C3C9A18FDE814001E8C69 /* Build configuration list for PBXProject "OSMKit" */; 284 | compatibilityVersion = "Xcode 3.2"; 285 | developmentRegion = English; 286 | hasScannedForEncodings = 0; 287 | knownRegions = ( 288 | en, 289 | ); 290 | mainGroup = 632C3C9618FDE814001E8C69; 291 | productRefGroup = 632C3CA018FDE815001E8C69 /* Products */; 292 | projectDirPath = ""; 293 | projectRoot = ""; 294 | targets = ( 295 | 632C3C9E18FDE815001E8C69 /* OSMKit */, 296 | 632C3CB918FDE815001E8C69 /* OSMKitTests */, 297 | ); 298 | }; 299 | /* End PBXProject section */ 300 | 301 | /* Begin PBXResourcesBuildPhase section */ 302 | 632C3C9D18FDE815001E8C69 /* Resources */ = { 303 | isa = PBXResourcesBuildPhase; 304 | buildActionMask = 2147483647; 305 | files = ( 306 | 63C6D53A1A2EC674009FB1B0 /* notes.xml in Resources */, 307 | 63C6D5381A2EC66D009FB1B0 /* note.json in Resources */, 308 | 632C3CAD18FDE815001E8C69 /* InfoPlist.strings in Resources */, 309 | 632C3CB518FDE815001E8C69 /* Images.xcassets in Resources */, 310 | 63E409871A2EC6F700C7B5E1 /* berkeley.osm in Resources */, 311 | 63C6D53B1A2EC679009FB1B0 /* small_berkeley.osm in Resources */, 312 | 63C6D5391A2EC672009FB1B0 /* notes.json in Resources */, 313 | 63C6D53C1A2EC67C009FB1B0 /* user.osm in Resources */, 314 | ); 315 | runOnlyForDeploymentPostprocessing = 0; 316 | }; 317 | 632C3CB818FDE815001E8C69 /* Resources */ = { 318 | isa = PBXResourcesBuildPhase; 319 | buildActionMask = 2147483647; 320 | files = ( 321 | 6322F4EA1A2EBEA800FA8F71 /* notes.xml in Resources */, 322 | 6322F4E81A2EBEA800FA8F71 /* note.json in Resources */, 323 | 632C3CC618FDE815001E8C69 /* InfoPlist.strings in Resources */, 324 | 6322F4EB1A2EBEA800FA8F71 /* small_berkeley.osm in Resources */, 325 | 6322F4E91A2EBEA800FA8F71 /* notes.json in Resources */, 326 | 63E409881A2EC6F700C7B5E1 /* berkeley.osm in Resources */, 327 | 6322F4EC1A2EBEA800FA8F71 /* user.osm in Resources */, 328 | ); 329 | runOnlyForDeploymentPostprocessing = 0; 330 | }; 331 | /* End PBXResourcesBuildPhase section */ 332 | 333 | /* Begin PBXShellScriptBuildPhase section */ 334 | 5AE6B5120C004514A2572A4C /* Check Pods Manifest.lock */ = { 335 | isa = PBXShellScriptBuildPhase; 336 | buildActionMask = 2147483647; 337 | files = ( 338 | ); 339 | inputPaths = ( 340 | ); 341 | name = "Check Pods Manifest.lock"; 342 | outputPaths = ( 343 | ); 344 | runOnlyForDeploymentPostprocessing = 0; 345 | shellPath = /bin/sh; 346 | 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"; 347 | showEnvVarsInLog = 0; 348 | }; 349 | 83822B81243F4C19AF8DCFAD /* Copy Pods Resources */ = { 350 | isa = PBXShellScriptBuildPhase; 351 | buildActionMask = 2147483647; 352 | files = ( 353 | ); 354 | inputPaths = ( 355 | ); 356 | name = "Copy Pods Resources"; 357 | outputPaths = ( 358 | ); 359 | runOnlyForDeploymentPostprocessing = 0; 360 | shellPath = /bin/sh; 361 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; 362 | showEnvVarsInLog = 0; 363 | }; 364 | B19C28EF369E464FB0CD78AD /* Copy Pods Resources */ = { 365 | isa = PBXShellScriptBuildPhase; 366 | buildActionMask = 2147483647; 367 | files = ( 368 | ); 369 | inputPaths = ( 370 | ); 371 | name = "Copy Pods Resources"; 372 | outputPaths = ( 373 | ); 374 | runOnlyForDeploymentPostprocessing = 0; 375 | shellPath = /bin/sh; 376 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; 377 | showEnvVarsInLog = 0; 378 | }; 379 | F76AA410EFEF48178FB8A1D3 /* Check Pods Manifest.lock */ = { 380 | isa = PBXShellScriptBuildPhase; 381 | buildActionMask = 2147483647; 382 | files = ( 383 | ); 384 | inputPaths = ( 385 | ); 386 | name = "Check Pods Manifest.lock"; 387 | outputPaths = ( 388 | ); 389 | runOnlyForDeploymentPostprocessing = 0; 390 | shellPath = /bin/sh; 391 | 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"; 392 | showEnvVarsInLog = 0; 393 | }; 394 | /* End PBXShellScriptBuildPhase section */ 395 | 396 | /* Begin PBXSourcesBuildPhase section */ 397 | 632C3C9B18FDE815001E8C69 /* Sources */ = { 398 | isa = PBXSourcesBuildPhase; 399 | buildActionMask = 2147483647; 400 | files = ( 401 | 63A5E4581A68AB2D0021EC67 /* OSMKTestResult.m in Sources */, 402 | 632C3CB318FDE815001E8C69 /* OSMKAppDelegate.m in Sources */, 403 | 63A5E4551A68A68A0021EC67 /* OSMKTestImportViewController.m in Sources */, 404 | 632C3CAF18FDE815001E8C69 /* main.mm in Sources */, 405 | ); 406 | runOnlyForDeploymentPostprocessing = 0; 407 | }; 408 | 632C3CB618FDE815001E8C69 /* Sources */ = { 409 | isa = PBXSourcesBuildPhase; 410 | buildActionMask = 2147483647; 411 | files = ( 412 | 63F7F7DA1A65FE4B0010D9D5 /* OSMKImporterTests.m in Sources */, 413 | 6322F4EE1A2EBEA800FA8F71 /* OSMKStorageTests.m in Sources */, 414 | 6322F4EF1A2EBEA800FA8F71 /* OSMKTestData.m in Sources */, 415 | 6322F4ED1A2EBEA800FA8F71 /* OSMKParserTests.m in Sources */, 416 | 635F4FD619469589006D2EF8 /* OSMKAPITests.m in Sources */, 417 | ); 418 | runOnlyForDeploymentPostprocessing = 0; 419 | }; 420 | /* End PBXSourcesBuildPhase section */ 421 | 422 | /* Begin PBXTargetDependency section */ 423 | 632C3CC018FDE815001E8C69 /* PBXTargetDependency */ = { 424 | isa = PBXTargetDependency; 425 | target = 632C3C9E18FDE815001E8C69 /* OSMKit */; 426 | targetProxy = 632C3CBF18FDE815001E8C69 /* PBXContainerItemProxy */; 427 | }; 428 | /* End PBXTargetDependency section */ 429 | 430 | /* Begin PBXVariantGroup section */ 431 | 632C3CAB18FDE815001E8C69 /* InfoPlist.strings */ = { 432 | isa = PBXVariantGroup; 433 | children = ( 434 | 632C3CAC18FDE815001E8C69 /* en */, 435 | ); 436 | name = InfoPlist.strings; 437 | sourceTree = ""; 438 | }; 439 | 632C3CC418FDE815001E8C69 /* InfoPlist.strings */ = { 440 | isa = PBXVariantGroup; 441 | children = ( 442 | 632C3CC518FDE815001E8C69 /* en */, 443 | ); 444 | name = InfoPlist.strings; 445 | sourceTree = ""; 446 | }; 447 | /* End PBXVariantGroup section */ 448 | 449 | /* Begin XCBuildConfiguration section */ 450 | 632C3CC918FDE815001E8C69 /* Debug */ = { 451 | isa = XCBuildConfiguration; 452 | buildSettings = { 453 | ALWAYS_SEARCH_USER_PATHS = NO; 454 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 455 | CLANG_CXX_LIBRARY = "libc++"; 456 | CLANG_ENABLE_MODULES = YES; 457 | CLANG_ENABLE_OBJC_ARC = YES; 458 | CLANG_WARN_BOOL_CONVERSION = YES; 459 | CLANG_WARN_CONSTANT_CONVERSION = YES; 460 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 461 | CLANG_WARN_EMPTY_BODY = YES; 462 | CLANG_WARN_ENUM_CONVERSION = YES; 463 | CLANG_WARN_INT_CONVERSION = YES; 464 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 465 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 466 | CODE_SIGN_IDENTITY = "iPhone Developer"; 467 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 468 | COPY_PHASE_STRIP = NO; 469 | GCC_C_LANGUAGE_STANDARD = gnu99; 470 | GCC_DYNAMIC_NO_PIC = NO; 471 | GCC_OPTIMIZATION_LEVEL = 0; 472 | GCC_PREPROCESSOR_DEFINITIONS = ( 473 | "DEBUG=1", 474 | "$(inherited)", 475 | ); 476 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 477 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 478 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 479 | GCC_WARN_UNDECLARED_SELECTOR = YES; 480 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 481 | GCC_WARN_UNUSED_FUNCTION = YES; 482 | GCC_WARN_UNUSED_VARIABLE = YES; 483 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 484 | ONLY_ACTIVE_ARCH = YES; 485 | SDKROOT = iphoneos; 486 | }; 487 | name = Debug; 488 | }; 489 | 632C3CCA18FDE815001E8C69 /* Release */ = { 490 | isa = XCBuildConfiguration; 491 | buildSettings = { 492 | ALWAYS_SEARCH_USER_PATHS = NO; 493 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 494 | CLANG_CXX_LIBRARY = "libc++"; 495 | CLANG_ENABLE_MODULES = YES; 496 | CLANG_ENABLE_OBJC_ARC = YES; 497 | CLANG_WARN_BOOL_CONVERSION = YES; 498 | CLANG_WARN_CONSTANT_CONVERSION = YES; 499 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 500 | CLANG_WARN_EMPTY_BODY = YES; 501 | CLANG_WARN_ENUM_CONVERSION = YES; 502 | CLANG_WARN_INT_CONVERSION = YES; 503 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 504 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 505 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 506 | COPY_PHASE_STRIP = YES; 507 | ENABLE_NS_ASSERTIONS = NO; 508 | GCC_C_LANGUAGE_STANDARD = gnu99; 509 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 510 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 511 | GCC_WARN_UNDECLARED_SELECTOR = YES; 512 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 513 | GCC_WARN_UNUSED_FUNCTION = YES; 514 | GCC_WARN_UNUSED_VARIABLE = YES; 515 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 516 | SDKROOT = iphoneos; 517 | VALIDATE_PRODUCT = YES; 518 | }; 519 | name = Release; 520 | }; 521 | 632C3CCC18FDE815001E8C69 /* Debug */ = { 522 | isa = XCBuildConfiguration; 523 | baseConfigurationReference = 6D3E5B0C9150F393546435EE /* Pods.debug.xcconfig */; 524 | buildSettings = { 525 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 526 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 527 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 528 | GCC_PREFIX_HEADER = "OSMKit/OSMKit-Prefix.pch"; 529 | INFOPLIST_FILE = "OSMKit/OSMKit-Info.plist"; 530 | PRODUCT_NAME = "$(TARGET_NAME)"; 531 | WRAPPER_EXTENSION = app; 532 | }; 533 | name = Debug; 534 | }; 535 | 632C3CCD18FDE815001E8C69 /* Release */ = { 536 | isa = XCBuildConfiguration; 537 | baseConfigurationReference = 86E8BF54C163D8B1BD08CA15 /* Pods.release.xcconfig */; 538 | buildSettings = { 539 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 540 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 541 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 542 | GCC_PREFIX_HEADER = "OSMKit/OSMKit-Prefix.pch"; 543 | INFOPLIST_FILE = "OSMKit/OSMKit-Info.plist"; 544 | PRODUCT_NAME = "$(TARGET_NAME)"; 545 | WRAPPER_EXTENSION = app; 546 | }; 547 | name = Release; 548 | }; 549 | 632C3CCF18FDE815001E8C69 /* Debug */ = { 550 | isa = XCBuildConfiguration; 551 | baseConfigurationReference = 6D3E5B0C9150F393546435EE /* Pods.debug.xcconfig */; 552 | buildSettings = { 553 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/OSMKit.app/OSMKit"; 554 | FRAMEWORK_SEARCH_PATHS = ( 555 | "$(SDKROOT)/Developer/Library/Frameworks", 556 | "$(inherited)", 557 | "$(DEVELOPER_FRAMEWORKS_DIR)", 558 | ); 559 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 560 | GCC_PREFIX_HEADER = "OSMKit/OSMKit-Prefix.pch"; 561 | GCC_PREPROCESSOR_DEFINITIONS = ( 562 | "DEBUG=1", 563 | "$(inherited)", 564 | ); 565 | INFOPLIST_FILE = "OSMKitTests/OSMKitTests-Info.plist"; 566 | PRODUCT_NAME = "$(TARGET_NAME)"; 567 | TEST_HOST = "$(BUNDLE_LOADER)"; 568 | WRAPPER_EXTENSION = xctest; 569 | }; 570 | name = Debug; 571 | }; 572 | 632C3CD018FDE815001E8C69 /* Release */ = { 573 | isa = XCBuildConfiguration; 574 | baseConfigurationReference = 86E8BF54C163D8B1BD08CA15 /* Pods.release.xcconfig */; 575 | buildSettings = { 576 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/OSMKit.app/OSMKit"; 577 | FRAMEWORK_SEARCH_PATHS = ( 578 | "$(SDKROOT)/Developer/Library/Frameworks", 579 | "$(inherited)", 580 | "$(DEVELOPER_FRAMEWORKS_DIR)", 581 | ); 582 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 583 | GCC_PREFIX_HEADER = "OSMKit/OSMKit-Prefix.pch"; 584 | INFOPLIST_FILE = "OSMKitTests/OSMKitTests-Info.plist"; 585 | PRODUCT_NAME = "$(TARGET_NAME)"; 586 | TEST_HOST = "$(BUNDLE_LOADER)"; 587 | WRAPPER_EXTENSION = xctest; 588 | }; 589 | name = Release; 590 | }; 591 | /* End XCBuildConfiguration section */ 592 | 593 | /* Begin XCConfigurationList section */ 594 | 632C3C9A18FDE814001E8C69 /* Build configuration list for PBXProject "OSMKit" */ = { 595 | isa = XCConfigurationList; 596 | buildConfigurations = ( 597 | 632C3CC918FDE815001E8C69 /* Debug */, 598 | 632C3CCA18FDE815001E8C69 /* Release */, 599 | ); 600 | defaultConfigurationIsVisible = 0; 601 | defaultConfigurationName = Release; 602 | }; 603 | 632C3CCB18FDE815001E8C69 /* Build configuration list for PBXNativeTarget "OSMKit" */ = { 604 | isa = XCConfigurationList; 605 | buildConfigurations = ( 606 | 632C3CCC18FDE815001E8C69 /* Debug */, 607 | 632C3CCD18FDE815001E8C69 /* Release */, 608 | ); 609 | defaultConfigurationIsVisible = 0; 610 | defaultConfigurationName = Release; 611 | }; 612 | 632C3CCE18FDE815001E8C69 /* Build configuration list for PBXNativeTarget "OSMKitTests" */ = { 613 | isa = XCConfigurationList; 614 | buildConfigurations = ( 615 | 632C3CCF18FDE815001E8C69 /* Debug */, 616 | 632C3CD018FDE815001E8C69 /* Release */, 617 | ); 618 | defaultConfigurationIsVisible = 0; 619 | defaultConfigurationName = Release; 620 | }; 621 | /* End XCConfigurationList section */ 622 | }; 623 | rootObject = 632C3C9718FDE814001E8C69 /* Project object */; 624 | } 625 | --------------------------------------------------------------------------------