Created
November 9, 2011 00:17
-
-
Save Nub/1349835 to your computer and use it in GitHub Desktop.
OfflineReverseGeocoder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // OfflineReverseGeocoder.h | |
| // OfflineReverseGeocoder | |
| // | |
| // Created by Zachry Thayer on 11/4/11. | |
| // Copyright (c) 2011 Zachry Thayer. All rights reserved. | |
| // | |
| #import <Foundation/Foundation.h> | |
| #import <CoreLocation/CoreLocation.h> | |
| #define kORGCountryKey @"Country" | |
| #define kORGCountryCodeKey @"CountryCode" | |
| #define kORGRegionKey @"Region" | |
| #define kORGRegionCodeKey @"RegionCode" | |
| @interface OfflineReverseGeocoder : NSObject | |
| - (id)initWithDictionary:(NSDictionary*)dictionary; | |
| - (NSDictionary*)reverseGeocodeLocation:(CLLocationCoordinate2D)location; | |
| @end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // OfflineReverseGeocoder.m | |
| // OfflineReverseGeocoder | |
| // | |
| // Created by Zachry Thayer on 11/4/11. | |
| // Copyright (c) 2011 Zachry Thayer. All rights reserved. | |
| // | |
| #import "OfflineReverseGeocoder.h" | |
| @interface OfflineReverseGeocoder () | |
| { | |
| NSDictionary *geologicalRegions; | |
| } | |
| - (UIBezierPath*)bezierPathForGeographicalPolygon:(NSArray*)polygonPoints; | |
| - (NSString*)countryForLocation:(CLLocationCoordinate2D)location; | |
| - (NSString*)regionForLocation:(CLLocationCoordinate2D)location inCountry:(NSString*)country; | |
| @end | |
| @implementation OfflineReverseGeocoder | |
| - (id)initWithDictionary:(NSDictionary*)dictionary{ | |
| self = [self init]; | |
| if (self) { | |
| geologicalRegions = dictionary; | |
| } | |
| return self; | |
| } | |
| - (NSDictionary*)reverseGeocodeLocation:(CLLocationCoordinate2D)location{ | |
| NSString *thisCountryName = [self countryForLocation:location]; | |
| if (!thisCountryName) { | |
| return nil; | |
| } | |
| NSMutableDictionary *reverseGeocode = [NSMutableDictionary dictionary]; | |
| [reverseGeocode setObject:thisCountryName forKey:kORGCountryKey]; | |
| NSDictionary *allCountries = [geologicalRegions objectForKey:@"Countries"]; | |
| NSDictionary *thisCountry = [allCountries objectForKey:thisCountryName]; | |
| NSString *thisCountryCode = [thisCountry objectForKey:@"Code"]; | |
| [reverseGeocode setObject:thisCountryCode forKey:kORGRegionCodeKey]; | |
| NSString *thisRegionName = [self regionForLocation:location inCountry:thisCountryName]; | |
| if (thisRegionName){ | |
| [reverseGeocode setObject:thisRegionName forKey:kORGRegionKey]; | |
| NSDictionary *thisCountriesRegions = [thisCountry objectForKey:@"Regions"]; | |
| NSDictionary *thisRegion = [thisCountriesRegions objectForKey:thisRegionName]; | |
| NSString *thisRegionCode = [thisRegion objectForKey:@"Code"]; | |
| [reverseGeocode setObject:thisRegionCode forKey:kORGRegionCodeKey]; | |
| }else{ | |
| [reverseGeocode setObject:[NSNull null] forKey:kORGRegionKey]; | |
| [reverseGeocode setObject:[NSNull null] forKey:kORGRegionCodeKey]; | |
| } | |
| return reverseGeocode; | |
| } | |
| #pragma mark - Private Helpers | |
| - (NSString*)countryForLocation:(CLLocationCoordinate2D)location{ | |
| NSDictionary *allCountries = [geologicalRegions objectForKey:@"Countries"]; | |
| if (!allCountries) { | |
| return nil; | |
| } | |
| for (NSString *thisCountryKey in allCountries) { | |
| NSDictionary *thisCountry = [allCountries objectForKey:thisCountryKey]; | |
| if (!thisCountry) { | |
| return nil; | |
| } | |
| UIBezierPath *thisCountryPath = [self bezierPathForGeographicalPolygon:[thisCountry objectForKey:@"Polygon"]]; | |
| CGPoint locationCGPoint = CGPointMake(location.latitude, location.longitude); | |
| if ([thisCountryPath containsPoint:locationCGPoint]) { | |
| thisCountryPath = nil;//ARC release | |
| return thisCountryKey;//Return valid match | |
| } | |
| } | |
| return nil;//Nothing was found | |
| } | |
| - (NSString*)regionForLocation:(CLLocationCoordinate2D)location inCountry:(NSString*)country{ | |
| NSDictionary *allCountries = [geologicalRegions objectForKey:@"Countries"]; | |
| NSDictionary *thisCountry = [allCountries objectForKey:country]; | |
| if (!thisCountry) { | |
| return nil; | |
| } | |
| NSDictionary *thisCountriesRegions = [thisCountry objectForKey:@"Regions"]; | |
| for (NSString *thisRegionKey in thisCountriesRegions) { | |
| NSDictionary *thisRegion = [thisCountriesRegions objectForKey:thisRegionKey]; | |
| if (!thisRegion) { | |
| return nil; | |
| } | |
| UIBezierPath *thisRegionPath = [self bezierPathForGeographicalPolygon:[thisRegion objectForKey:@"Polygon"]]; | |
| CGPoint locationCGPoint = CGPointMake(location.latitude, location.longitude); | |
| if ([thisRegionPath containsPoint:locationCGPoint]) { | |
| thisRegionPath = nil;//ARC release | |
| return thisRegionKey;//Return valid match | |
| } | |
| } | |
| return nil;//Nothing was found | |
| } | |
| - (UIBezierPath*)bezierPathForGeographicalPolygon:(NSArray*)polygonPoints{ | |
| if (!polygonPoints) { | |
| return nil; | |
| } | |
| if ([polygonPoints count] < 3) { | |
| return nil; | |
| } | |
| UIBezierPath *bezierPath = [[UIBezierPath alloc] init]; | |
| for (NSDictionary *thisPoint in polygonPoints) { | |
| CGFloat latitude = [[thisPoint objectForKey:@"lat"] floatValue]; | |
| CGFloat longitude = [[thisPoint objectForKey:@"lon"] floatValue]; | |
| CGPoint locationCGPoint = CGPointMake(latitude, longitude); | |
| [bezierPath addLineToPoint:locationCGPoint]; | |
| } | |
| [bezierPath closePath]; | |
| return bezierPath; | |
| } | |
| @end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment