Created
November 15, 2011 01:30
-
-
Save joshsmith/1365825 to your computer and use it in GitHub Desktop.
Finding zip codes within the radius of a given address using SimpleGeo
This file contains 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
from math import pi,sqrt,sin,cos,asin,atan2 | |
from simplegeo import Client | |
import json | |
def get_nearby_zips(address, radius, client): | |
''' | |
Given an address and radius (and the SimpleGeo client), returns | |
a comma-separated list of zip codes within that radius. | |
''' | |
context = client.context.get_context_by_address(address) | |
lat = float(context['query']['latitude']) | |
lon = float(context['query']['longitude']) | |
# Convert the initial lat, lon to radians | |
lat = lat * pi / 180 | |
lon = lon * pi / 180 | |
earths_radius = 6372.8 | |
# Find the hypotenuse of the triangle and convert to kilometers | |
distance = sqrt(2 * radius**2) | |
distance = distance * 1.609344 | |
ne_bearing = 45 * pi / 180 | |
sw_bearing = 225 * pi / 180 | |
# Get the Southwest Lat/Lon in degrees | |
swLatRad = asin(sin(lat) * cos(distance/earths_radius) + | |
cos(lat) * sin(distance/earths_radius) * cos(ne_bearing)) | |
swLat = swLatRad * 180 / pi | |
swLonRad = lon + atan2(sin(ne_bearing) * sin(distance/earths_radius) * | |
cos(lat), cos(distance/earths_radius) - sin(lat) * sin(swLatRad)) | |
swLon = swLonRad * 180 / pi | |
# Get the Northeast Lat/Lon in degrees | |
neLatRad = asin (sin(lat) * cos(distance/earths_radius) + | |
cos(lat) * sin(distance/earths_radius) * cos(sw_bearing)) | |
neLat = neLatRad * 180 / pi | |
neLonRad = lon + atan2(sin(sw_bearing) * sin(distance/earths_radius) * | |
cos(lat), cos(distance/earths_radius) - sin(lat) * sin(neLatRad)) | |
neLon = neLonRad * 180 / pi | |
# Find the zip codes within the given mile radius | |
# and put them in a comma-separated string | |
bbox_ZIPs = client.context.get_context_from_bbox(swLat, swLon, neLat, neLon, | |
features__category='Postal Code') | |
zips = sorted(bbox_ZIPs['features'],cmp=lambda x,y: cmp(x['name'],y['name'])) | |
zips = ",".join(zip['name'] for zip in zips) | |
return zips | |
# Instantiate the SimpleGeo Client | |
client = Client('KEY', 'SECRET') | |
address = "1000 Commerce Park Dr, Williamsport PA" | |
radius = 30 | |
zips = get_nearby_zips(address, radius, client) | |
print(zips) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment