views:

2869

answers:

4

Say I have a web service API that accepts a zipcode as a parameter, but I only have access to a GPS coordinate (latitude, longitude). How can I dynamically lookup the zipcode that the coordinate belongs to?

I'm doing this work on the iPhone, so hopefully there's a simple way to do this within the CoreLocation APIs that I'm overlooking in the documentation.

A: 

This kind of lookup is called "Reverse Geolocation."

The first thing you need to do is convert the lat/lng data from CLocation object to degrees...

in the locationManager function (which is called once you receive a location update)....

Code:

[lat stringWithFormat:@"%+.6f", myLocation.coordinate.latitude];
[lng stringWithFormat:@"%+.6f", myLocation.coordinate.longitude];

From there you send the lat and lng strings to a backend webservice like "GeoNames.org" or Google Maps API ... and you can get the nearest city or street address.

Robert Harvey
A: 

There is a database produced by the US Census - the Tiger database. I believe there is a possibility to lookup zipcode given lat/long.

I'll bet if you searched for Tiger zipcode you might find something. see here for example. It appears there is a Perl module on CPAN that does this, so it shouldn't be impossible.

Cheeso
+4  A: 

This page provides a database (in csv) of all the zip codes in the US, with their latitude and longitude. http://zips.sourceforge.net/

The file is 500k unpacked. Here's the first few lines of data:

"35004", "AL", " 33.606379", " -86.50249", "Moody", "Alabama"
"35005", "AL", " 33.592585", " -86.95969", "Adamsville", "Alabama"
"35006", "AL", " 33.451714", " -87.23957", "Adger", "Alabama"

Dump this data into a local database. Use the Haversine formula to compare your coordinates and the ones in the database to find the nearest point. CoreLocation has a function getDistanceFrom that you could use too.

- (CLLocationDistance)getDistanceFrom:(const CLLocation *)location

This page has a Haversine function in c and info about the zips database.

http://www.jaimerios.com/?p=39

Edit: Heres a great explanation from Google about calculating distances. It uses MySQL and PHP, but the SQL for finding nearest points is also useful here. It'd probably be faster to query using SQL, rather than the getDistanceFrom function.

http://code.google.com/support/bin/answer.py?answer=87134&topic=11364

Find the closest 20 locations that are within a radius of 25 miles to the 37, -122 coordinate:

SELECT id, ( 3959 * acos( cos( radians(37) ) 
 * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) 
 + sin( radians(37) ) * sin( radians( lat ) ) ) ) 
 AS distance FROM markers HAVING distance < 25 
 ORDER BY distance LIMIT 0 , 20;

To search by kilometers instead of miles, replace 3959 with 6371.

nevan
+4  A: 

I'd try checking out the docs for the reverse geocoder in the 3.0 SDK if I were you. I can't say what's there, but you might, say, find that the reverse geocode returns a placeMark, and then if you look up that placeMark in the SDK, you might find that it has a postcode property. Who knows?

Jane Sales