Skip to content

Instantly share code, notes, and snippets.

@joshsmith
Created November 15, 2011 01:30
Show Gist options
  • Save joshsmith/1365825 to your computer and use it in GitHub Desktop.
Save joshsmith/1365825 to your computer and use it in GitHub Desktop.
Finding zip codes within the radius of a given address using SimpleGeo
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