Skip to content

Instantly share code, notes, and snippets.

@Nub
Created November 9, 2011 00:17
Show Gist options
  • Select an option

  • Save Nub/1349835 to your computer and use it in GitHub Desktop.

Select an option

Save Nub/1349835 to your computer and use it in GitHub Desktop.
OfflineReverseGeocoder
//
// 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
//
// 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