Skip to content

Instantly share code, notes, and snippets.

@marcel
Created October 24, 2008 15:26
Show Gist options
  • Save marcel/19457 to your computer and use it in GitHub Desktop.
Save marcel/19457 to your computer and use it in GitHub Desktop.
Small library to do reverse geocoding (translating a lat/lon pair into an address)
// Created by Marcel Molina Jr on 10/8/08.
//
#import <UIKit/UIKit.h>
#import <JSON/JSON.h>
#import <CoreLocation/CoreLocation.h>
@class ReverseGeocoder;
@protocol ReverseGeocoderDelegate
- (void)reverseGeocoder:(ReverseGeocoder *)geocoder
lookupReturnedAddress:(NSString *)address;
@end
@interface ReverseGeocoder : NSObject {
NSURL *_url;
NSString *_responseBody;
CLLocationDegrees latitude;
CLLocationDegrees longitude;
NSMutableString *responsePayload;
NSDictionary *addressDictionary;
NSObject<ReverseGeocoderDelegate> *delegate;
}
@property (nonatomic, retain) NSString *responsePayload;
@property (nonatomic, retain) NSDictionary *addressDictionary;
@property (nonatomic, retain) NSObject<ReverseGeocoderDelegate> *delegate;
+ (void)lookupLatitude:(CLLocationDegrees)aLatitude longitude:(CLLocationDegrees)aLongitude delegate:(id)aDelegate;
- (id)initWithLatitude:(CLLocationDegrees)aLatitude longitude:(CLLocationDegrees)aLongitude;
- (void)performLookup;
- (NSURL *)url;
- (void)parsePayload;
- (NSString *)address;
- (NSString *)streetNumber;
- (NSString *)street;
- (NSString *)city;
- (NSString *)state;
- (NSString *)_valueForAddressComponentNamed:(NSString *)componentName;
@end
// Created by Marcel Molina Jr on 10/8/08.
//
#import "ReverseGeocoder.h"
#define CoordinateTranslationDomain @"http://ws.geonames.org"
#define CoordinateTranslationPath @"findNearestAddressJSON"
@implementation ReverseGeocoder
@synthesize responsePayload, addressDictionary, delegate;
+ (void)lookupLatitude:(CLLocationDegrees)aLatitude
longitude:(CLLocationDegrees)aLongitude
delegate:(id)aDelegate
{
ReverseGeocoder *reverseGeocoder;
reverseGeocoder = [[[ReverseGeocoder alloc]
initWithLatitude:aLatitude
longitude:aLongitude] autorelease];
reverseGeocoder.delegate = aDelegate;
[reverseGeocoder performLookup];
}
- (id)initWithLatitude:(CLLocationDegrees)aLatitude
longitude:(CLLocationDegrees)aLongitude
{
self = [super init];
if (self != nil) {
latitude = aLatitude;
longitude = aLongitude;
self.responsePayload = [[NSMutableString alloc] init];
}
return self;
}
- (void)performLookup
{
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[self url]];
NSLog(@"Reverse geolocation url: %@", [self url]);
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[connection release];
[request release];
}
- (NSURL *)url
{
if (_url == nil) {
_url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@?lat=%f&lng=%f",
CoordinateTranslationDomain, CoordinateTranslationPath,
latitude, longitude]
];
}
return _url;
}
- (void)parsePayload
{
SBJSON *json = [[SBJSON new] autorelease];
NSError *error;
NSDictionary *parsedJSON;
parsedJSON = [json objectWithString:responsePayload error:&error];
self.addressDictionary = [parsedJSON valueForKey:@"address"];
}
- (NSString *)address
{
return [NSString stringWithFormat:@"%@ %@, %@, %@",
[self streetNumber],
[self street],
[self city],
[self state]];
}
- (NSString *)streetNumber
{
return [self _valueForAddressComponentNamed:@"streetNumber"];
}
- (NSString *)street
{
return [self _valueForAddressComponentNamed:@"street"];
}
- (NSString *)city
{
return [self _valueForAddressComponentNamed:@"placename"];
}
- (NSString *)state
{
return [self _valueForAddressComponentNamed:@"adminCode1"];
}
- (NSString *)_valueForAddressComponentNamed:(NSString *)componentName
{
return [addressDictionary valueForKey:componentName];
}
- (void)dealloc
{
[responsePayload release];
[addressDictionary release];
[_url release];
[_responseBody release];
[delegate release];
[super dealloc];
}
- (void)notifyDelegate
{
[delegate reverseGeocoder:self lookupReturnedAddress:[self address]];
}
#pragma mark NSURLConnection delegate methods
- (void)connection:(NSURLConnection *)connection
didReceiveData:(NSData *)data {
NSString *newText = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (newText != NULL) {
[responsePayload appendString:newText];
[newText release];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection {
NSLog(@"Response payload: %@", responsePayload);
[self parsePayload];
NSLog(@"Address: %@", [self address]);
[self notifyDelegate];
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment