Simple and consistent geocoding library written in Python.
Many online providers such as Google & Bing have geocoding services, these providers do not include Python libraries and have different JSON responses between each other.
It can be very difficult sometimes to parse a particular geocoding provider since each one of them have their own JSON schema.
Here is a typical example of retrieving a Lat & Lng from Google using Python, things shouldn't be this hard.
>>> import requests
>>> url = 'https://maps.googleapis.com/maps/api/geocode/json'
>>> params = {'sensor': 'false', 'address': 'Mountain View, CA'}
>>> r = requests.get(url, params=params)
>>> results = r.json()['results']
>>> location = results[0]['geometry']['location']
>>> location['lat'], location['lng']
(37.3860517, -122.0838511)
Now lets use Geocoder to do the same task.
>>> import geocoder
>>> g = geocoder.google('Mountain View, CA')
>>> g.latlng
(37.3860517, -122.0838511)
As for now, Geocoder always returns one result: the best match according to the queried provider.
A Work is In Progress to support multiple results, starting with the provider geonames
.
>>> import geocoder
>>> g = geocoder.geonames('Mountain View, CA', maxRows=5)
>>> print(len(g))
5
>>> for result in g:
... print(result.address, result.latlng)
...
Mountain View ['37.38605', '-122.08385']
Mountain View Elementary School ['34.0271', '-117.59116']
Best Western Plus Mountainview Inn and Suites ['51.79516', '-114.62793']
Best Western Mountainview Inn ['49.3338', '-123.1446']
Mountain View Post Office ['37.393', '-122.07774']
As a side note, this change does not break backward compatibility, and the usual properties are still available, and applies on the best match:
# the default result is still the best match
>>> g.latlng
(37.3860517, -122.0838511)
https://geocoder.readthedocs.org/
Many properties are available once the geocoder object is created.
>>> import geocoder
>>> g = geocoder.google('Mountain View, CA')
>>> g.geojson
>>> g.json
>>> g.wkt
>>> g.osm
WIP SideNote / multiple results
For the providers currently supporting multiple results (see table below), the geojson
property called on g
will not apply to the best match but to all results. See documentation for more details on this.
>>> g = geocoder.google([45.15, -75.14], method='reverse')
>>> g.city
>>> g.state
>>> g.state_long
>>> g.country
>>> g.country_long
>>> g = geocoder.google("453 Booth Street, Ottawa ON")
>>> g.housenumber
>>> g.postal
>>> g.street
>>> g.street_long
>>> g = geocoder.ip('199.7.157.0')
>>> g = geocoder.ip('me')
>>> g.latlng
>>> g.city
Accessing the JSON & GeoJSON attributes will be different
>>> g = geocoder.google("Ottawa")
>>> g.bbox
{"northeast": [45.53453, -75.2465979], "southwest": [44.962733, -76.3539158]}
>>> g.geojson['bbox']
[-76.3539158, 44.962733, -75.2465979, 45.53453]
>>> g.southwest
[44.962733, -76.3539158]
$ geocode "Ottawa, ON" >> ottawa.geojson
$ geocode "Ottawa, ON" \
--provide google \
--out geojson \
--method geocode
Provider | Optimal | Usage Policy | Mutiple results |
---|---|---|---|
ArcGIS | World | ||
Baidu | China | API key | |
Bing | World | API key | yes |
CanadaPost | Canada | API key | |
FreeGeoIP | World | ||
Geocoder.ca | CA & US | Rate Limit | |
GeocodeFarm | World | Policy | |
GeoNames | World | Username | yes |
GeoOttawa | Ottawa | ||
World | Rate Limit, Policy | yes | |
HERE | World | API key | |
IPInfo | World | ||
Mapbox | World | API key | yes |
MapQuest | World | API key | yes |
Mapzen | World | API key | |
MaxMind | World | ||
OpenCage | World | API key | |
OpenStreetMap | World | Policy | |
Tamu | US | API key | |
TomTom | World | API key | |
What3Words | World | API key | |
Yahoo | World | ||
Yandex | Russia | ||
TGOS | Taiwan |
To install Geocoder, simply:
$ pip install geocoder
Installing the latest version from Github:
$ git clone https://github.com/DenisCarriere/geocoder
$ cd geocoder
$ python setup.py install
Speak up on Twitter @DenisCarriere and tell me how you use this Python Geocoder. New updates will be pushed to Twitter Hashtags #python.
Please feel free to give any feedback on this module. If you find any bugs or any enhancements to recommend please send some of your comments/suggestions to the Github Issues Page.