PK ,HؾҬ" " geocoder/ottawa_parcel.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import requests
from geocoder.base import Base
class OttawaParcel(Base):
"""
Ottawa ArcGIS REST Services
===========================
Geocoding is the process of assigning a location, usually in the form of
coordinate values (points), to an address by comparing the descriptive
location elements in the address to those present in the reference
material. Addresses come in many forms, ranging from the common address
format of a house number followed by the street name and succeeding
information to other location descriptions such as postal zone or census
tract. An address includes any type of information that distinguishes
a place.
API Reference
-------------
http://maps.ottawa.ca/ArcGIS/rest/services/
compositeLocator/GeocodeServer/findAddressCandidates
"""
provider = 'ottawa'
method = 'parcel'
def __init__(self, location, **kwargs):
self.url = 'http://maps.ottawa.ca/arcgis/rest/services/Property_Parcels/MapServer/find'
self.location = location
self.address_id = self._get_address_id(location)
if self.address_id:
self.params = {
'searchText': self.address_id,
'layers': 2,
'f': 'json',
'sr': 4326,
}
self._initialize(**kwargs)
def _exceptions(self):
# Build intial Tree with results
if self.parse['results']:
self._build_tree(self.parse['results'][0])
def _get_address_id(self, location):
url = 'http://maps.ottawa.ca/arcgis/rest/services/Property_Parcels/MapServer/find'
params = {
'searchText': location,
'layers': 0,
'f': 'json',
'sr': 4326,
}
r = requests.get(url, params=params)
content = r.json()
if content:
results = content['results']
if results:
return results[0]['attributes']['PI Municipal Address ID']
def _clean(self, item):
if item:
return item.strip()
@property
def ok(self):
return bool(self.geometry)
@property
def frontage(self):
"""Length in Feet (f)"""
if self.length and self.area:
return round(self.area / self.length)
@property
def length(self):
"""Length in Feet (f)"""
length = self.parse['attributes'].get('Shape_Length')
if length:
return round(float(length))
@property
def area(self):
"""Square Foot Area (sqft)"""
area = self.parse['attributes'].get('Shape_Area')
if area:
return round(float(area) * 10.76391)
@property
def municipality(self):
return self._clean(self.parse['attributes'].get('MUNICIPALITY_NAME'))
@property
def housenumber(self):
return self._clean(self.parse['attributes'].get('ADDRESS_NUMBER'))
@property
def suffix(self):
return self._clean(self.parse['attributes'].get('SUFFIX'))
@property
def public_land(self):
return self._clean(self.parse['attributes'].get('PUBLICLAND'))
@property
def street(self):
return self._clean(self.parse['attributes'].get('ROAD_NAME'))
@property
def legal_unit(self):
return self._clean(self.parse['attributes'].get('LEGAL_UNIT'))
@property
def pin(self):
return self._clean(self.parse['attributes'].get('PIN_NUMBER'))
@property
def geometry(self):
return self.parse['geometry']
@property
def postal(self):
return self._clean(self.parse['attributes'].get('POSTAL_CODE'))
if __name__ == '__main__':
area = 2123
length = 100
frontage = 21
location = '169 Carillon'
g = OttawaParcel(location, timeout=10.0)
print('%s: %i x %i = %i' % (location, g.frontage, g.length, g.area))
print('453 Booth: %i x %i = %i' % (frontage, length, area))
print('%i x %i = %i' % (g.frontage - frontage, g.length - length, g.area - area))
PK fI9 geocoder/geocodefarm_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import six
from geocoder.base import Base
from geocoder.location import Location
from geocoder.geocodefarm import GeocodeFarm
from geocoder.keys import geocodefarm_key
class GeocodeFarmReverse(GeocodeFarm, Base):
"""
Geocode.Farm
=======================
Geocode.Farm is one of the few providers that provide this highly
specialized service for free. We also have affordable paid plans, of
course, but our free services are of the same quality and provide the same
results. The major difference between our affordable paid plans and our
free API service is the limitations. On one of our affordable paid plans
your limit is set based on the plan you signed up for, starting at 25,000
query requests per day (API calls). On our free API offering, you are
limited to 250 query requests per day (API calls).
Params
------
:param lat: The numerical latitude value for which you wish to obtain the closest, human-readable address.
:param lon: The numerical longitude value for which you wish to obtain the closest, human-readable address.
:param key: (optional) API Key. Only Required for Paid Users.
:param lang: (optional) 2 digit lanuage code to return results in. Currently only "en"(English) or "de"(German) supported.
:param country: (optional) The country to return results in. Used for biasing purposes and may not fully filter results to this specific country.
API Reference
-------------
https://geocode.farm/geocoding/free-api-documentation/
"""
provider = 'geocodefarm'
method = 'reverse'
def __init__(self, location, **kwargs):
self.url = 'https://www.geocode.farm/v3/json/reverse/'
self.location = location
location = Location(location)
key = kwargs.get('key', geocodefarm_key)
self.params = {
'lat': location.latitude,
'lon': location.longitude,
'key': key if key else None,
'lang': kwargs.get('lang', ''),
'country': kwargs.get('country', ''),
}
self._initialize(**kwargs)
if __name__ == '__main__':
g = GeocodeFarm([45.3, -75.4])
g.debug()
PK 6|Hk
k
geocoder/mapquest.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import mapquest_key
class Mapquest(Base):
"""
MapQuest
========
The geocoding service enables you to take an address and get the
associated latitude and longitude. You can also use any latitude
and longitude pair and get the associated address. Three types of
geocoding are offered: address, reverse, and batch.
API Reference
-------------
http://www.mapquestapi.com/geocoding/
"""
provider = 'mapquest'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'http://www.mapquestapi.com/geocoding/v1/address'
self.location = location
self.headers = {
'referer': 'http://www.mapquestapi.com/geocoding/',
'host': 'www.mapquestapi.com',
}
self.params = {
'key': self._get_api_key(mapquest_key, **kwargs),
'location': location,
'maxResults': 1,
'outFormat': 'json',
}
self._initialize(**kwargs)
def _catch_errors(self):
if self.content and 'The AppKey submitted with this request is invalid' in self.content:
raise ValueError('MapQuest API Key invalid')
def _exceptions(self):
# Build intial Tree with results
if self.parse['results']:
self._build_tree(self.parse['results'][0])
if self.parse['locations']:
self._build_tree(self.parse['locations'][0])
@property
def lat(self):
return self.parse['latLng'].get('lat')
@property
def lng(self):
return self.parse['latLng'].get('lng')
@property
def street(self):
return self.parse.get('street')
@property
def address(self):
if self.street:
return self.street
elif self.city:
return self.city
elif self.country:
return self.country
@property
def quality(self):
return self.parse.get('geocodeQuality')
@property
def postal(self):
return self.parse.get('postalCode')
@property
def neighborhood(self):
return self.parse.get('adminArea6')
@property
def city(self):
return self.parse.get('adminArea5')
@property
def county(self):
return self.parse.get('adminArea4')
@property
def state(self):
return self.parse.get('adminArea3')
@property
def country(self):
return self.parse.get('adminArea1')
if __name__ == '__main__':
g = Mapquest('1552 Payette dr., Ottawa Ontario')
g.debug()
PK fI@c& & geocoder/maxmind.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
class Maxmind(Base):
"""
MaxMind's GeoIP2
=======================
MaxMind's GeoIP2 products enable you to identify the location,
organization, connection speed, and user type of your Internet
visitors. The GeoIP2 databases are among the most popular and
accurate IP geolocation databases available.
API Reference
-------------
https://www.maxmind.com/en/geolocation_landing
"""
provider = 'maxmind'
method = 'geocode'
def __init__(self, location, **kwargs):
if location:
self.location = location
else:
self.location = 'me'
self.headers = {
'Referer': 'https://www.maxmind.com/en/geoip_demo',
'Host': 'www.maxmind.com',
}
self.params = {'demo': 1}
self.url = 'https://www.maxmind.com/geoip/v2.0/city_isp_org/{0}'.format(self.location)
self._initialize(**kwargs)
def _catch_errors(self):
error = self.content.get('error')
if error:
code = self.content.get('code')
self.error = code
def _exceptions(self):
subdivisions = self.content.get('subdivisions')
if subdivisions:
self.content['subdivision'] = subdivisions[0]
# Grab all names in [en] and place them in self.parse
for key, value in self.content.items():
if isinstance(value, dict):
for minor_key, minor_value in value.items():
if minor_key == 'names':
self.parse[key] = minor_value['en']
@property
def lat(self):
return self.parse['location'].get('latitude')
@property
def lng(self):
return self.parse['location'].get('longitude')
@property
def address(self):
if self.city:
return u'{0}, {1}, {2}'.format(self.city, self.state, self.country)
elif self.state:
return u'{0}, {1}'.format(self.state, self.country)
elif self.country:
return u'{0}'.format(self.country)
else:
return u''
@property
def domain(self):
return self.parse['traits'].get('domain')
@property
def isp(self):
return self.parse['traits'].get('isp')
@property
def postal(self):
return self.parse['postal'].get('code')
@property
def city(self):
return self.parse.get('city')
@property
def state(self):
return self.parse.get('subdivision')
@property
def country(self):
return self.parse.get('country')
@property
def continent(self):
return self.parse.get('continent')
@property
def ip(self):
return self.parse['traits'].get('ip_address')
@property
def timezone(self):
return self.parse['location'].get('time_zone')
@property
def metro_code(self):
return self.parse['location'].get('metro_code')
if __name__ == '__main__':
g = Maxmind('8.8.8.8')
g.debug()
PK gH으! ! geocoder/google.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import ratelim
import requests
import six
from geocoder.base import Base
from geocoder.keys import google_key, google_client, google_client_secret
class Google(Base):
"""
Google Geocoding API
====================
Geocoding is the process of converting addresses into geographic
coordinates (like latitude 37.423021 and longitude -122.083739),
which you can use to place markers or position the map.
API Reference
-------------
https://developers.google.com/maps/documentation/geocoding
Parameters
----------
:param location: Your search location you want geocoded.
:param components: Component Filtering
:param method: (default=geocode) Use the following:
> geocode
> reverse
> batch
> timezone
> elevation
:param key: Your Google developers free key.
:param language: 2-letter code of preferred language of returned address elements.
:param client: Google for Work client ID. Use with client_secret. Cannot use with key parameter
:param client_secret: Google for Work client secret. Use with client.
"""
provider = 'google'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'https://maps.googleapis.com/maps/api/geocode/json'
self.location = location
self.client = kwargs.get('client', google_client)
self.client_secret = kwargs.get('client_secret', google_client_secret)
self.params = {
'address': location,
'key': None if self.client and self.client_secret else kwargs.get('key', google_key),
'client': self.client,
'bounds': kwargs.get('bounds', ''),
'language': kwargs.get('language', ''),
'region': kwargs.get('region', ''),
'components': kwargs.get('components', ''),
}
if self.client and self.client_secret:
self._encode_params(**kwargs)
self._initialize(**kwargs)
def _encode_params(self, **kwargs):
# turn non-empty params into sorted list in order to maintain signature validity.
# Requests will honor the order.
self.params = sorted([(k, v) for (k, v) in self.params.items() if v])
# the signature parameter needs to come in the end of the url
self.params.append(self._sign_url(self.url, self.params, self.client_secret))
def _sign_url(self, base_url=None, params=None, client_secret=None):
""" Sign a request URL with a Crypto Key.
Usage:
from urlsigner import sign_url
signed_url = sign_url(base_url=my_url,
params=url_params,
client_secret=CLIENT_SECRET)
Args:
base_url - The trunk of the URL to sign. E.g. https://maps.googleapis.com/maps/api/geocode/json
params - List of tuples of URL parameters INCLUDING YOUR CLIENT ID ('client','gme-...')
client_secret - Your Crypto Key from Google for Work
Returns:
The signature as a dictionary #signed request URL
"""
import hashlib
import hmac
import base64
if six.PY3:
from urllib.parse import urlparse, urlencode
else:
from urllib import urlencode
from urlparse import urlparse
# Return if any parameters aren't given
if not base_url or not self.client_secret or not self.client:
return None
# assuming parameters will be submitted to Requests in identical order!
url = urlparse(base_url + "?" + urlencode(params))
# We only need to sign the path+query part of the string
url_to_sign = (url.path + "?" + url.query).encode('utf-8')
# Decode the private key into its binary format
# We need to decode the URL-encoded private key
decoded_key = base64.urlsafe_b64decode(client_secret)
# Create a signature using the private key and the URL-encoded
# string using HMAC SHA1. This signature will be binary.
signature = hmac.new(decoded_key, url_to_sign, hashlib.sha1)
# Encode the binary signature into base64 for use within a URL
encoded_signature = base64.urlsafe_b64encode(signature.digest())
# Return signature as a tuple (to be appended as a param to url)
return ("signature", encoded_signature)
"""
@staticmethod
@ratelim.greedy(2500, 60 * 60 * 24)
@ratelim.greedy(10, 1)
@ratelim.greedy(100000, 60 * 60 * 24) # Google for Work daily limit
@ratelim.greedy(50, 1) # Google for Work limit per second
def rate_limited_get(*args, **kwargs):
return requests.get(*args, **kwargs)
"""
def _catch_errors(self):
status = self.parse.get('status')
if not status == 'OK':
self.error = status
def _exceptions(self):
# Build intial Tree with results
if self.parse['results']:
self._build_tree(self.parse.get('results')[0])
# Build Geometry
self._build_tree(self.parse.get('geometry'))
# Parse address components with short & long names
for item in self.parse['address_components']:
for category in item['types']:
self.parse[category]['long_name'] = item['long_name']
self.parse[category]['short_name'] = item['short_name']
@property
def lat(self):
return self.parse['location'].get('lat')
@property
def lng(self):
return self.parse['location'].get('lng')
@property
def place(self):
return self.parse.get('place_id')
@property
def quality(self):
quality = self.parse.get('types')
if quality:
return quality[0]
@property
def accuracy(self):
return self.parse.get('location_type')
@property
def bbox(self):
south = self.parse['southwest'].get('lat')
west = self.parse['southwest'].get('lng')
north = self.parse['northeast'].get('lat')
east = self.parse['northeast'].get('lng')
return self._get_bbox(south, west, north, east)
@property
def address(self):
return self.parse.get('formatted_address')
@property
def postal(self):
return self.parse['postal_code'].get('short_name')
@property
def subpremise(self):
return self.parse['subpremise'].get('short_name')
@property
def housenumber(self):
return self.parse['street_number'].get('short_name')
@property
def street(self):
return self.parse['route'].get('short_name')
@property
def street_long(self):
return self.parse['route'].get('long_name')
@property
def road_long(self):
return self.street_long
@property
def neighborhood(self):
return self.parse['neighborhood'].get('short_name')
@property
def sublocality(self):
return self.parse['sublocality'].get('short_name')
@property
def city(self):
city = self.parse['locality'].get('short_name')
postal_town = self.postal_town
if city:
return city
else:
return postal_town
@property
def city_long(self):
city_long = self.parse['locality'].get('long_name')
postal_town_long = self.postal_town_long
if city_long:
return city_long
else:
return postal_town_long
@property
def postal_town(self):
return self.parse['postal_town'].get('short_name')
@property
def postal_town_long(self):
return self.parse['postal_town'].get('long_name')
@property
def county(self):
return self.parse['administrative_area_level_2'].get('short_name')
@property
def state(self):
return self.parse['administrative_area_level_1'].get('short_name')
@property
def state_long(self):
return self.parse['administrative_area_level_1'].get('long_name')
@property
def province_long(self):
return self.state_long
@property
def country(self):
return self.parse['country'].get('short_name')
@property
def country_long(self):
return self.parse['country'].get('long_name')
if __name__ == '__main__':
g = Google('11 Wall Street, New York')
g.debug()
PK fIZ geocoder/canadapost.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import re
import requests
from geocoder.base import Base
from geocoder.keys import canadapost_key
class Canadapost(Base):
"""
Addres Complete API
=======================
The next generation of address finders, AddressComplete uses
intelligent, fast searching to improve data accuracy and relevancy.
Simply start typing a business name, address or Postal Code
and AddressComplete will suggest results as you go.
Params
------
:param ``location``: Your search location you want geocoded.
:param ``key``: (optional) API Key from CanadaPost Address Complete.
:param ``language``: (default=en) Output language preference.
:param ``country``: (default=ca) Geofenced query by country.
API Reference
-------------
https://www.canadapost.ca/pca/
"""
provider = 'canadapost'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'https://ws1.postescanada-canadapost.ca/AddressComplete' \
'/Interactive/RetrieveFormatted/v2.10/json3ex.ws'
self.location = location
self.key = self._get_api_key(canadapost_key, **kwargs)
self.timeout = kwargs.get('timeout', 5.0)
self.proxies = kwargs.get('proxies', '')
self._language = kwargs.get('language', 'en')
self._country = kwargs.get('country', 'ca')
self.id = ''
# Connect to CanadaPost to retrieve API key if none are provided
if not self.key:
self._retrieve_key()
self._retrieve_id()
if self.key and self.id:
self.params = {
'Key': self.key,
'Id': self.id,
'Source': '',
'cache': 'true'
}
self._initialize(**kwargs)
else:
self.json = dict()
self.parse = self.tree()
self._json()
def _retrieve_key(self):
url = 'http://www.canadapost.ca/cpo/mc/personal/postalcode/fpc.jsf'
text = ''
try:
r = requests.get(url, timeout=self.timeout, proxies=self.proxies)
text = r.text
except:
self.error = 'ERROR - URL Connection'
if text:
expression = r"'(....-....-....-....)';"
pattern = re.compile(expression)
match = pattern.search(text)
if match:
self.key = match.group(1)
return self.key
else:
self.error = 'ERROR - No API Key'
def _retrieve_id(self, last_id=''):
params = {
'Key': self.key,
'LastId': last_id,
'Country': self._country,
'SearchFor': 'Everything',
'SearchTerm': self.location,
'LanguagePreference': self._language,
'$cache': 'true'
}
items = []
url = 'https://ws1.postescanada-canadapost.ca/AddressComplete' \
'/Interactive/Find/v2.10/json3ex.ws'
try:
r = requests.get(url, params=params,
timeout=self.timeout,
proxies=self.proxies)
items = r.json().get('Items')
self.status_code = 200
except:
self.status_code = 404
self.error = 'ERROR - URL Connection'
if items:
first_item = items[0]
if 'Error' in first_item:
self.error = first_item['Description']
else:
item_id = first_item['Id']
description = first_item.get('Description')
if item_id:
if 'results' in description:
self._retrieve_id(item_id)
elif 'Id' in first_item:
self.id = item_id
return self.id
def _exceptions(self):
# Build intial Tree with results
if self.parse['Items']:
self._build_tree(self.parse['Items'][0])
@property
def ok(self):
return bool(self.postal)
@property
def quality(self):
return self.parse.get('Type')
@property
def accuracy(self):
return self.parse.get('DataLevel')
@property
def address(self):
return self.parse.get('Line1')
@property
def postal(self):
return self.parse.get('PostalCode')
@property
def housenumber(self):
return self.parse.get('BuildingNumber')
@property
def street(self):
return self.parse.get('Street')
@property
def city(self):
return self.parse.get('City')
@property
def state(self):
return self.parse.get('ProvinceName')
@property
def country(self):
return self.parse.get('CountryName')
@property
def unit(self):
return self.parse.get('SubBuilding')
@property
def domesticId(self):
return self.parse.get('DomesticId')
@property
def label(self):
return self.parse.get('Label')
@property
def canadapost_api_key(self):
return self.key
if __name__ == '__main__':
g = Canadapost("453 Booth Street, ON")
g.debug()
PK ,H geocoder/google_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.google import Google
from geocoder.location import Location
from geocoder.keys import google_key, google_client
class GoogleReverse(Google, Base):
"""
Google Geocoding API
====================
Geocoding is the process of converting addresses (like "1600 Amphitheatre
Parkway, Mountain View, CA") into geographic coordinates (like latitude
37.423021 and longitude -122.083739), which you can use to place markers or
position the map.
API Reference
-------------
https://developers.google.com/maps/documentation/geocoding/
"""
provider = 'google'
method = 'reverse'
def __init__(self, location, **kwargs):
self.url = 'https://maps.googleapis.com/maps/api/geocode/json'
self.location = str(Location(location))
self.short_name = kwargs.get('short_name', True)
self.params = {
'sensor': 'false',
'latlng': self.location,
'key': kwargs.get('key', google_key),
'language': kwargs.get('language', ''),
'client': kwargs.get('client', google_client)
}
self._initialize(**kwargs)
@property
def ok(self):
return bool(self.address)
if __name__ == '__main__':
g = GoogleReverse([45.4049053, -75.7077965])
g.debug()
PK I.O2 2 geocoder/tgos.py#!/usr/bin/python
# coding: utf8
import re
import requests
from geocoder.base import Base
from geocoder.keys import tgos_key
class Tgos(Base):
'''
TGOS Geocoding Service
TGOS Map is official map service of Taiwan.
API Reference
-------------
http://api.tgos.nat.gov.tw/TGOS_MAP_API/Web/Default.aspx
'''
provider = 'tgos'
method = 'geocode'
def __init__(self, location, **kwargs):
self._define_language(kwargs)
self.url = 'http://gis.tgos.nat.gov.tw/TGLocator/TGLocator.ashx'
self.params = {
'format': 'json',
'input': location,
'center': kwargs.get('method', 'center'),
'srs': 'EPSG:4326',
'ignoreGeometry': False,
'keystr': self._get_api_key(self._get_tgos_key(tgos_key), **kwargs),
'pnum': 5
}
self._initialize(**kwargs)
def _get_tgos_key(self, key):
if key:
return key
url = 'http://api.tgos.nat.gov.tw/TGOS_API/tgos'
r = requests.get(url, headers={'Referer': url})
# TGOS Hash pattern used for TGOS API key
pattern = re.compile(r'TGOS.tgHash="([a-zA-Z\d/\-_+=]*)"')
match = pattern.search(r.content)
if match:
return match.group(1)
else:
raise ValueError('Cannot find TGOS.tgHash')
def _catch_errors(self):
status = self.parse['status']
if not status == 'OK':
if status == 'REQUEST_DENIED':
self.error = self.parse['error_message']
self.status_code = 401
else:
self.error = 'Unknown'
self.status_code = 500
def _define_language(self, kwargs):
# Custom language output
language = kwargs.get('language', 'taiwan').lower()
if language in ['english', 'en', 'eng']:
self.language = 'en'
elif language in ['chinese', 'zh']:
self.language = 'zh-tw'
else:
self.language = 'zh-tw'
def _exceptions(self):
# Build intial Tree with results
result = self.parse['results']
if result:
self._build_tree(result[0])
@property
def quality(self):
return self.type
@property
def lat(self):
return self.parse['geometry'].get('y')
@property
def lng(self):
return self.parse['geometry'].get('x')
@property
def address(self):
return self.parse.get('FULL_ADDR')
@property
def housenumber(self):
number = self.number
if number:
match = re.match(r'\d+', number)
if match:
return int(match.group())
return number
@property
def street(self):
if bool(self.road and self.section):
return u'{road}{section}{segment}'.format(
road=self.road,
section=self.section,
segment={'zh-tw': u'段', 'en': 'Segement'}[self.language])
return self.road
@property
def state(self):
return self.county
@property
def city(self):
return self.town
@property
def country(self):
return {'en': u'Taiwan', 'zh-tw': u'中華民國'}[self.language]
# TGOS specific attributes
# ========================
@property
def alley(self):
return self.parse.get('ALLEY')
@property
def lane(self):
return self.parse.get('LANE')
@property
def neighborhood(self):
return self.parse.get('NEIGHBORHOOD')
@property
def number(self):
return self.parse.get('NUMBER')
@property
def road(self):
return self.parse.get('ROAD')
@property
def section(self):
section = self.parse.get('SECTION')
if section:
if self.language == 'zh-tw':
return {
0: u'零',
1: u'一',
2: u'二',
3: u'三',
4: u'四',
5: u'五',
6: u'六',
7: u'七',
8: u'八',
9: u'九'
}[int(section)]
return int(section)
@property
def sub_alley(self):
return self.parse.get('sub_alley')
@property
def tong(self):
return self.parse.get('TONG')
@property
def village(self):
return self.parse.get('VILLAGE')
@property
def county(self):
return self.parse.get('county')
@property
def name(self):
return self.parse.get('name')
@property
def town(self):
return self.parse.get('town')
@property
def type(self):
return self.parse.get('type')
if __name__ == '__main__':
g = Tgos('台北市內湖區內湖路一段735號', language='en')
g.debug()
PK ,Hk geocoder/komoot.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
class Komoot(Base):
"""
Komoot REST API
=======================
API Reference
-------------
http://photon.komoot.de
"""
provider = 'komoot'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'http://photon.komoot.de/api'
self.location = location
self.params = {
'q': location,
'limit': kwargs.get('result', 1),
'lang': 'en',
}
self._initialize(**kwargs)
def _exceptions(self):
# Only retrieve the first feature
features = self.parse['features']
if features:
self._build_tree(self.parse['features'][0])
def __iter__(self):
for item in self.content['features']:
yield item
@property
def lat(self):
return self.parse['geometry']['coordinates'][1]
@property
def lng(self):
return self.parse['geometry']['coordinates'][0]
@property
def bbox(self):
extent = self.parse['properties']['extent']
if extent:
west = extent[0]
north = extent[1]
east = extent[2]
south = extent[3]
return self._get_bbox(south, west, north, east)
@property
def address(self):
# Ontario, Canada
address = ', '.join([self.state, self.country])
# 453 Booth street, Ottawa ON, Canada
if self.housenumber:
middle = ', '.join([self.street, self.city])
address = ' '.join([self.housenumber, middle, address])
# 453 Booth street, Ottawa ON, Canada
elif self.street:
middle = ', '.join([self.street, self.city])
address = ' '.join([middle, address])
# Ottawa ON, Canada
elif self.city:
address = ' '.join([self.city, address])
return address
@property
def country(self):
return self.parse['properties'].get('country', '')
@property
def state(self):
if self.osm_value == 'state':
return self.parse['properties'].get('name', '')
return self.parse['properties'].get('state', '')
@property
def city(self):
if self.osm_value == 'city':
return self.parse['properties'].get('name', '')
return self.parse['properties'].get('city', '')
@property
def street(self):
return self.parse['properties'].get('street', '')
@property
def housenumber(self):
return self.parse['properties'].get('housenumber', '')
@property
def postal(self):
return self.parse['properties'].get('postcode', '')
@property
def osm_id(self):
return self.parse['properties'].get('osm_id', '')
@property
def osm_value(self):
return self.parse['properties'].get('osm_value', '')
@property
def osm_key(self):
return self.parse['properties'].get('osm_key', '')
@property
def osm_type(self):
return self.parse['properties'].get('osm_type', '')
if __name__ == '__main__':
g = Komoot('Ottawa Ontario', result=3)
g.debug()
PK ,H'a$DH H geocoder/opencage_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import opencage_key
from geocoder.opencage import OpenCage
from geocoder.location import Location
class OpenCageReverse(OpenCage, Base):
"""
OpenCage Geocoding Services
===========================
OpenCage Geocoder simple, easy, and open geocoding for the entire world
Our API combines multiple geocoding systems in the background.
Each is optimized for different parts of the world and types of requests.
We aggregate the best results from open data sources and algorithms so you don't have to.
Each is optimized for different parts of the world and types of requests.
API Reference
-------------
http://geocoder.opencagedata.com/api.html
"""
provider = 'opencage'
method = 'reverse'
def __init__(self, location, **kwargs):
self.url = 'http://api.opencagedata.com/geocode/v1/json'
self.location = str(Location(location))
self.params = {
'query': self.location,
'key': self._get_api_key(opencage_key, **kwargs),
}
self._initialize(**kwargs)
@property
def ok(self):
return bool(self.address)
if __name__ == '__main__':
g = OpenCageReverse([45.4049053, -75.7077965])
g.debug()
PK fI9f: : geocoder/geocodefarm.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import six
from geocoder.base import Base
from geocoder.keys import geocodefarm_key
class GeocodeFarm(Base):
"""
Geocode.Farm
============
Geocode.Farm is one of the few providers that provide this highly
specialized service for free. We also have affordable paid plans, of
course, but our free services are of the same quality and provide the same
results. The major difference between our affordable paid plans and our
free API service is the limitations. On one of our affordable paid plans
your limit is set based on the plan you signed up for, starting at 25,000
query requests per day (API calls). On our free API offering, you are
limited to 250 query requests per day (API calls).
Params
------
:param location: The string to search for. Usually a street address.
:param key: (optional) API Key. Only Required for Paid Users.
:param lang: (optional) 2 digit lanuage code to return results in. Currently only "en"(English) or "de"(German) supported.
:param country: (optional) The country to return results in. Used for biasing purposes and may not fully filter results to this specific country.
API Reference
-------------
https://geocode.farm/geocoding/free-api-documentation/
"""
provider = 'geocodefarm'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'https://www.geocode.farm/v3/json/forward/'
key = kwargs.get('key', geocodefarm_key)
self.params = {
'addr': location,
'key': key if key else None,
'lang': kwargs.get('lang', ''),
'country': kwargs.get('country', ''),
}
self._initialize(**kwargs)
def _catch_errors(self):
status = self.parse['STATUS'].get('status')
if not status == 'SUCCESS':
self.error = status
def _exceptions(self):
geocoding_results = self.parse['geocoding_results']
if geocoding_results:
self._build_tree(geocoding_results['RESULTS'][0])
self._build_tree(geocoding_results['STATUS'])
self._build_tree(geocoding_results['ACCOUNT'])
@property
def lat(self):
lat = self.parse['COORDINATES'].get('latitude')
if lat:
return float(lat)
@property
def lng(self):
lng = self.parse['COORDINATES'].get('longitude')
if lng:
return float(lng)
@property
def accuracy(self):
return self.parse.get('accuracy')
@property
def bbox(self):
south = self.parse['BOUNDARIES'].get('southwest_latitude')
west = self.parse['BOUNDARIES'].get('southwest_longitude')
north = self.parse['BOUNDARIES'].get('northeast_latitude')
east = self.parse['BOUNDARIES'].get('northeast_longitude')
return self._get_bbox(south, west, north, east)
@property
def address(self):
return self.parse.get('formatted_address')
@property
def housenumber(self):
return self.parse['ADDRESS'].get('street_number')
@property
def street(self):
return self.parse['ADDRESS'].get('street_name')
@property
def neighborhood(self):
return self.parse['ADDRESS'].get('neighborhood')
@property
def city(self):
return self.parse['ADDRESS'].get('locality')
@property
def county(self):
return self.parse['ADDRESS'].get('admin_2')
@property
def state(self):
return self.parse['ADDRESS'].get('admin_1')
@property
def country(self):
return self.parse['ADDRESS'].get('country')
@property
def postal(self):
return self.parse['ADDRESS'].get('postal_code')
@property
def elevation(self):
return self.parse['LOCATION_DETAILS'].get('elevation')
@property
def timezone_long(self):
return self.parse['LOCATION_DETAILS'].get('timezone_long')
@property
def timezone_short(self):
return self.parse['LOCATION_DETAILS'].get('timezone_short')
@property
def access(self):
return self.parse['STATUS'].get('access')
@property
def address_provided(self):
return self.parse['STATUS'].get('address_provided')
@property
def ip_address(self):
return self.parse['ACCOUNT'].get('ip_address')
@property
def distribution_license(self):
return self.parse['ACCOUNT'].get('distribution_license')
@property
def usage_limit(self):
usage_limit = self.parse['ACCOUNT'].get('usage_limit')
if usage_limit:
return int(usage_limit)
@property
def used_today(self):
used_today = self.parse['ACCOUNT'].get('used_today')
if used_today:
return int(used_today)
@property
def used_total(self):
used_total = self.parse['ACCOUNT'].get('used_total')
if used_total:
return int(used_total)
@property
def first_used(self):
return self.parse['ACCOUNT'].get('first_used')
if __name__ == '__main__':
g = GeocodeFarm("New York City")
g.debug()
PK ,H^pGt t geocoder/w3w.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import w3w_key
class W3W(Base):
"""
What3Words
==========
What3Words is a global grid of 57 trillion 3mx3m squares.
Each square has a 3 word address that can be communicated quickly,
easily and with no ambiguity.
Addressing the world
Everyone and everywhere now has an address
Params
------
:param location: Your search location you want geocoded.
:param key: W3W API key.
:param method: Chose a method (geocode, method)
References
----------
API Reference: http://developer.what3words.com/
Get W3W key: http://developer.what3words.com/api-register/
"""
provider = 'w3w'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'https://api.what3words.com/w3w'
self.location = location
self.params = {
'string': location,
'key': self._get_api_key(w3w_key, **kwargs),
}
self._initialize(**kwargs)
@property
def lat(self):
position = self.parse['position']
if position:
return position[0]
@property
def lng(self):
position = self.parse['position']
if position:
return position[1]
@property
def language(self):
return self.parse.get('language')
@property
def type(self):
return self.parse.get('type')
@property
def words(self):
return self.parse.get('words')
if __name__ == '__main__':
g = W3W('embedded.fizzled.trial')
g.debug()
PK IzB&}
}
geocoder/bing.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import bing_key
import re
class Bing(Base):
"""
Bing Maps REST Services
=======================
The Bing™ Maps REST Services Application Programming Interface (API)
provides a Representational State Transfer (REST) interface to
perform tasks such as creating a static map with pushpins, geocoding
an address, retrieving imagery metadata, or creating a route.
API Reference
-------------
http://msdn.microsoft.com/en-us/library/ff701714.aspx
Get Bing key
------------
https://www.bingmapsportal.com/
"""
provider = 'bing'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'http://dev.virtualearth.net/REST/v1/Locations'
self.location = location
self.headers = {
'Referer': "http://addxy.com/",
'User-agent': 'Mozilla/5.0'
}
self.params = {
'q': location,
'o': 'json',
'inclnb': 1,
'key': self._get_api_key(bing_key, **kwargs),
'maxResults': 1
}
self._initialize(**kwargs)
def _catch_errors(self):
status = self.parse['statusDescription']
if not status == 'OK':
self.error = status
def _exceptions(self):
# Build intial Tree with results
sets = self.parse['resourceSets']
if sets:
resources = sets[0]['resources']
if resources:
self._build_tree(resources[0])
for item in self.parse['geocodePoints']:
self._build_tree(item)
@property
def lat(self):
coord = self.parse['point']['coordinates']
if coord:
return coord[0]
@property
def lng(self):
coord = self.parse['point']['coordinates']
if coord:
return coord[1]
@property
def address(self):
return self.parse['address'].get('formattedAddress')
@property
def housenumber(self):
if self.street:
expression = r'\d+'
pattern = re.compile(expression)
match = pattern.search(self.street, re.UNICODE)
if match:
return match.group(0)
@property
def street(self):
return self.parse['address'].get('addressLine')
@property
def neighborhood(self):
return self.parse['address'].get('neighborhood')
@property
def city(self):
return self.parse['address'].get('locality')
@property
def state(self):
return self.parse['address'].get('adminDistrict')
@property
def country(self):
return self.parse['address'].get('countryRegion')
@property
def quality(self):
return self.parse.get('entityType')
@property
def accuracy(self):
return self.parse.get('calculationMethod')
@property
def postal(self):
return self.parse['address'].get('postalCode')
@property
def bbox(self):
if self.parse['bbox']:
south = self.parse['bbox'][0]
north = self.parse['bbox'][2]
west = self.parse['bbox'][1]
east = self.parse['bbox'][3]
return self._get_bbox(south, west, north, east)
if __name__ == '__main__':
g = Bing('453 Booth Street, Ottawa Ontario')
g.debug()
PK ,HΠB B geocoder/mapquest_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.keys import mapquest_key
from geocoder.mapquest import Mapquest
from geocoder.location import Location
class MapquestReverse(Mapquest):
"""
MapQuest
========
The geocoding service enables you to take an address and get the
associated latitude and longitude. You can also use any latitude
and longitude pair and get the associated address. Three types of
geocoding are offered: address, reverse, and batch.
API Reference
-------------
http://www.mapquestapi.com/geocoding/
"""
provider = 'mapquest'
method = 'reverse'
def __init__(self, location, **kwargs):
self.url = 'http://www.mapquestapi.com/geocoding/v1/address'
self.location = str(Location(location))
self.headers = {
'referer': 'http://www.mapquestapi.com/geocoding/',
'host': 'www.mapquestapi.com',
}
self.params = {
'key': self._get_api_key(mapquest_key, **kwargs),
'location': self.location,
'maxResults': 1,
'outFormat': 'json',
}
self._initialize(**kwargs)
@property
def ok(self):
return bool(self.quality)
if __name__ == '__main__':
g = MapquestReverse([45.50, -76.05])
g.debug()
PK ,Hh h geocoder/google_elevation.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.location import Location
class Elevation(Base):
"""
Google Elevation API
====================
The Elevation API provides elevation data for all locations on the surface of the
earth, including depth locations on the ocean floor (which return negative values).
In those cases where Google does not possess exact elevation measurements at the
precise location you request, the service will interpolate and return an averaged
value using the four nearest locations.
API Reference
-------------
https://developers.google.com/maps/documentation/elevation/
"""
provider = 'google'
method = 'elevation'
def __init__(self, location, **kwargs):
self.url = 'https://maps.googleapis.com/maps/api/elevation/json'
self.location = str(Location(location))
self.params = {
'locations': self.location,
}
self._initialize(**kwargs)
def _exceptions(self):
# Build intial Tree with results
if self.parse['results']:
self._build_tree(self.parse['results'][0])
@property
def status(self):
if self.elevation:
return 'OK'
else:
return 'ERROR - No Elevation found'
@property
def ok(self):
return bool(self.elevation)
@property
def meters(self):
if self.elevation:
return round(self.elevation, 1)
@property
def feet(self):
if self.elevation:
return round(self.elevation * 3.28084, 1)
@property
def elevation(self):
return self.parse.get('elevation')
@property
def resolution(self):
return self.parse.get('resolution')
if __name__ == '__main__':
g = Elevation([45.123, -76.123])
g.debug()
PK fIJ geocoder/location.py#!/usr/bin/python
# coding: utf8
import re
import geocoder
from six import string_types
class Location(object):
""" Location container """
lat = None
lng = None
def __init__(self, location, **kwargs):
self.location = location
self.kwargs = kwargs
self._check_input(location)
@property
def ok(self):
return bool(self.latlng)
def _convert_float(self, number):
try:
return float(number)
except ValueError:
return None
def _check_input(self, location):
# Checking for a LatLng String
if isinstance(location, string_types):
expression = r"[-]?\d+[.]?[-]?[\d]+"
pattern = re.compile(expression)
match = pattern.findall(location)
if len(match) == 2:
lat, lng = match
self._check_for_list([lat, lng])
else:
# Check for string to Geocode using a provider
provider = self.kwargs.get('provider', 'osm')
g = geocoder.get(location, provider=provider)
if g.ok:
self.lat, self.lng = g.lat, g.lng
# Checking for List of Tuple
elif isinstance(location, (list, tuple)):
self._check_for_list(location)
# Checking for Dictionary
elif isinstance(location, dict):
self._check_for_dict(location)
# Checking for a Geocoder Class
elif hasattr(location, 'latlng'):
if location.latlng:
self.lat, self.lng = location.latlng
# Result into Error
else:
raise ValueError("Unknown location: %s" % location)
def _check_for_list(self, location):
# Standard LatLng list or tuple with 2 number values
if len(location) == 2:
lat = self._convert_float(location[0])
lng = self._convert_float(location[1])
condition_1 = isinstance(lat, float)
condition_2 = isinstance(lng, float)
# Check if input are Floats
if condition_1 and condition_2:
condition_3 = -90 <= lat <= 90
condition_4 = -180 <= lng <= 180
# Check if inputs are within the World Geographical
# boundary (90,180,-90,-180)
if condition_3 and condition_4:
self.lat = lat
self.lng = lng
return self.lat, self.lng
else:
raise ValueError("Coords are not within the world's geographical boundary")
else:
raise ValueError("Coordinates must be numbers")
def _check_for_dict(self, location):
# Standard LatLng list or tuple with 2 number values
if 'lat' in location and 'lng' in location:
lat = location['lat']
lng = location['lng']
self._check_for_list([lat, lng])
if 'y' in location and 'x' in location:
lat = location['y']
lng = location['x']
self._check_for_list([lat, lng])
@property
def latlng(self):
if isinstance(self.lat, float) and isinstance(self.lng, float):
return [self.lat, self.lng]
return []
@property
def latitude(self):
return self.lat
@property
def longitude(self):
return self.lng
@property
def xy(self):
if isinstance(self.lat, float) and isinstance(self.lng, float):
return [self.lng, self.lat]
return []
def __str__(self):
if self.ok:
return u'{0}, {1}'.format(self.lat, self.lng)
return u''
if __name__ == '__main__':
l = Location([0.0, 0.0])
print(l.lng)
PK ,H geocoder/baidu.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import baidu_key
class Baidu(Base):
"""
Baidu Geocoding API
===================
Baidu Maps Geocoding API is a free open the API, the default quota
one million times / day.
Params
------
:param location: Your search location you want geocoded.
:param key: Baidu API key.
:param referer: Baidu API referer website.
References
----------
API Documentation: http://developer.baidu.com/map
Get Baidu Key: http://lbsyun.baidu.com/apiconsole/key
"""
provider = 'baidu'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'http://api.map.baidu.com/geocoder/v2/'
self.location = location
self.params = {
'address': location,
'output': 'json',
'ak': self._get_api_key(baidu_key, **kwargs),
}
self.headers = {'Referer': kwargs.get('referer', 'http://developer.baidu.com')}
self._initialize(**kwargs)
@property
def lat(self):
return self.parse['location'].get('lat')
@property
def lng(self):
return self.parse['location'].get('lng')
@property
def quality(self):
return self.parse['result'].get('level')
@property
def accuracy(self):
return self.parse['result'].get('confidence')
if __name__ == '__main__':
g = Baidu('中国')
g.debug()
PK wI.* * geocoder/tomtom.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import tomtom_key
class Tomtom(Base):
"""
Geocoding API
=============
The Geocoding API gives developers access to TomTom’s first class geocoding service.
Developers may call this service through either a single or batch geocoding request.
This service supports global coverage, with house number level matching in over 50 countries,
and address point matching where available.
API Reference
-------------
http://developer.tomtom.com/products/geocoding_api
"""
provider = 'tomtom'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'https://api.tomtom.com/lbs/geocoding/geocode'
self.location = location
self.params = {
'query': location,
'format': 'json',
'key': self._get_api_key(tomtom_key, **kwargs),
'maxResults': 1,
}
self._initialize(**kwargs)
def _exceptions(self):
# Build intial Tree with results
result = self.parse['geoResponse']['geoResult']
if result:
self._build_tree(result[0])
def _catch_errors(self):
if self.content == '
Developer Inactive
':
self.error = 'API Key not valid'
self.status_code = 401
@property
def lat(self):
return self.parse.get('latitude')
@property
def lng(self):
return self.parse.get('longitude')
@property
def address(self):
return self.parse.get('formattedAddress')
@property
def housenumber(self):
return self.parse.get('houseNumber')
@property
def street(self):
return self.parse.get('street')
@property
def city(self):
return self.parse.get('city')
@property
def state(self):
return self.parse.get('state')
@property
def country(self):
return self.parse.get('country')
@property
def geohash(self):
return self.parse.get('geohash')
@property
def postal(self):
return self.parse.get('postcode')
@property
def quality(self):
return self.parse.get('type')
if __name__ == '__main__':
g = Tomtom('1552 Payette dr., Ottawa')
g.debug()
PK ,H#7 geocoder/yahoo.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
class Yahoo(Base):
"""
Yahoo BOSS Geo Services
=======================
Yahoo PlaceFinder is a geocoding Web service that helps developers make
their applications location-aware by converting street addresses or
place names into geographic coordinates (and vice versa).
API Reference
-------------
https://developer.yahoo.com/boss/geo/
"""
provider = 'yahoo'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'https://sgws2.maps.yahoo.com/FindLocation'
self.location = location
self.params = {
'q': location,
'flags': 'J',
'locale': kwargs.get('locale', 'en-CA'),
}
self._initialize(**kwargs)
def _catch_errors(self):
status = self.parse['statusDescription']
if status:
if not status == 'OK':
self.error = status
def _exceptions(self):
# Build intial Tree with results
if self.parse['Result']:
self._build_tree(self.parse['Result'])
@property
def lat(self):
return self.parse.get('latitude')
@property
def lng(self):
return self.parse.get('longitude')
@property
def address(self):
line1 = self.parse.get('line1')
line2 = self.parse.get('line2')
if line1:
return ', '.join([line1, line2])
else:
return line2
@property
def housenumber(self):
return self.parse.get('house')
@property
def street(self):
return self.parse.get('street')
@property
def neighborhood(self):
return self.parse.get('neighborhood')
@property
def city(self):
return self.parse.get('city')
@property
def county(self):
return self.parse.get('county')
@property
def state(self):
return self.parse.get('state')
@property
def country(self):
return self.parse.get('country')
@property
def hash(self):
return self.parse.get('hash')
@property
def quality(self):
return self.parse.get('addressMatchType')
@property
def postal(self):
postal = self.parse.get('postal')
if postal:
return postal
else:
return self.parse.get('uzip')
if __name__ == '__main__':
g = Yahoo('1552 Payette dr., Ottawa, ON')
g.debug()
PK fIHxy geocoder/mapbox.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import mapbox_access_token
from geocoder.location import Location
class Mapbox(Base):
"""
Mapbox Geocoding
================
The Mapbox Geocoding API lets you convert location text into
geographic coordinates (1600 Pennsylvania Ave NW → -77.0366,38.8971).
API Reference
-------------
https://www.mapbox.com/developers/api/geocoding/
Get Mapbox Access Token
-----------------------
https://www.mapbox.com/account
"""
provider = 'mapbox'
method = 'geocode'
def __init__(self, location, **kwargs):
self.location = location
self.url = u'https://api.mapbox.com/geocoding/v5/mapbox.places/{0}.json'.format(location)
self.params = {
'access_token': self._get_api_key(mapbox_access_token, **kwargs),
'country': kwargs.get('country'),
'proximity': self._get_proximity(),
'types': kwargs.get('types'),
}
self._get_proximity(**kwargs)
self._initialize(**kwargs)
def _exceptions(self):
# Build intial Tree with results
features = self.parse['features']
if features:
self._build_tree(features[0])
for item in self.parse['context']:
if '.' in item['id']:
# attribute=country & text=Canada
attribute = item['id'].split('.')[0]
self.parse[attribute] = item['text']
def _get_proximity(self, **kwargs):
if 'proximity' in kwargs:
lat, lng = Location(kwargs['proximity']).latlng
return u'{0},{1}'.format(lng, lat)
@property
def lat(self):
coord = self.parse['geometry']['coordinates']
if coord:
return coord[1]
@property
def lng(self):
coord = self.parse['geometry']['coordinates']
if coord:
return coord[0]
@property
def address(self):
return self.parse.get('place_name')
@property
def housenumber(self):
return self.parse.get('address')
@property
def street(self):
return ''
@property
def city(self):
return self.parse.get('place')
@property
def state(self):
return self.parse.get('region')
@property
def country(self):
return self.parse.get('country')
@property
def postal(self):
return self.parse.get('postcode')
@property
def accuracy(self):
if self.interpolated:
return "interpolated"
@property
def quality(self):
return self.parse.get('relevance')
@property
def interpolated(self):
return self.parse['geometry'].get('interpolated')
@property
def bbox(self):
if self.parse['bbox']:
west = self.parse['bbox'][0]
south = self.parse['bbox'][1]
east = self.parse['bbox'][2]
north = self.parse['bbox'][3]
return self._get_bbox(south, west, north, east)
if __name__ == '__main__':
g = Mapbox("200 Queen Street", proximity=[45.3, -66.1])
print(g.address)
g = Mapbox("200 Queen Street")
print(g.address)
g.debug()
PK ,Hce/ / geocoder/w3w_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import w3w_key
from geocoder.w3w import W3W
from geocoder.location import Location
class W3WReverse(W3W, Base):
"""
what3words
==========
what3words is a global grid of 57 trillion 3mx3m squares.
Each square has a 3 word address that can be communicated quickly,
easily and with no ambiguity.
Addressing the world
Everyone and everywhere now has an address
Params
------
:param location: Your search location you want geocoded.
:param key: W3W API key.
:param method: Chose a method (geocode, method)
References
----------
API Reference: http://developer.what3words.com/
Get W3W key: http://developer.what3words.com/api-register/
"""
provider = 'w3w'
method = 'reverse'
def __init__(self, location, **kwargs):
self.url = 'https://api.what3words.com/position'
self.location = str(Location(location))
self.params = {
'position': self.location,
'key': kwargs.get('key', w3w_key),
}
self._initialize(**kwargs)
@property
def ok(self):
return bool(self.words)
if __name__ == '__main__':
g = W3WReverse([45.15, -75.14])
g.debug()
PK fI9 geocoder/mapzen_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.mapzen import Mapzen
from geocoder.location import Location
from geocoder.keys import mapzen_key
class MapzenReverse(Mapzen):
"""
Mapzen REST API
=======================
API Reference
-------------
https://mapzen.com/documentation/search/reverse/
"""
provider = 'mapzen'
method = 'reverse'
def __init__(self, location, **kwargs):
self.url = 'https://search.mapzen.com/v1/reverse'
self.location = location
location = Location(location)
self.params = {
'point.lat': location.lat,
'point.lon': location.lng,
'size': kwargs.get('size', 1),
'layers': kwargs.get('layers'),
'source': kwargs.get('sources'),
'boundary.country': kwargs.get('country'),
'api_key': self._get_api_key(mapzen_key, **kwargs) if mapzen_key or 'key' in kwargs else None
}
self._initialize(**kwargs)
@property
def ok(self):
return bool(self.address)
if __name__ == '__main__':
g = MapzenReverse("45.4049053 -75.7077965", key='search-un1M9Hk')
g.debug()
PK 6|HG.b b geocoder/arcgis.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
class Arcgis(Base):
"""
ArcGIS REST API
=======================
The World Geocoding Service finds addresses and places in all supported countries
from a single endpoint. The service can find point locations of addresses,
business names, and so on. The output points can be visualized on a map,
inserted as stops for a route, or loaded as input for a spatial analysis.
an address, retrieving imagery metadata, or creating a route.
API Reference
-------------
https://developers.arcgis.com/rest/geocode/api-reference/geocoding-find.htm
"""
provider = 'arcgis'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find'
self.location = location
self.params = {
'f': 'json',
'text': location,
'maxLocations': kwargs.get('limit', 1),
}
self._initialize(**kwargs)
def _exceptions(self):
if self.parse['locations']:
self._build_tree(self.parse['locations'][0])
def __iter__(self):
for item in self.content['locations']:
yield item
@property
def lat(self):
return self.parse['geometry'].get('y')
@property
def lng(self):
return self.parse['geometry'].get('x')
@property
def address(self):
return self.parse.get('name', '')
@property
def score(self):
return self.parse['attributes'].get('Score', '')
@property
def quality(self):
return self.parse['attributes'].get('Addr_Type', '')
@property
def bbox(self):
if self.parse['extent']:
south = self.parse['extent'].get('ymin')
west = self.parse['extent'].get('xmin')
north = self.parse['extent'].get('ymax')
east = self.parse['extent'].get('xmax')
return self._get_bbox(south, west, north, east)
if __name__ == '__main__':
g = Arcgis('Toronto')
g.debug()
PK /IF% F% geocoder/osm.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
class Osm(Base):
"""
Nominatim
=========
Nominatim (from the Latin, 'by name') is a tool to search OSM data by name
and address and to generate synthetic addresses of OSM points (reverse geocoding).
API Reference
-------------
http://wiki.openstreetmap.org/wiki/Nominatim
"""
provider = 'osm'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = self._get_osm_url(kwargs.get('url', ''))
self.location = location
self.params = {
'q': location,
'format': 'jsonv2',
'addressdetails': 1,
'limit': kwargs.get('limit', 1),
}
self._initialize(**kwargs)
def _get_osm_url(self, url):
if url.lower() == 'localhost':
return 'http://localhost/nominatim/search'
elif url:
return url
else:
return 'https://nominatim.openstreetmap.org/search'
def _exceptions(self):
if self.content:
self._build_tree(self.content[0])
def __iter__(self):
for item in self.content:
yield item
# ============================ #
# Geometry - Points & Polygons #
# ============================ #
@property
def lat(self):
lat = self.parse.get('lat')
if lat:
return float(lat)
@property
def lng(self):
lng = self.parse.get('lon')
if lng:
return float(lng)
@property
def bbox(self):
if self.parse['boundingbox']:
south = float(self.parse['boundingbox'][0])
west = float(self.parse['boundingbox'][2])
north = float(self.parse['boundingbox'][1])
east = float(self.parse['boundingbox'][3])
return self._get_bbox(south, west, north, east)
# ========================== #
# Tags for individual houses #
# ========================== #
@property
def address(self):
return self.parse.get('display_name')
@property
def housenumber(self):
return self.parse['address'].get('house_number')
@property
def street(self):
return self.parse['address'].get('road')
@property
def postal(self):
return self.parse['address'].get('postcode')
# ============================ #
# Populated settlements, urban #
# ============================ #
@property
def neighborhood(self):
"""place=neighborhood
A named part of a place=village, a place=town or a place=city. Smaller
than place=suburb and place=quarter.
The tag can be used for any kind of landuse or mix of landuse (such as
residential, commercial, industrial etc). Usage of this term depends
greatly on local history, culture, politics, economy and organization
of settlements. More specific rules are intentionally avoided.
Note: the British English spelling is used rather than the
American English spelling of neighborhood.
"""
return self.parse['address'].get('neighbourhood')
@property
def suburb(self):
"""place=suburb
A distinct section of an urban settlement (city, town, etc.) with its
own name and identity. e.g.
- annexed towns or villages which were formerly independent,
- independent (or dependent) municipalities within a city or next to a
much bigger town
- historical districts of settlements
- industrial districts or recreation areas within a settlements with
specific names.
"""
return self.parse['address'].get('suburb')
@property
def quarter(self):
"""place=quarter
A named part of a bigger settlement where this part is smaller than
a suburb and bigger than a neighbourhood. This does not have to be
an administrative entity.
The term quarter is sometimes used synonymously for neighbourhood.
"""
return self.parse['address'].get('quarter')
# ====================================== #
# Populated settlements, urban and rural #
# ====================================== #
@property
def allotments(self):
"""place=allotments
Dacha or cottage settlement, which is located outside other
inhabited locality. This value is used mainly in Russia and other
countries of the former Soviet Union, where a lot of such unofficial
settlements exist
"""
return self.parse['address'].get('hamlet')
@property
def farm(self):
"""place=farm
A farm that has its own name. If the farm is not a part of bigger
settlement use place=isolated_dwelling. See also landuse=farmyard
"""
return self.parse['address'].get('hamlet')
@property
def locality(self):
"""place=isolated_dwelling
For an unpopulated named place.
"""
return self.parse['address'].get('locality')
@property
def isolated_dwelling(self):
"""place=isolated_dwelling
Smallest kind of human settlement. No more than 2 households.
"""
return self.parse['address'].get('hamlet')
@property
def hamlet(self):
"""place=hamlet
A smaller rural community typically with less than 100-200 inhabitants,
few infrastructure.
"""
return self.parse['address'].get('hamlet')
@property
def village(self):
"""place=village
A smaller distinct settlement, smaller than a town with few facilities
available with people traveling to nearby towns to access these.
Populations of villages vary widely in different territories but will
nearly always be less than 10,000 people, often a lot less.
See place=neighbourhood on how to tag divisions within a larger village
"""
return self.parse['address'].get('village')
@property
def town(self):
"""place=town
A second tier urban settlement of local importance, often with a
population of 10,000 people and good range of local facilities
including schools, medical facilities etc and traditionally a market.
In areas of low population, towns may have significantly
lower populations.
See place=neighbourhood and possibly also place=suburb on how to tag
divisions within a town.
"""
return self.parse['address'].get('town')
@property
def island(self):
"""place=island
Identifies the coastline of an island (> 1 km2), also consider
place=islet for very small islandsIdentifies the coastline of an
island (> 1 km2), also consider place=islet for very small islands
"""
return self.parse['address'].get('island')
@property
def city(self):
"""place=city
The largest urban settlements in the territory, normally including the
national, state and provincial capitals. These are defined by charter
or other governmental designation in some territories and are a matter
of judgement in others. Should normally have a population of at
least 100,000 people and be larger than nearby towns.
See place=suburb and place=neighbourhood on how to tag divisions
within a city. The outskirts of urban settlements may or may not match
the administratively declared boundary of the city.
"""
return self.parse['address'].get('city')
# ================================ #
# Administratively declared places #
# ================================ #
@property
def municipality(self):
"""admin_level=8"""
return self.parse['address'].get('municipality')
@property
def county(self):
"""admin_level=6"""
return self.parse['address'].get('county')
@property
def district(self):
"""admin_level=5/6"""
return self.parse['address'].get('city_district')
@property
def state(self):
"""admin_level=4"""
return self.parse['address'].get('state')
@property
def region(self):
"""admin_level=3"""
return self.parse['address'].get('state')
@property
def country(self):
"""admin_level=2"""
return self.parse['address'].get('country')
# ======================== #
# Quality Control & Others #
# ======================== #
@property
def accuracy(self):
return self.importance
@property
def quality(self):
return self.type
@property
def population(self):
return self.parse.get('population')
@property
def license(self):
return self.parse.get('license')
@property
def type(self):
return self.parse.get('type')
@property
def importance(self):
return self.parse.get('importance')
@property
def icon(self):
return self.parse.get('icon')
@property
def osm_type(self):
return self.parse.get('osm_type')
@property
def osm_id(self):
return self.parse.get('osm_id')
@property
def place_id(self):
return self.parse.get('place_id')
@property
def place_rank(self):
return self.parse.get('place_rank')
if __name__ == '__main__':
g = Osm("Ottawa, ON")
g.debug()
PK fIuD geocoder/arcgis_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.arcgis import Arcgis
from geocoder.location import Location
class ArcgisReverse(Arcgis):
"""
ArcGIS REST API
=======================
The World Geocoding Service finds addresses and places in all supported countries
from a single endpoint. The service can find point locations of addresses,
business names, and so on. The output points can be visualized on a map,
inserted as stops for a route, or loaded as input for a spatial analysis.
an address, retrieving imagery metadata, or creating a route.
API Reference
-------------
https://developers.arcgis.com/rest/geocode/api-reference/geocoding-reverse-geocode.htm
"""
provider = 'arcgis'
method = 'reverse'
def __init__(self, location, **kwargs):
self.url = 'https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode'
self.location = location
location = Location(location)
self.params = {
'location': u'{}, {}'.format(location.lng, location.lat),
'f': 'pjson',
'distance': kwargs.get('distance', 50000),
'outSR': kwargs.get('outSR', ''),
'maxLocations': kwargs.get('limit', 1),
}
self._initialize(**kwargs)
def _catch_errors(self):
error = self.parse['error']
if error:
self.error = error['message']
@property
def ok(self):
return bool(self.address)
@property
def lat(self):
return self.parse['location'].get('y')
@property
def lng(self):
return self.parse['location'].get('x')
@property
def address(self):
return self.parse['address'].get('Match_addr')
@property
def city(self):
return self.parse['address'].get('City')
@property
def neighborhood(self):
return self.parse['address'].get('Neighbourhood')
@property
def region(self):
return self.parse['address'].get('Region')
@property
def country(self):
return self.parse['address'].get('CountryCode')
@property
def postal(self):
return self.parse['address'].get('Postal')
@property
def state(self):
return self.parse['address'].get('Region')
def _exceptions(self):
self._build_tree(self.content)
if __name__ == '__main__':
g = ArcgisReverse("45.404702, -75.704150")
g.debug()
PK fIؓ
geocoder/distance.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from math import radians, cos, sin, asin, sqrt
from geocoder.location import Location
AVG_EARTH_RADIUS = 6371 # in km
def Distance(*args, **kwargs):
total = 0.0
last = None
if len(args) == 1 and isinstance(args, (list, tuple)):
args = args[0]
if len(args) <= 1:
raise ValueError("Distance needs at least two locations")
for location in args:
if last:
distance = haversine(Location(last), Location(location), **kwargs)
if distance:
total += distance
last = location
return total
def haversine(point1, point2, **kwargs):
""" Calculate the great-circle distance bewteen two points on the Earth surface.
:input: two 2-tuples, containing the latitude and longitude of each point
in decimal degrees.
Example: haversine((45.7597, 4.8422), (48.8567, 2.3508))
:output: Returns the distance bewteen the two points.
The default unit is kilometers. Miles can be returned
if the ``miles`` parameter is set to True.
"""
lookup_units = {
'miles': 'miles',
'mile': 'miles',
'mi': 'miles',
'ml': 'miles',
'kilometers': 'kilometers',
'kilometres': 'kilometers',
'kilometer': 'kilometers',
'kilometre': 'kilometers',
'km': 'kilometers',
'meters': 'meters',
'metres': 'meters',
'meter': 'meters',
'metre': 'meters',
'm': 'meters',
'feet': 'feet',
'f': 'feet',
'ft': 'feet',
}
if point1.ok and point2.ok:
# convert all latitudes/longitudes from decimal degrees to radians
lat1, lng1, lat2, lng2 = list(map(radians, point1.latlng + point2.latlng))
# calculate haversine
lat = lat2 - lat1
lng = lng2 - lng1
d = sin(lat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(lng / 2) ** 2
h = 2 * AVG_EARTH_RADIUS * asin(sqrt(d))
# Measurements
units = kwargs.get('units', 'kilometers').lower()
units_calculation = {
'miles': h * 0.621371,
'feet': h * 0.621371 * 5280,
'meters': h * 1000,
'kilometers': h,
}
if units in lookup_units:
return units_calculation[lookup_units[units]]
else:
raise ValueError("Unknown units of measurement")
else:
print(u'[WARNING] Error calculating the following two locations.\n'
'Points: {0} to {1}'.format(point1.location, point2.location))
if __name__ == '__main__':
d = Distance('Ottawa, ON', 'Toronto, ON', 'Montreal, QC')
print(d)
PK ,H geocoder/mapbox_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.mapbox import Mapbox
from geocoder.keys import mapbox_access_token
from geocoder.location import Location
class MapboxReverse(Mapbox, Base):
"""
Mapbox Reverse Geocoding
========================
Reverse geocoding lets you reverse this process, turning a
pair of lat/lon coordinates into a meaningful place name
(-77.036,38.897 → 1600 Pennsylvania Ave NW).
API Reference
-------------
https://www.mapbox.com/developers/api/geocoding/
Get Mapbox Access Token
-----------------------
https://www.mapbox.com/account
"""
provider = 'mapbox'
method = 'reverse'
def __init__(self, location, **kwargs):
self.location = str(Location(location))
lat, lng = Location(location).latlng
self.url = 'https://api.mapbox.com/geocoding/v5/mapbox.places/'\
'{lng},{lat}.json'.format(lng=lng, lat=lat)
self.params = {
'access_token': self._get_api_key(mapbox_access_token, **kwargs),
'country': kwargs.get('country'),
'proximity': self._get_proximity(),
'types': kwargs.get('types'),
}
self._initialize(**kwargs)
@property
def ok(self):
return bool(self.address)
if __name__ == '__main__':
g = MapboxReverse([45.4049053, -75.7077965])
g.debug()
PK ,H geocoder/osm_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.osm import Osm
from geocoder.location import Location
class OsmReverse(Osm):
"""
Nominatim
=========
Nominatim (from the Latin, 'by name') is a tool to search OSM data by name
and address and to generate synthetic addresses of OSM points (reverse geocoding).
API Reference
-------------
http://wiki.openstreetmap.org/wiki/Nominatim
"""
provider = 'osm'
method = 'reverse'
def __init__(self, location, **kwargs):
self.url = self._get_osm_url(kwargs.get('url', ''))
self.location = location
location = Location(location)
self.params = {
'q': str(location),
'format': 'jsonv2',
'addressdetails': 1,
'limit': kwargs.get('limit', 1)
}
self._initialize(**kwargs)
if __name__ == '__main__':
g = OsmReverse("45.3, -75.4")
g.debug()
PK ,H:o o geocoder/opencage.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import opencage_key
class OpenCage(Base):
"""
OpenCage Geocoding Services
===========================
OpenCage Geocoder simple, easy, and open geocoding for the entire world
Our API combines multiple geocoding systems in the background.
Each is optimized for different parts of the world and types of requests.
We aggregate the best results from open data sources and algorithms so you don't have to.
Each is optimized for different parts of the world and types of requests.
API Reference
-------------
http://geocoder.opencagedata.com/api.html
"""
provider = 'opencage'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'http://api.opencagedata.com/geocode/v1/json'
self.location = location
self.params = {
'query': location,
'key': self._get_api_key(opencage_key, **kwargs),
}
self._initialize(**kwargs)
def _catch_errors(self):
if self.content:
status = self.content.get('status')
if status:
self.status_code = status.get('code')
message = status.get('message')
if self.status_code:
self.error = message
def _exceptions(self):
# Build intial Tree with results
if self.parse['results']:
self._build_tree(self.parse['results'][0])
licenses = self.parse['licenses']
if licenses:
self.parse['licenses'] = licenses[0]
@property
def lat(self):
return self.parse['geometry'].get('lat')
@property
def lng(self):
return self.parse['geometry'].get('lng')
@property
def address(self):
return self.parse.get('formatted')
@property
def housenumber(self):
return self.parse['components'].get('house_number')
@property
def street(self):
return self.parse['components'].get('road')
@property
def neighborhood(self):
neighbourhood = self.parse['components'].get('neighbourhood')
if neighbourhood:
return neighbourhood
elif self.suburb:
return self.suburb
elif self.city_district:
return self.city_district
@property
def suburb(self):
return self.parse['components'].get('suburb')
@property
def city_district(self):
return self.parse['components'].get('city_district')
@property
def city(self):
city = self.parse['components'].get('city')
if city:
return city
elif self.town:
return self.town
elif self.county:
return self.county
@property
def town(self):
return self.parse['components'].get('town')
@property
def county(self):
return self.parse['components'].get('county')
@property
def state(self):
return self.parse['components'].get('state')
@property
def country(self):
return self.parse['components'].get('country_code')
@property
def postal(self):
return self.parse['components'].get('postcode')
@property
def confidence(self):
return self.parse.get('confidence')
@property
def w3w(self):
return self.parse['what3words'].get('words')
@property
def mgrs(self):
return self.parse['annotations'].get('MGRS')
@property
def geohash(self):
return self.parse['annotations'].get('geohash')
@property
def callingcode(self):
return self.parse['annotations'].get('callingcode')
@property
def Maidenhead(self):
return self.parse['annotations'].get('Maidenhead')
@property
def DMS(self):
return self.parse.get('DMS')
@property
def Mercator(self):
return self.parse.get('Mercator')
@property
def license(self):
return self.parse.get('licenses')
@property
def bbox(self):
south = self.parse['southwest'].get('lat')
north = self.parse['northeast'].get('lat')
west = self.parse['southwest'].get('lng')
east = self.parse['northeast'].get('lng')
return self._get_bbox(south, west, north, east)
if __name__ == '__main__':
g = OpenCage('1552 Payette dr., Ottawa')
print(g.json['mgrs'])
PK fI
_j geocoder/bing_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.bing import Bing
from geocoder.keys import bing_key
from geocoder.location import Location
class BingReverse(Bing):
"""
Bing Maps REST Services
=======================
The Bing™ Maps REST Services Application Programming Interface (API)
provides a Representational State Transfer (REST) interface to
perform tasks such as creating a static map with pushpins, geocoding
an address, retrieving imagery metadata, or creating a route.
API Reference
-------------
http://msdn.microsoft.com/en-us/library/ff701714.aspx
"""
provider = 'bing'
method = 'reverse'
def __init__(self, location, **kwargs):
self.location = str(Location(location))
self.url = u'http://dev.virtualearth.net/' \
'REST/v1/Locations/{0}'.format(self.location)
self.params = {
'o': 'json',
'key': self._get_api_key(bing_key, **kwargs),
'maxResults': 1,
}
self._initialize(**kwargs)
@property
def ok(self):
return bool(self.address)
if __name__ == '__main__':
g = BingReverse([45.4049053, -75.7077965], key=None)
g.debug()
PK fIg geocoder/google_timezone.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import time
from geocoder.base import Base
from geocoder.location import Location
class Timezone(Base):
"""
Google Time Zone API
====================
The Time Zone API provides time offset data for locations on the surface of the earth.
Requesting the time zone information for a specific Latitude/Longitude pair will
return the name of that time zone, the time offset from UTC, and the Daylight Savings offset.
API Reference
-------------
https://developers.google.com/maps/documentation/timezone/
"""
provider = 'google'
method = 'timezone'
def __init__(self, location, **kwargs):
self.url = 'https://maps.googleapis.com/maps/api/timezone/json'
self.location = str(Location(location))
self.timestamp = kwargs.get('timestamp', time.time())
self.params = {
'location': self.location,
'timestamp': self.timestamp,
}
self._initialize(**kwargs)
def __repr__(self):
return u'<[{0}] {1} [{2}]>'.format(self.status, self.provider, self.timeZoneName)
def _exceptions(self):
if self.parse['results']:
self._build_tree(self.parse['results'][0])
@property
def ok(self):
return bool(self.timeZoneName)
@property
def timeZoneId(self):
return self.parse.get('timeZoneId')
@property
def timeZoneName(self):
return self.parse.get('timeZoneName')
@property
def rawOffset(self):
return self.parse.get('rawOffset')
@property
def dstOffset(self):
return self.parse.get('dstOffset')
if __name__ == '__main__':
g = Timezone([45.5375801, -75.2465979])
g.debug()
PK fI geocoder/geolytica.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
class Geolytica(Base):
"""
Geocoder.ca
===========
A Canadian and US location geocoder.
API Reference
-------------
http://geocoder.ca/?api=1
"""
provider = 'geolytica'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'http://geocoder.ca'
self.location = location
self.params = {
'json': 1,
'locate': location,
'geoit': 'xml'
}
if 'strictmode' in kwargs:
self.params.update({'strictmode': kwargs.pop('strictmode')})
if 'strict' in kwargs:
self.params.update({'strict': kwargs.pop('strict')})
if 'auth' in kwargs:
self.params.update({'auth': kwargs.pop('auth')})
self._initialize(**kwargs)
@property
def lat(self):
lat = self.parse.get('latt', '').strip()
if lat:
return float(lat)
@property
def lng(self):
lng = self.parse.get('longt', '').strip()
if lng:
return float(lng)
@property
def postal(self):
return self.parse.get('postal', '').strip()
@property
def housenumber(self):
return self.parse['standard'].get('stnumber', '').strip()
@property
def street(self):
return self.parse['standard'].get('staddress', '').strip()
@property
def city(self):
return self.parse['standard'].get('city', '').strip()
@property
def state(self):
return self.parse['standard'].get('prov', '').strip()
@property
def address(self):
if self.street_number:
return u'{0} {1}, {2}'.format(self.street_number, self.route, self.locality)
elif self.route and self.route != 'un-known':
return u'{0}, {1}'.format(self.route, self.locality)
else:
return self.locality
if __name__ == '__main__':
g = Geolytica('1552 Payette dr., Ottawa')
g.debug()
PK fIj geocoder/mapzen.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import mapzen_key
class Mapzen(Base):
"""
Mapzen REST API
=======================
API Reference
-------------
https://mapzen.com/documentation/search/search/
"""
provider = 'mapzen'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'https://search.mapzen.com/v1/search'
self.location = location
self.params = {
'text': location,
'api_key': kwargs.get('key') or mapzen_key,
'size': kwargs.get('size', 1)
}
self._initialize(**kwargs)
def _exceptions(self):
# Only retrieve the first feature
features = self.parse['features']
if features:
self._build_tree(self.parse['features'][0])
def __iter__(self):
for item in self.content['features']:
yield item
@property
def lat(self):
return self.parse['geometry']['coordinates'][1]
@property
def lng(self):
return self.parse['geometry']['coordinates'][0]
@property
def bbox(self):
extent = self.parse['bbox']
if extent:
west = extent[0]
north = extent[1]
east = extent[2]
south = extent[3]
return self._get_bbox(south, west, north, east)
@property
def address(self):
return self.parse['properties'].get('label')
@property
def housenumber(self):
return self.parse['properties'].get('housenumber')
@property
def street(self):
return self.parse['properties'].get('street')
@property
def neighbourhood(self):
return self.parse['properties'].get('neighbourhood')
@property
def city(self):
return self.parse['properties'].get('locality')
@property
def state(self):
return self.parse['properties'].get('region')
@property
def country(self):
return self.parse['properties'].get('country')
@property
def postal(self):
return self.parse['properties'].get('postalcode')
@property
def gid(self):
return self.parse['properties'].get('gid')
@property
def id(self):
return self.parse['properties'].get('id')
if __name__ == '__main__':
g = Mapzen('201 Spear Street, San Francisco')
g.debug()
PK fIC`^ geocoder/yandex_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.yandex import Yandex
from geocoder.location import Location
class YandexReverse(Yandex, Base):
"""
Yandex
======
Yandex (Russian: Яндекс) is a Russian Internet company
which operates the largest search engine in Russia with
about 60% market share in that country.
The Yandex home page has been rated as the most popular website in Russia.
Params
------
:param location: Your search location you want geocoded.
:param lang: Chose the following language:
> ru-RU — Russian (by default)
> uk-UA — Ukrainian
> be-BY — Belarusian
> en-US — American English
> en-BR — British English
> tr-TR — Turkish (only for maps of Turkey)
:param kind: Type of toponym (only for reverse geocoding):
> house - house or building
> street - street
> metro - subway station
> district - city district
> locality - locality (city, town, village, etc.)
References
----------
API Reference: http://api.yandex.com/maps/doc/geocoder/
desc/concepts/input_params.xml
"""
provider = 'yandex'
method = 'reverse'
def __init__(self, location, **kwargs):
self.url = 'http://geocode-maps.yandex.ru/1.x/'
location = location
x, y = Location(location).xy
self.location = u'{}, {}'.format(x, y)
self.params = {
'geocode': self.location,
'lang': kwargs.get('lang', 'en-US'),
'kind': kwargs.get('kind', ''),
'format': 'json',
'results': 1,
}
self._initialize(**kwargs)
@property
def ok(self):
return bool(self.address)
if __name__ == '__main__':
g = YandexReverse({'lat': 41.005407, 'lng': 28.978349})
g.debug()
PK efI߈B( ( geocoder/base.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import requests
import sys
import json
import six
from collections import defaultdict
from geocoder.distance import Distance
is_python2 = sys.version_info < (3, 0)
class Base(object):
_exclude = ['parse', 'json', 'url', 'fieldnames', 'help', 'debug',
'short_name', 'api', 'content', 'params',
'street_number', 'api_key', 'key', 'id', 'x', 'y',
'latlng', 'headers', 'timeout', 'wkt', 'locality',
'province', 'rate_limited_get', 'osm', 'route', 'schema',
'properties', 'geojson', 'tree', 'error', 'proxies', 'road',
'xy', 'northeast', 'northwest', 'southeast', 'southwest',
'road_long', 'city_long', 'state_long', 'country_long',
'postal_town_long', 'province_long', 'road_long',
'street_long', 'interpolated', 'method', 'geometry']
fieldnames = []
error = None
status_code = None
headers = {}
params = {}
# Essential attributes for Quality Control
lat = ''
lng = ''
accuracy = ''
quality = ''
confidence = ''
# Bounding Box attributes
northeast = []
northwest = []
southeast = []
southwest = []
bbox = {}
# Essential attributes for Street Address
address = ''
housenumber = ''
street = ''
road = ''
city = ''
state = ''
country = ''
postal = ''
def __repr__(self):
if self.address:
return u'<[{0}] {1} - {2} [{3}]>'.format(
self.status,
self.provider.title(),
self.method.title(),
six.text_type(self.address)
)
else:
return u'<[{0}] {1} - {2}>'.format(
self.status,
self.provider.title(),
self.method.title()
)
@staticmethod
def rate_limited_get(url, **kwargs):
return requests.get(url, **kwargs)
def _get_api_key(self, base_key, **kwargs):
key = kwargs.get('key')
# Retrieves API Key from method argument first
if key:
return key
# Retrieves API Key from Environment variables
elif base_key:
return base_key
raise ValueError('Provide API Key')
def _connect(self, **kwargs):
self.status_code = 'Unknown'
self.timeout = kwargs.get('timeout', 5.0)
self.proxies = kwargs.get('proxies', '')
try:
r = self.rate_limited_get(
self.url,
params=self.params,
headers=self.headers,
timeout=self.timeout,
proxies=self.proxies
)
self.status_code = r.status_code
self.url = r.url
if r.content:
self.status_code = 200
except (KeyboardInterrupt, SystemExit):
raise
except requests.exceptions.SSLError:
self.status_code = 495
self.error = 'ERROR - SSLError'
# Open JSON content from Request connection
if self.status_code == 200:
try:
self.content = r.json()
except:
self.status_code = 400
self.error = 'ERROR - JSON Corrupted'
self.content = r.content
def _initialize(self, **kwargs):
# Remove extra URL from kwargs
if 'url' in kwargs:
kwargs.pop('url')
self.json = {}
self.parse = self.tree()
self.content = None
self.encoding = kwargs.get('encoding', 'utf-8')
self._connect(url=self.url, params=self.params, **kwargs)
###
try:
for result in self.next(): # Convert to iterator in each of the search tools
self._build_tree(result)
self._exceptions()
self._catch_errors()
self._json()
except:
self._build_tree(self.content)
self._exceptions()
self._catch_errors()
self._json()
###
def _json(self):
self.fieldnames = []
for key in dir(self):
if not key.startswith('_') and key not in self._exclude:
self.fieldnames.append(key)
value = getattr(self, key)
if value:
self.json[key] = value
# Add OK attribute even if value is "False"
self.json['ok'] = self.ok
def debug(self):
print(json.dumps(self.parse, indent=4))
print(json.dumps(self.json, indent=4))
print('')
print('OSM Quality')
print('-----------')
count = 0
for key in self.osm:
if 'addr:' in key:
if self.json.get(key.replace('addr:', '')):
print('- [x] {0}'.format(key))
count += 1
else:
print('- [ ] {0}'.format(key))
print('({0}/{1})'.format(count, len(self.osm) - 2))
print('')
print('Fieldnames')
print('----------')
count = 0
for fieldname in self.fieldnames:
if self.json.get(fieldname):
print('- [x] {0}'.format(fieldname))
count += 1
else:
print('- [ ] {0}'.format(fieldname))
print('({0}/{1})'.format(count, len(self.fieldnames)))
print('')
print('URL')
print('---')
print(self.url)
def _exceptions(self):
pass
def _catch_errors(self):
pass
def tree(self):
return defaultdict(self.tree)
def _build_tree(self, content, last=''):
if content:
if isinstance(content, dict):
for key, value in content.items():
# Rebuild the tree if value is a dictionary
if isinstance(value, dict):
self._build_tree(value, last=key)
else:
if last:
self.parse[last][key] = value
else:
self.parse[key] = value
@property
def status(self):
if self.ok:
return 'OK'
elif self.error:
return self.error
if self.status_code == 200:
if not self.address:
return 'ERROR - No results found'
elif not (self.lng and self.lat):
return 'ERROR - No Geometry'
return 'ERROR - Unhandled Exception'
def _get_bbox(self, south, west, north, east):
if all([south, east, north, west]):
# South Latitude, West Longitude, North Latitude, East Longitude
self.south = float(south)
self.west = float(west)
self.north = float(north)
self.east = float(east)
# Bounding Box Corners
self.northeast = [self.north, self.east]
self.northwest = [self.north, self.west]
self.southwest = [self.south, self.west]
self.southeast = [self.south, self.east]
# GeoJSON bbox
self.westsouth = [self.west, self.south]
self.eastnorth = [self.east, self.north]
return dict(northeast=self.northeast, southwest=self.southwest)
return {}
@property
def confidence(self):
if self.bbox:
# Units are measured in Kilometers
distance = Distance(self.northeast, self.southwest, units='km')
for score, maximum in [(10, 0.25),
(9, 0.5),
(8, 1),
(7, 5),
(6, 7.5),
(5, 10),
(4, 15),
(3, 20),
(2, 25)]:
if distance < maximum:
return score
if distance >= 25:
return 1
# Cannot determine score
return 0
@property
def ok(self):
return bool(self.lng and self.lat)
@property
def geometry(self):
if self.ok:
return {
'type': 'Point',
'coordinates': [self.x, self.y]}
return {}
@property
def osm(self):
osm = dict()
if self.ok:
osm['x'] = self.x
osm['y'] = self.y
if self.housenumber:
osm['addr:housenumber'] = self.housenumber
if self.road:
osm['addr:street'] = self.road
if self.city:
osm['addr:city'] = self.city
if self.state:
osm['addr:state'] = self.state
if self.country:
osm['addr:country'] = self.country
if self.postal:
osm['addr:postal'] = self.postal
if hasattr(self, 'population'):
if self.population:
osm['population'] = self.population
return osm
@property
def geojson(self):
feature = {
'type': 'Feature',
'properties': self.json,
}
if self.bbox:
feature['bbox'] = [self.west, self.south, self.east, self.north]
feature['properties']['bbox'] = feature['bbox']
if self.geometry:
feature['geometry'] = self.geometry
return feature
@property
def wkt(self):
if self.ok:
return 'POINT({x} {y})'.format(x=self.x, y=self.y)
return ''
@property
def xy(self):
if self.ok:
return [self.lng, self.lat]
return []
@property
def latlng(self):
if self.ok:
return [self.lat, self.lng]
return []
@property
def y(self):
return self.lat
@property
def x(self):
return self.lng
@property
def locality(self):
return self.city
@property
def province(self):
return self.state
@property
def street_number(self):
return self.housenumber
@property
def road(self):
return self.street
@property
def route(self):
return self.street
PK fIO; geocoder/tamu.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import tamu_key
class Tamu(Base):
"""
TAMU Geocoding Services
=======================
Params
------
:param location: The street address of the location you want geocoded.
:param city: The city of the location to geocode.
:param state: The state of the location to geocode.
:param zipcode: The zipcode of the location to geocode.
:param key: The API key (use API key "demo" for testing).
API Reference
-------------
https://geoservices.tamu.edu/Services/Geocode/WebService
"""
provider = 'tamu'
method = 'geocode'
def __init__(self, location, censusYears=('1990', '2000', '2010'), **kwargs):
# city, state, zip
city = kwargs.get('city', '')
state = kwargs.get('state', '')
zipcode = kwargs.get('zipcode', '')
if not bool(city and state and zipcode):
raise ValueError("Provide city, state and zipcode")
self.location = location
self.key = self._get_api_key(tamu_key, **kwargs)
self.url = 'https://geoservices.tamu.edu/Services/Geocode/WebService' \
'/GeocoderWebServiceHttpNonParsed_V04_01.aspx'
self.params = {
'streetAddress': location,
'city': city,
'state': state,
'zip': zipcode,
'apikey': self.key,
'format': 'json',
'census': 'true',
'censusYear': '|'.join(censusYears),
'notStore': 'false',
'verbose': 'true',
'version': '4.01'
}
self._initialize(**kwargs)
def _catch_errors(self):
exception_occured = self.parse.get('ExceptionOccured')
status_code = self.parse.get('QueryStatusCodeValue')
exception = self.parse.get('Exception')
if (exception_occured == 'True' or status_code != '200' or exception):
self.error = exception
if status_code == '401' or status_code == '470':
self.error = u'Tamu returned status_code {0}. Is API key {1} valid?'.format(status_code, self.key)
raise Exception(self.error)
def _exceptions(self):
# Build initial Tree with results
if self.parse['OutputGeocodes']:
self._build_tree(self.parse.get('OutputGeocodes')[0])
self._build_tree(self.parse.get('OutputGeocode'))
self._build_tree(self.parse.get('ReferenceFeature'))
if self.parse['CensusValues']:
self._build_tree(self.parse.get('CensusValues')[0]['CensusValue1'])
@property
def lat(self):
lat = self.parse.get('Latitude')
if lat:
return float(lat)
@property
def lng(self):
lng = self.parse.get('Longitude')
if lng:
return float(lng)
@property
def quality(self):
return self.parse.get('MatchedLocationType')
@property
def accuracy(self):
return self.parse.get('FeatureMatchingGeographyType')
@property
def confidence(self):
return self.parse.get('MatchScore')
@property
def housenumber(self):
return self.parse.get('Number')
@property
def street(self):
name = self.parse.get('Name', '')
suffix = self.parse.get('Suffix', '')
return ' '.join([name, suffix]).strip()
@property
def address(self):
return ' '.join([
self.parse.get('Number', ''),
self.parse.get('Name', ''),
self.parse.get('Suffix', ''),
self.parse.get('City', ''),
self.parse.get('State', ''),
self.parse.get('Zip', '')])
@property
def city(self):
return self.parse.get('City')
@property
def state(self):
return self.parse.get('State')
@property
def postal(self):
return self.parse.get('Zip')
@property
def census_tract(self):
return self.parse.get('CensusTract')
@property
def census_block(self):
return self.parse.get('CensusBlock')
@property
def census_msa_fips(self):
return self.parse.get('CensusMsaFips')
@property
def census_mcd_fips(self):
return self.parse.get('CensusMcdFips')
@property
def census_metdiv_fips(self):
return self.parse.get('CensusMetDivFips')
@property
def census_place_fips(self):
return self.parse.get('CensusPlaceFips')
@property
def census_cbsa_fips(self):
return self.parse.get('CensusCbsaFips')
@property
def census_state_fips(self):
return self.parse.get('CensusStateFips')
@property
def census_county_fips(self):
return self.parse.get('CensusCountyFips')
@property
def census_year(self):
return self.parse.get('CensusYear')
if __name__ == '__main__':
g = Tamu(
'595 Market Street',
city='San Francisco',
state='CA',
zipcode='94105')
g.debug()
PK \ICre e geocoder/cli.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import click
import json
import geocoder
import os
import fileinput
from geocoder.api import options
providers = sorted(options.keys())
methods = ['geocode', 'reverse', 'elevation', 'timezone']
outputs = ['json', 'osm', 'geojson', 'wkt']
units = ['kilometers', 'miles', 'feet', 'meters']
@click.command()
@click.argument('location', nargs=-1)
@click.option('--provider', '-p', default='osm', type=click.Choice(providers))
@click.option('--method', '-m', default='geocode', type=click.Choice(methods))
@click.option('--output', '-o', default='json', type=click.Choice(outputs))
@click.option('--units', '-u', default='kilometers', type=click.Choice(units))
@click.option('--timeout', '-t', default=5.0)
@click.option('--distance', is_flag=True)
@click.option('--language', default='')
@click.option('--url', default='')
@click.option('--proxies')
@click.option('--key')
# following are for Tamu provider
@click.option('--city', '-c', default='')
@click.option('--state', '-s', default='')
@click.option('--zipcode', '-z', default='')
def cli(location, **kwargs):
"Geocode an arbitrary number of strings from Command Line."
locations = []
# Read Standard Input
# $ cat foo.txt | geocode
try:
for line in fileinput.input():
locations.append(line.strip())
except:
pass
# Read multiple files & user input location
for item in location:
if os.path.exists(item):
with open(item, 'rb') as f:
locations += f.read().splitlines()
else:
locations.append(item)
# Distance calcuation
if kwargs['distance']:
d = geocoder.distance(locations, **kwargs)
click.echo(d)
return
# Geocode results from user input
for location in locations:
g = geocoder.get(location.strip(), **kwargs)
try:
click.echo(json.dumps(g.__getattribute__(kwargs['output'])))
except IOError:
# When invalid command is entered a broken pipe error occurs
return
if __name__ == '__main__':
cli()
PK WHo\/ geocoder/yandex.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
class Yandex(Base):
"""
Yandex
======
Yandex (Russian: Яндекс) is a Russian Internet company
which operates the largest search engine in Russia with
about 60% market share in that country.
The Yandex home page has been rated as the most popular website in Russia.
Params
------
:param location: Your search location you want geocoded.
:param lang: Chose the following language:
> ru-RU — Russian (by default)
> uk-UA — Ukrainian
> be-BY — Belarusian
> en-US — American English
> en-BR — British English
> tr-TR — Turkish (only for maps of Turkey)
:param kind: Type of toponym (only for reverse geocoding):
> house - house or building
> street - street
> metro - subway station
> district - city district
> locality - locality (city, town, village, etc.)
References
----------
API Reference: http://api.yandex.com/maps/doc/geocoder/
desc/concepts/input_params.xml
"""
provider = 'yandex'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'http://geocode-maps.yandex.ru/1.x/'
self.location = location
self.params = {
'geocode': location,
'lang': kwargs.get('lang', 'en-US'),
'kind': kwargs.get('kind', ''),
'format': 'json',
'results': 1,
}
self._initialize(**kwargs)
def _exceptions(self):
# Build intial Tree with results
feature = self.parse['GeoObjectCollection']['featureMember']
for item in feature:
self._build_tree(item['GeoObject'])
@property
def address(self):
return self.parse['GeocoderMetaData'].get('text')
@property
def lat(self):
pos = self.parse['Point'].get('pos')
if pos:
return pos.split(' ')[1]
@property
def lng(self):
pos = self.parse['Point'].get('pos')
if pos:
return pos.split(' ')[0]
@property
def bbox(self):
if self.parse['Envelope']:
east, north = self.parse['Envelope'].get('upperCorner').split(' ')
west, south = self.parse['Envelope'].get('lowerCorner').split(' ')
try:
return self._get_bbox(float(south),
float(west),
float(north),
float(east))
except:
pass
@property
def quality(self):
return self.parse['GeocoderMetaData'].get('kind')
@property
def accuracy(self):
return self.parse['GeocoderMetaData'].get('precision')
@property
def housenumber(self):
return self.parse['Premise'].get('PremiseNumber')
@property
def street(self):
return self.parse['Thoroughfare'].get('ThoroughfareName')
@property
def city(self):
return self.parse['Locality'].get('LocalityName')
@property
def county(self):
return self.parse['SubAdministrativeArea'].get('SubAdministrative'
'AreaName')
@property
def state(self):
return self.parse['AdministrativeArea'].get('AdministrativeAreaName')
@property
def country(self):
return self.parse['Country'].get('CountryName')
@property
def country_code(self):
return self.parse['Country'].get('CountryNameCode')
@property
def SubAdministrativeArea(self):
return self.parse['SubAdministrativeArea'].get('SubAdministrativeAreaName')
@property
def Premise(self):
return self.parse.get('Premise')
@property
def AdministrativeArea(self):
return self.parse['AdministrativeArea'].get('AdministrativeAreaName')
@property
def Locality(self):
return self.parse['Locality']
@property
def Thoroughfare(self):
return self.parse['Thoroughfare'].get('ThoroughfareName')
@property
def description(self):
return self.parse['description']
if __name__ == '__main__':
g = Yandex('1552 Payette dr., Ottawa')
g.debug()
PK ,H0)L9 9 geocoder/api.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.osm import Osm
from geocoder.w3w import W3W
from geocoder.bing import Bing
from geocoder.here import Here
from geocoder.tamu import Tamu
from geocoder.tgos import Tgos
from geocoder.yahoo import Yahoo
from geocoder.baidu import Baidu
from geocoder.tomtom import Tomtom
from geocoder.arcgis import Arcgis
from geocoder.ottawa import Ottawa
from geocoder.yandex import Yandex
from geocoder.mapbox import Mapbox
from geocoder.mapzen import Mapzen
from geocoder.ipinfo import Ipinfo
from geocoder.komoot import Komoot
from geocoder.maxmind import Maxmind
from geocoder.location import Location
from geocoder.opencage import OpenCage
from geocoder.geonames import Geonames
from geocoder.mapquest import Mapquest
from geocoder.distance import Distance
from geocoder.geolytica import Geolytica
from geocoder.freegeoip import FreeGeoIP
from geocoder.canadapost import Canadapost
from geocoder.geocodefarm import GeocodeFarm
from geocoder.w3w_reverse import W3WReverse
from geocoder.osm_reverse import OsmReverse
from geocoder.here_reverse import HereReverse
from geocoder.bing_reverse import BingReverse
from geocoder.arcgis_reverse import ArcgisReverse
from geocoder.mapzen_reverse import MapzenReverse
from geocoder.komoot_reverse import KomootReverse
from geocoder.mapbox_reverse import MapboxReverse
from geocoder.yandex_reverse import YandexReverse
from geocoder.mapquest_reverse import MapquestReverse
from geocoder.opencage_reverse import OpenCageReverse
from geocoder.geocodefarm_reverse import GeocodeFarmReverse
# Google Services
from geocoder.google import Google
from geocoder.google_timezone import Timezone
from geocoder.google_reverse import GoogleReverse
from geocoder.google_elevation import Elevation
options = {
'osm': {
'geocode': Osm,
'reverse': OsmReverse,
},
'tgos': {
'geocode': Tgos
},
'here': {
'geocode': Here,
'reverse': HereReverse,
},
'baidu': {'geocode': Baidu},
'yahoo': {'geocode': Yahoo},
'tomtom': {'geocode': Tomtom},
'arcgis': {
'geocode': Arcgis,
'reverse': ArcgisReverse
},
'ottawa': {'geocode': Ottawa},
'mapbox': {
'geocode': Mapbox,
'reverse': MapboxReverse,
},
'maxmind': {'geocode': Maxmind},
'ipinfo': {'geocode': Ipinfo},
'geonames': {'geocode': Geonames},
'freegeoip': {'geocode': FreeGeoIP},
'w3w': {
'geocode': W3W,
'reverse': W3WReverse,
},
'yandex': {
'geocode': Yandex,
'reverse': YandexReverse
},
'mapquest': {
'geocode': Mapquest,
'reverse': MapquestReverse,
},
'geolytica': {'geocode': Geolytica},
'canadapost': {'geocode': Canadapost},
'opencage': {
'geocode': OpenCage,
'reverse': OpenCageReverse,
},
'bing': {
'geocode': Bing,
'reverse': BingReverse,
},
'google': {
'geocode': Google,
'reverse': GoogleReverse,
'timezone': Timezone,
'elevation': Elevation,
},
'mapzen': {
'geocode': Mapzen,
'reverse': MapzenReverse,
},
'komoot': {
'geocode': Komoot,
'reverse': KomootReverse,
},
'tamu': {
'geocode': Tamu
},
'geocodefarm': {
'geocode': GeocodeFarm,
'reverse': GeocodeFarmReverse,
},
}
def get(location, **kwargs):
"""Get Geocode
:param ``location``: Your search location you want geocoded.
:param ``provider``: The geocoding engine you want to use.
:param ``method``: Define the method (geocode, method).
"""
provider = kwargs.get('provider', 'bing').lower().strip()
method = kwargs.get('method', 'geocode').lower().strip()
if isinstance(location, (list, dict)) and method == 'geocode':
raise ValueError("Location should be a string")
if provider not in options:
raise ValueError("Invalid provider")
else:
if method not in options[provider]:
raise ValueError("Invalid method")
return options[provider][method](location, **kwargs)
def distance(*args, **kwargs):
"""Distance tool measures the distance between two or multiple points.
:param location: (min 2x locations) Your search location you want geocoded.
:param units: (default=kilometers) Unit of measurement.
> kilometers
> miles
> feet
> meters
"""
return Distance(*args, **kwargs)
def location(location, **kwargs):
"""Parser for different location formats
"""
return Location(location, **kwargs)
def google(location, **kwargs):
"""Google Provider
:param location: Your search location you want geocoded.
:param method: (default=geocode) Use the following:
> geocode
> reverse
> batch
> timezone
> elevation
"""
return get(location, provider='google', **kwargs)
def mapbox(location, **kwargs):
"""Mapbox Provider
:param location: Your search location you want geocoded.
:param proximity: Search nearby [lat, lng]
:param method: (default=geocode) Use the following:
> geocode
> reverse
> batch
"""
return get(location, provider='mapbox', **kwargs)
def yandex(location, **kwargs):
"""Yandex Provider
:param location: Your search location you want geocoded.
:param lang: Chose the following language:
> ru-RU — Russian (by default)
> uk-UA — Ukrainian
> be-BY — Belarusian
> en-US — American English
> en-BR — British English
> tr-TR — Turkish (only for maps of Turkey)
:param kind: Type of toponym (only for reverse geocoding):
> house - house or building
> street - street
> metro - subway station
> district - city district
> locality - locality (city, town, village, etc.)
"""
return get(location, provider='yandex', **kwargs)
def w3w(location, **kwargs):
"""what3words Provider
:param location: Your search location you want geocoded.
:param key: W3W API key.
:param method: Chose a method (geocode, method)
"""
return get(location, provider='w3w', **kwargs)
def baidu(location, **kwargs):
"""Baidu Provider
:param location: Your search location you want geocoded.
:param key: Baidu API key.
:param referer: Baidu API referer website.
"""
return get(location, provider='baidu', **kwargs)
def komoot(location, **kwargs):
"""Ottawa Provider
:param location: Your search location you want geocoded.
"""
return get(location, provider='komoot', **kwargs)
def ottawa(location, **kwargs):
"""Ottawa Provider
:param location: Your search location you want geocoded.
"""
return get(location, provider='ottawa', **kwargs)
def elevation(location, **kwargs):
"""Elevation - Google Provider
:param location: Your search location you want to retrieve elevation data.
"""
return get(location, method='elevation', provider='google', **kwargs)
def timezone(location, **kwargs):
"""Timezone - Google Provider
:param location: Your search location you want to retrieve timezone data.
:param timestamp: Define your own specified time to calculate timezone.
"""
return get(location, method='timezone', provider='google', **kwargs)
def reverse(location, provider="google", **kwargs):
"""Reverse Geocoding
:param location: Your search location you want to reverse geocode.
:param key: (optional) use your own API Key from Bing.
:param provider: (default=google) Use the following:
> google
> bing
"""
return get(location, method='reverse', provider=provider, **kwargs)
def bing(location, **kwargs):
"""Bing Provider
:param location: Your search location you want geocoded.
:param key: (optional) use your own API Key from Bing.
:param method: (default=geocode) Use the following:
> geocode
> reverse
"""
return get(location, provider='bing', **kwargs)
def yahoo(location, **kwargs):
"""Yahoo Provider
:param ``location``: Your search location you want geocoded.
"""
return get(location, provider='yahoo', **kwargs)
def geolytica(location, **kwargs):
"""Geolytica (Geocoder.ca) Provider
:param location: Your search location you want geocoded.
"""
return get(location, provider='geolytica', **kwargs)
def opencage(location, **kwargs):
"""Opencage Provider
:param ``location``: Your search location you want geocoded.
:param ``key``: (optional) use your own API Key from OpenCage.
"""
return get(location, provider='opencage', **kwargs)
def arcgis(location, **kwargs):
"""ArcGIS Provider
:param ``location``: Your search location you want geocoded.
"""
return get(location, provider='arcgis', **kwargs)
def here(location, **kwargs):
"""HERE Provider
:param location: Your search location you want geocoded.
:param app_code: (optional) use your own Application Code from HERE.
:param app_id: (optional) use your own Application ID from HERE.
:param method: (default=geocode) Use the following:
> geocode
> reverse
"""
return get(location, provider='here', **kwargs)
def nokia(location, **kwargs):
"""HERE Provider
:param location: Your search location you want geocoded.
:param app_code: (optional) use your own Application Code from HERE.
:param app_id: (optional) use your own Application ID from HERE.
:param method: (default=geocode) Use the following:
> geocode
> reverse
"""
return get(location, provider='here', **kwargs)
def tomtom(location, **kwargs):
"""TomTom Provider
:param location: Your search location you want geocoded.
:param key: (optional) use your own API Key from TomTom.
"""
return get(location, provider='tomtom', **kwargs)
def mapquest(location, **kwargs):
"""MapQuest Provider
:param location: Your search location you want geocoded.
:param key: (optional) use your own API Key from MapQuest.
:param method: (default=geocode) Use the following:
> geocode
> reverse
"""
return get(location, provider='mapquest', **kwargs)
def osm(location, **kwargs):
"""OSM Provider
:param location: Your search location you want geocoded.
:param url: Custom OSM Server URL location
(ex: http://nominatim.openstreetmap.org/search)
"""
return get(location, provider='osm', **kwargs)
def maxmind(location='me', **kwargs):
"""MaxMind Provider
:param location: Your search IP Address you want geocoded.
:param location: (optional) if left blank will return your
current IP address's location.
"""
return get(location, provider='maxmind', **kwargs)
def ipinfo(location='', **kwargs):
"""IP Info.io Provider
:param location: Your search IP Address you want geocoded.
:param location: (optional) if left blank will return your
current IP address's location.
"""
return get(location, provider='ipinfo', **kwargs)
def freegeoip(location, **kwargs):
"""FreeGeoIP Provider
:param location: Your search IP Address you want geocoded.
:param location: (optional) if left blank will return your
current IP address's location.
"""
return get(location, provider='freegeoip', **kwargs)
def ip(location, **kwargs):
"""IP Address lookup
:param location: Your search IP Address you want geocoded.
:param location: (optional) if left blank will return your
current IP address's location.
"""
return get(location, provider='ipinfo', **kwargs)
def canadapost(location, **kwargs):
"""CanadaPost Provider
:param ``location``: Your search location you want geocoded.
:param ``key``: (optional) API Key from CanadaPost Address Complete.
:param ``language``: (default=en) Output language preference.
:param ``country``: (default=ca) Geofenced query by country.
"""
return get(location, provider='canadapost', **kwargs)
def postal(location, **kwargs):
"""CanadaPost Provider
:param ``location``: Your search location you want geocoded.
:param ``key``: (optional) use your own API Key from
CanadaPost Address Complete.
"""
return get(location, provider='canadapost', **kwargs)
def geonames(location, **kwargs):
"""GeoNames Provider
:param ``location``: Your search location you want geocoded.
:param ``username``: (required) needs to be passed with each request.
"""
return get(location, provider='geonames', **kwargs)
def mapzen(location, **kwargs):
"""Mapzen Provider
:param ``location``: Your search location you want geocoded.
"""
return get(location, provider='mapzen', **kwargs)
def tamu(location, **kwargs):
"""TAMU Provider
Params
------
:param location: The street address of the location you want geocoded.
:param city: The city of the location to geocode.
:param state: The state of the location to geocode.
:param zipcode: The zipcode of the location to geocode.
:param key: The API key (use API key "demo" for testing).
API Reference
-------------
https://geoservices.tamu.edu/Services/Geocode/WebService
"""
return get(location, provider='tamu', **kwargs)
def geocodefarm(location, **kwargs):
"""GeocodeFarm Provider
Params
------
:param location: The string to search for. Usually a street address.
:param key: (optional) API Key. Only Required for Paid Users.
:param lang: (optional) 2 digit lanuage code to return results in. Currently only "en"(English) or "de"(German) supported.
:param country: (optional) The country to return results in. Used for biasing purposes and may not fully filter results to this specific country.
API Reference
-------------
https://geocode.farm/geocoding/free-api-documentation/
"""
return get(location, provider='geocodefarm', **kwargs)
def tgos(location, **kwargs):
"""TGOS Provider
:param location: Your search location you want geocoded.
:param language: (default=taiwan) Use the following:
> taiwan
> english
> chinese
:param method: (default=geocode) Use the following:
> geocode
API Reference
-------------
http://api.tgos.nat.gov.tw/TGOS_MAP_API/Web/Default.aspx
"""
return get(location, provider='tgos', **kwargs)
PK fIc geocoder/freegeoip.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import requests
import ratelim
from geocoder.base import Base
class FreeGeoIP(Base):
"""
FreeGeoIP.net
=============
freegeoip.net provides a public HTTP API for software developers to
search the geolocation of IP addresses. It uses a database of IP addresses
that are associated to cities along with other relevant information like
time zone, latitude and longitude.
You're allowed up to 10,000 queries per hour by default. Once this
limit is reached, all of your requests will result in HTTP 403,
forbidden, until your quota is cleared.
API Reference
-------------
http://freegeoip.net/
"""
provider = 'freegeoip'
method = 'geocode'
def __init__(self, location='me', **kwargs):
self.location = location
self.url = kwargs.get('url', 'https://telize.j3ss.co/geoip/') + self.location
self._initialize(**kwargs)
@staticmethod
@ratelim.greedy(10000, 60 * 60)
def rate_limited_get(*args, **kwargs):
return requests.get(*args, **kwargs)
@property
def lat(self):
return self.parse.get('latitude')
@property
def lng(self):
return self.parse.get('longitude')
@property
def address(self):
if self.city:
return u'{0}, {1} {2}'.format(self.city, self.state, self.country)
elif self.state:
return u'{0}, {1}'.format(self.state, self.country)
elif self.country:
return u'{0}'.format(self.country)
return u''
@property
def postal(self):
zip_code = self.parse.get('zip_code')
postal_code = self.parse.get('postal_code')
if zip_code:
return zip_code
if postal_code:
return postal_code
@property
def city(self):
return self.parse.get('city')
@property
def state(self):
return self.parse.get('region')
@property
def region_code(self):
return self.parse.get('region_code')
@property
def country(self):
return self.parse.get('country_name')
@property
def country_code3(self):
return self.parse.get('country_code3')
@property
def continent(self):
return self.parse.get('continent')
@property
def timezone(self):
return self.parse.get('timezone')
@property
def area_code(self):
return self.parse.get('area_code')
@property
def dma_code(self):
return self.parse.get('dma_code')
@property
def offset(self):
return self.parse.get('offset')
@property
def organization(self):
return self.parse.get('organization')
@property
def offset(self):
return self.parse.get('offset')
@property
def ip(self):
return self.parse.get('ip')
@property
def time_zone(self):
return self.parse.get('time_zone')
if __name__ == '__main__':
g = FreeGeoIP('99.240.181.199')
g.debug()
PK ,H\P geocoder/komoot_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.komoot import Komoot
from geocoder.location import Location
class KomootReverse(Komoot):
"""
Komoot REST API
=======================
API Reference
-------------
http://photon.komoot.de
"""
provider = 'komoot'
method = 'reverse'
def __init__(self, location, **kwargs):
self.url = 'https://photon.komoot.de/reverse'
self.location = location
location = Location(location)
self.params = {
'lat': location.lat,
'lon': location.lng,
}
self._initialize(**kwargs)
def _exceptions(self):
if self.parse['features']:
self._build_tree(self.parse['features'][0])
@property
def ok(self):
return bool(self.address)
if __name__ == '__main__':
g = KomootReverse("45.4 -75.7")
g.debug()
PK ,Hd) ) geocoder/geonames.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import geonames_username
class Geonames(Base):
"""
GeoNames REST Web Services
==========================
GeoNames is mainly using REST webservices. Find nearby postal codes / reverse geocoding
This service comes in two flavors.You can either pass the lat/long or a postalcode/placename.
API Reference
-------------
http://www.geonames.org/export/web-services.html
"""
provider = 'geonames'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'http://api.geonames.org/searchJSON'
self.location = location
username = kwargs.get('username', geonames_username)
if not username:
raise ValueError('Provide username')
self.params = {
'q': location,
'fuzzy': 0.8,
'username': username,
'maxRows': 1,
}
self._initialize(**kwargs)
def _catch_errors(self):
status = self.parse['status'].get('message')
value = self.parse['status'].get('value')
count = self.parse['totalResultsCount']
if status:
value_lookup = {10: 'Invalid credentials'}
self.error = value_lookup[value]
if count == 0:
self.error = 'No Results Found'
def _exceptions(self):
# Build intial Tree with results
if self.parse['geonames']:
self._build_tree(self.parse['geonames'][0])
@property
def lat(self):
return self.parse.get('lat')
@property
def lng(self):
return self.parse.get('lng')
@property
def address(self):
return self.parse.get('name')
@property
def state(self):
return self.parse.get('adminName1')
@property
def country(self):
return self.parse.get('countryName')
@property
def description(self):
return self.parse.get('fcodeName')
@property
def code(self):
return self.parse.get('fcode')
@property
def geonames_id(self):
return self.parse.get('geonameId')
@property
def population(self):
return self.parse.get('population')
if __name__ == '__main__':
g = Geonames('Ottawa, Ontario')
g.debug()
PK 6|HT? geocoder/here_reverse.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.keys import here_app_id, here_app_code
from geocoder.location import Location
from geocoder.here import Here
class HereReverse(Here, Base):
"""
HERE Geocoding REST API
=======================
Send a request to the geocode endpoint to find an address
using a combination of country, state, county, city,
postal code, district, street and house number.
API Reference
-------------
https://developer.here.com/rest-apis/documentation/geocoder
"""
provider = 'here'
method = 'reverse'
def __init__(self, location, **kwargs):
self.url = 'http://reverse.geocoder.cit.api.here.com/6.2/reversegeocode.json'
self.location = str(Location(location))
# HERE Credentials
app_id = kwargs.get('app_id', here_app_id)
app_code = kwargs.get('app_code', here_app_code)
if not bool(app_id and app_code):
raise ValueError("Provide app_id & app_code")
# URL Params
self.params = {
'prox': self.location,
'app_id': app_id,
'app_code': app_code,
'mode': 'retrieveAddresses',
'language': kwargs.get('language ', ''),
'gen': 8,
}
self._initialize(**kwargs)
@property
def ok(self):
return bool(self.address)
if __name__ == '__main__':
g = HereReverse([45.4049053, -75.7077965])
g.debug()
PK fIl}E E geocoder/ipinfo.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
from geocoder.base import Base
from geocoder.location import Location
class Ipinfo(Base):
"""
API Reference
-------------
https://ipinfo.io
"""
provider = 'ipinfo'
method = 'geocode'
def __init__(self, location='', **kwargs):
self.location = location
if location.lower() == 'me':
self.location = ''
self.url = 'http://ipinfo.io/{0}/json'.format(self.location)
self._initialize(**kwargs)
def _catch_errors(self):
content = self.content
if content and self.status_code == 400:
self.error = content
@property
def lat(self):
loc = self.parse.get('loc')
if loc:
return Location(loc).lat
@property
def lng(self):
loc = self.parse.get('loc')
if loc:
return Location(loc).lng
@property
def address(self):
if self.city:
return u'{0}, {1}, {2}'.format(self.city, self.state, self.country)
elif self.state:
return u'{0}, {1}'.format(self.state, self.country)
elif self.country:
return u'{0}'.format(self.country)
else:
return u''
@property
def postal(self):
return self.parse.get('postal')
@property
def city(self):
return self.parse.get('city')
@property
def state(self):
return self.parse.get('region')
@property
def country(self):
return self.parse.get('country')
@property
def hostname(self):
return self.parse.get('hostname')
@property
def ip(self):
return self.parse.get('ip')
@property
def org(self):
return self.parse.get('org')
if __name__ == '__main__':
g = Ipinfo('8.8.8.8')
g.debug()
PK ,H geocoder/here.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import six
from geocoder.base import Base
from geocoder.keys import here_app_id, here_app_code
class Here(Base):
"""
HERE Geocoding REST API
=======================
Send a request to the geocode endpoint to find an address
using a combination of country, state, county, city,
postal code, district, street and house number.
API Reference
-------------
https://developer.here.com/rest-apis/documentation/geocoder
"""
provider = 'here'
method = 'geocode'
qualified_address = ['city', 'district', 'postal', 'state', 'country']
def __init__(self, location, **kwargs):
self.url = kwargs.get('url', 'http://geocoder.cit.api.here.com/6.2/geocode.json')
self.location = location
# HERE Credentials
app_id = kwargs.get('app_id', here_app_id)
app_code = kwargs.get('app_code', here_app_code)
if not bool(app_id and app_code):
raise ValueError("Provide app_id & app_code")
# URL Params
self.params = {
'searchtext': location,
'app_id': app_id,
'app_code': app_code,
'gen': 9,
'language': kwargs.get('language', 'en')
}
for value in Here.qualified_address:
if kwargs.get(value) is not None:
self.params[value] = kwargs.get(value)
self._initialize(**kwargs)
def _exceptions(self):
# Build intial Tree with results
view = self.parse['Response']['View']
if view:
result = view[0]['Result']
if result:
self._build_tree(result[0])
for item in self.parse['Location']['Address']['AdditionalData']:
self.parse[item['key']] = item['value']
def _catch_errors(self):
status = self.parse.get('type')
if not status == 'OK':
self.error = status
@property
def lat(self):
return self.parse['DisplayPosition'].get('Latitude')
@property
def lng(self):
return self.parse['DisplayPosition'].get('Longitude')
@property
def address(self):
return self.parse['Address'].get('Label')
@property
def postal(self):
return self.parse['Address'].get('PostalCode')
@property
def housenumber(self):
return self.parse['Address'].get('HouseNumber')
@property
def street(self):
return self.parse['Address'].get('Street')
@property
def neighborhood(self):
return self.district
@property
def district(self):
return self.parse['Address'].get('District')
@property
def city(self):
return self.parse['Address'].get('City')
@property
def county(self):
return self.parse['Address'].get('County')
@property
def state(self):
return self.parse['Address'].get('State')
@property
def country(self):
return self.parse['Address'].get('Country')
@property
def quality(self):
return self.parse.get('MatchLevel')
@property
def accuracy(self):
return self.parse.get('MatchType')
@property
def bbox(self):
south = self.parse['BottomRight'].get('Latitude')
north = self.parse['TopLeft'].get('Latitude')
west = self.parse['TopLeft'].get('Longitude')
east = self.parse['BottomRight'].get('Longitude')
return self._get_bbox(south, west, north, east)
if __name__ == '__main__':
g = Here("New York City")
g.debug()
PK /I geocoder/keys.py#!/usr/bin/python
# coding: utf8
import os
bing_key = os.environ.get('BING_API_KEY')
tomtom_key = os.environ.get('TOMTOM_API_KEY')
here_app_id = os.environ.get('HERE_APP_ID')
here_app_code = os.environ.get('HERE_APP_CODE')
geonames_username = os.environ.get('GEONAMES_USERNAME')
canadapost_key = os.environ.get('CANADAPOST_API_KEY')
opencage_key = os.environ.get('OPENCAGE_API_KEY')
mapquest_key = os.environ.get('MAPQUEST_API_KEY')
baidu_key = os.environ.get('BAIDU_API_KEY')
w3w_key = os.environ.get('W3W_API_KEY')
mapbox_access_token = os.environ.get('MAPBOX_ACCESS_TOKEN')
google_key = os.environ.get('GOOGLE_API_KEY')
google_client = os.environ.get('GOOGLE_CLIENT')
google_client_secret = os.environ.get('GOOGLE_CLIENT_SECRET')
mapzen_key = os.environ.get('MAPZEN_API_KEY')
tamu_key = os.environ.get('TAMU_API_KEY')
geocodefarm_key = os.environ.get('GEOCODEFARM_API_KEY')
tgos_key = os.environ.get('TGOS_API_KEY')
PK ,HUh
h
geocoder/ottawa.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import re
from geocoder.base import Base
class Ottawa(Base):
"""
Ottawa ArcGIS REST Services
===========================
Geocoding is the process of assigning a location, usually in the form of
coordinate values (points), to an address by comparing the descriptive
location elements in the address to those present in the reference
material. Addresses come in many forms, ranging from the common address
format of a house number followed by the street name and succeeding
information to other location descriptions such as postal zone or census
tract. An address includes any type of information that distinguishes
a place.
API Reference
-------------
http://maps.ottawa.ca/ArcGIS/rest/services/
compositeLocator/GeocodeServer/findAddressCandidates
"""
provider = 'ottawa'
method = 'geocode'
def __init__(self, location, **kwargs):
self.url = 'http://maps.ottawa.ca/ArcGIS/rest/services/'
self.url += 'compositeLocator/GeocodeServer/findAddressCandidates'
self.location = location
self.params = {
'SingleLine': location.replace(', Ottawa, ON', ''),
'f': 'json',
'outSR': 4326,
}
self._initialize(**kwargs)
def _exceptions(self):
# Build intial Tree with results
if self.parse['candidates']:
self._build_tree(self.parse['candidates'][0])
@property
def lat(self):
return self.parse['location'].get('y')
@property
def lng(self):
return self.parse['location'].get('x')
@property
def postal(self):
if self.address:
expression = r'([ABCEGHJKLMNPRSTVXY]{1}\d{1}[A-Z]{1}( *\d{1}[A-Z]{1}\d{1})?)'
pattern = re.compile(expression)
match = pattern.search(self.address.upper())
if match:
return match.group(0)
@property
def housenumber(self):
if self.address:
expression = r'\d+'
pattern = re.compile(expression)
match = pattern.search(self.address)
if match:
return int(match.group(0))
@property
def city(self):
return 'Ottawa'
@property
def state(self):
return 'Ontario'
@property
def country(self):
return 'Canada'
@property
def address(self):
return self.parse.get('address')
@property
def accuracy(self):
return self.parse.get('score')
if __name__ == '__main__':
g = Ottawa('1552 Payette dr.')
g.debug()
PK fIa& geocoder/__init__.py#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
"""
Geocoder
~~~~~~~~
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.
Consistant JSON responses from various providers.
>>> g = geocoder.google('New York City')
>>> g.latlng
[40.7127837, -74.0059413]
>>> g.state
'New York'
>>> g.json
...
"""
__title__ = 'geocoder'
__author__ = 'Denis Carriere'
__author_email__ = 'carriere.denis@gmail.com'
__version__ = '1.17.5'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2013-2016 Denis Carriere'
# CORE
from geocoder.api import get, yahoo, bing, geonames, mapquest, google, mapbox # noqa
from geocoder.api import nokia, osm, tomtom, geolytica, arcgis, opencage # noqa
from geocoder.api import maxmind, ipinfo, freegeoip, ottawa, here, baidu, w3w # noqa
from geocoder.api import yandex, mapzen, komoot, tamu, geocodefarm, tgos # noqa
# EXTRAS
from geocoder.api import timezone, elevation, ip, canadapost, reverse, distance, location # noqa
# CLI
from geocoder.cli import cli # noqa
PK (fIƟD7 D7 ) geocoder-1.17.5.dist-info/DESCRIPTION.rstPython Geocoder
===============
|image0| |image1| |image2| |image3|
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.
.. code:: python
>>> 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.
.. code:: python
>>> import geocoder
>>> g = geocoder.google('Mountain View, CA')
>>> g.latlng
(37.3860517, -122.0838511)
Documentation
-------------
https://geocoder.readthedocs.org/
API Overview
------------
Many properties are available once the geocoder object is created.
Forward
~~~~~~~
.. code:: python
>>> import geocoder
>>> g = geocoder.google('Mountain View, CA')
>>> g.geojson
>>> g.json
>>> g.wkt
>>> g.osm
Reverse
~~~~~~~
.. code:: python
>>> g = geocoder.google([45.15, -75.14], method='reverse')
>>> g.city
>>> g.state
>>> g.state_long
>>> g.country
>>> g.country_long
House Addresses
~~~~~~~~~~~~~~~
.. code:: python
>>> g = geocoder.google("453 Booth Street, Ottawa ON")
>>> g.housenumber
>>> g.postal
>>> g.street
>>> g.street_long
IP Addresses
~~~~~~~~~~~~
.. code:: python
>>> g = geocoder.ip('199.7.157.0')
>>> g = geocoder.ip('me')
>>> g.latlng
>>> g.city
Bounding Box
~~~~~~~~~~~~
Accessing the JSON & GeoJSON attributes will be different
.. code:: python
>>> 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]
Command Line Interface
----------------------
.. code:: bash
$ geocode "Ottawa, ON" >> ottawa.geojson
$ geocode "Ottawa, ON" \
--provide google \
--out geojson \
--method geocode
Providers
---------
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| Provider | Optimal | Usage Policy |
+====================================================================================+===========+====================================================================================================+
| `ArcGIS `__ | World | |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `Baidu `__ | China | API key |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `Bing `__ | World | API key |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `CanadaPost `__ | Canada | API key |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `FreeGeoIP `__ | World | |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `Geocoder.ca `__ | CA & US | Rate Limit |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `GeocodeFarm `__ | World | `Policy `__ |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `GeoNames `__ | World | Username |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `GeoOttawa `__ | Ottawa | |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `Google `__ | World | Rate Limit, `Policy `__ |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `HERE `__ | World | API key |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `IPInfo `__ | World | |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `Mapbox `__ | World | API key |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `MapQuest `__ | World | API key |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
| `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 | |
+------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+
Installation
------------
PyPi Install
~~~~~~~~~~~~
To install Geocoder, simply:
.. code:: bash
$ pip install geocoder
GitHub Install
~~~~~~~~~~~~~~
Installing the latest version from Github:
.. code:: bash
$ git clone https://github.com/DenisCarriere/geocoder
$ cd geocoder
$ python setup.py install
Twitter
-------
Speak up on Twitter [@DenisCarriere](https://twitter.com/DenisCarriere)
and tell me how you use this Python Geocoder. New updates will be pushed
to Twitter Hashtags
`#python `__.
Feedback
--------
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 `__.
.. |image0| image:: https://img.shields.io/pypi/v/geocoder.svg
:target: https://pypi.python.org/pypi/geocoder
.. |image1| image:: https://img.shields.io/pypi/dm/geocoder.svg
:target: https://pypi.python.org/pypi/geocoder
.. |image2| image:: https://travis-ci.org/DenisCarriere/geocoder.svg?branch=master
:target: https://travis-ci.org/DenisCarriere/geocoder
.. |image3| image:: https://coveralls.io/repos/DenisCarriere/geocoder/badge.svg?branch=master&service=github
:target: https://coveralls.io/github/DenisCarriere/geocoder?branch=master
PK 'fI'n@ @ * geocoder-1.17.5.dist-info/entry_points.txt
[console_scripts]
geocode=geocoder.cli:cli
PK (fIF ' geocoder-1.17.5.dist-info/metadata.json{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.1", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Topic :: Internet", "Topic :: Internet :: WWW/HTTP", "Topic :: Scientific/Engineering :: GIS", "Topic :: Software Development :: Libraries :: Python Modules"], "download_url": "https://github.com/DenisCarriere/geocoder", "extensions": {"python.commands": {"wrap_console": {"geocode": "geocoder.cli:cli"}}, "python.details": {"contacts": [{"email": "carriere.denis@gmail.com", "name": "Denis Carriere", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/DenisCarriere/geocoder"}}, "python.exports": {"console_scripts": {"geocode": "geocoder.cli:cli"}}}, "extras": [], "generator": "bdist_wheel (0.26.0)", "keywords": ["geocoder", "arcgis", "tomtom", "opencage", "google", "bing", "here"], "license": "The MIT License", "metadata_version": "2.0", "name": "geocoder", "run_requires": [{"requires": ["click", "ratelim", "requests", "six"]}], "summary": "Geocoder is a simple and consistent geocoding library.", "version": "1.17.5"}PK 'fIlx ' geocoder-1.17.5.dist-info/top_level.txtgeocoder
PK (fIndn n geocoder-1.17.5.dist-info/WHEELWheel-Version: 1.0
Generator: bdist_wheel (0.26.0)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any
PK (fIYv<<