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,H@Z Z 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 '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,HP" " 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 '{0}, {1}, {2}'.format(self.city, self.state, self.country) elif self.state: return '{0}, {1}'.format(self.state, self.country) elif self.country: return '{0}'.format(self.country) else: return '' @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,H}d 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 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('bounds ', ''), '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 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,HL5geocoder/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 = kwargs.get('key', canadapost_key) 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,Hgeocoder/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,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$DHHgeocoder/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,H^pGttgeocoder/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,HzB&} } 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ΠBBgeocoder/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,Hhhgeocoder/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,H)_|kgeocoder/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 '{0}, {1}'.format(self.lat, self.lng) return '' 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,Hq+bgeocoder/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]) @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,Hh]Fs 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 = '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 '{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,Hdgeocoder/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) key = kwargs.get('key', mapzen_key) if not key: raise ValueError('Mapzen requires a [key] as parameter.') 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': key } 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,Hiaageocoder/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 = 'http://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,Ha5U%U%geocoder/osm.py#!/usr/bin/python # coding: utf8 from __future__ import absolute_import import ratelim 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,Hط 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 = 'http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/reverseGeocode' self.location = location location = Location(location) self.params = { 'location': '{}, {}'.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,Hג 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('[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,Hgeocoder/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,Hgeocoder/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:oogeocoder/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,H!]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 = '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,HB:egeocoder/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 "<[{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,H^dv DDgeocoder/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 '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 '{0} {1}, {2}'.format(self.street_number, self.route, self.locality) elif self.route and self.route != 'un-known': return '{0}, {1}'.format(self.route, self.locality) else: return self.locality if __name__ == '__main__': g = Geolytica('1552 Payette dr., Ottawa') g.debug() PK,Hv  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 key = kwargs.get('key', mapzen_key) if not key: raise ValueError('Mapzen requires a [key] as parameter.') self.params = { 'text': location, 'api_key': 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('1552 Payette dr., Ottawa, ON', key='search-un1M9Hk') g.debug() PKnHcgeocoder/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 = '{}, {}'.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,Ha((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 "<[{0}] {1} - {2} [{3}]>".format( self.status, self.provider.title(), self.method.title(), six.text_type(self.address) ) else: return "<[{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', base_key) if not key: raise ValueError('Provide API Key') return 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' except: self.status_code = 404 self.error = 'ERROR - URL Connection' # 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): 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): # South Latitude, West Longitude, North Latitude, East Longitude self.south = south self.west = west self.north = north self.east = 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] if all([self.south, self.east, self.north, self.west]): 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,Hأrrgeocoder/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") # API key key = kwargs.get('key', tamu_key) if not key: raise ValueError("Provide key") self.key = key self.location = location self.url = 'https://geoservices.tamu.edu/Services/Geocode/WebService' \ '/GeocoderWebServiceHttpNonParsed_V04_01.aspx' self.params = { 'streetAddress': location, 'city': city, 'state': state, 'zip': zipcode, 'apikey': 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 = \ "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,HV==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('--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() PKWHo\/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() PKH! 44geocoder/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.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.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 # 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, }, '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 }, } 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) PK,H t} 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 '{0}, {1} {2}'.format(self.city, self.state, self.country) elif self.state: return '{0}, {1}'.format(self.state, self.country) else: return '{0}'.format(self.country) @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\Pgeocoder/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,Htgeocoder/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', '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,H?<AAgeocoder/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 '{0}, {1}, {2}'.format(self.city, self.state, self.country) elif self.state: return '{0}, {1}'.format(self.state, self.country) elif self.country: return '{0}'.format(self.country) else: return '' @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,Hgeocoder/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,H}77geocoder/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') 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() PKHOigeocoder/__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.12.0' __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, yandex, mapzen, komoot, tamu # noqa # EXTRAS from geocoder.api import timezone, elevation, ip, canadapost, reverse, distance, location # noqa # CLI from geocoder.cli import cli # noqa PKHJ$4$4)geocoder-1.12.0.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 | +------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+ | `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 | | +------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+ 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 PKH'n@@*geocoder-1.12.0.dist-info/entry_points.txt [console_scripts] geocode=geocoder.cli:cli PKH}'geocoder-1.12.0.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.12.0"}PKHlx 'geocoder-1.12.0.dist-info/top_level.txtgeocoder PKHndnngeocoder-1.12.0.dist-info/WHEELWheel-Version: 1.0 Generator: bdist_wheel (0.26.0) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any PKH%b99"geocoder-1.12.0.dist-info/METADATAMetadata-Version: 2.0 Name: geocoder Version: 1.12.0 Summary: Geocoder is a simple and consistent geocoding library. Home-page: https://github.com/DenisCarriere/geocoder Author: Denis Carriere Author-email: carriere.denis@gmail.com License: The MIT License Download-URL: https://github.com/DenisCarriere/geocoder Keywords: geocoder arcgis tomtom opencage google bing here Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: Intended Audience :: Science/Research Classifier: License :: OSI Approved :: Apache Software License Classifier: Natural Language :: English Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.1 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Topic :: Internet Classifier: Topic :: Internet :: WWW/HTTP Classifier: Topic :: Scientific/Engineering :: GIS Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Dist: click Requires-Dist: ratelim Requires-Dist: requests Requires-Dist: six Python 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 | +------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+ | `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 | | +------------------------------------------------------------------------------------+-----------+----------------------------------------------------------------------------------------------------+ 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 PKH8,, geocoder-1.12.0.dist-info/RECORDgeocoder/__init__.py,sha256=gw6Vj-aWDWd0t8yvojlnbIR3nj1eOtBmFcaCDYttrjo,1174 geocoder/api.py,sha256=3EI28jrrYPfT9ND0Fl6_7ILPxxMbMpqgEU8tPlfdj30,13338 geocoder/arcgis.py,sha256=s4Qmm4fUng7aW2kPMzc2S3vTXAKyCf00olfJ3ebbrGI,2145 geocoder/arcgis_reverse.py,sha256=LwaDW7SODtYKlmrLmbetD4-s3fwW90DWrN26vs-tXII,2487 geocoder/baidu.py,sha256=M-OiSoL6unaXoxY9t_rSAmy2yIjl55B1zcY8Uv6LhB0,1503 geocoder/base.py,sha256=vaBKuegkRq-cMKSxjFUvKbl56VrOUoJF6-KJC2thirE,10264 geocoder/bing.py,sha256=424l0n8Gu4jwckkN86ePyyjKhCE7joWuYZcQBBmsuQo,3453 geocoder/bing_reverse.py,sha256=vL3pAdIEJZADe5z8xGuwLLDIFqEbzVLTKkGdo8zFhJU,1256 geocoder/canadapost.py,sha256=6ImBhzN1WSrz35Dh1LCWhcqkZtVvwjc_MTKsCBoGHz8,5251 geocoder/cli.py,sha256=ghhq12mH2cl5Pav7WYjqYMpp0vSyko71EKJuepTXwyY,2109 geocoder/distance.py,sha256=mq5lnUB0kGd67Fk8W7_Pkrid0Ub8c2-4RHPq7v3D00o,2706 geocoder/freegeoip.py,sha256=9lAZpQHXBzHs__E26zYShZPhEx2-_LAbDLoju3OqcuU,3014 geocoder/geolytica.py,sha256=-afCpil3OJ8_KfFwZv_KCeMenZF_xqkVsX44mnM7jMU,1860 geocoder/geonames.py,sha256=d-UqAy7Jb-uSIDT-Pj00BGjr4UbqfhJvDUCuC5SKQ1s,2345 geocoder/google.py,sha256=3_8l_V3-l4bKXL_Tau5v7lZg1M83MxyaX2lg_7ZcUDY,8328 geocoder/google_elevation.py,sha256=QDprQQVEOaj6MRoXEjq6IMv15NtsY72AHo1rbGaOC1c,1896 geocoder/google_reverse.py,sha256=Q1PxHFGDwbJ0lvpwVTEWjrh1-Ps0CH3rlhSvNPyBLZU,1413 geocoder/google_timezone.py,sha256=45txAzkJKoydhXKlOn5WAI0TadzlH7orKDujdsyXsmE,1772 geocoder/here.py,sha256=z6aXpEfnvePhfy8oMggh7--nLUDyy7x0ymxrRHdNRVY,3584 geocoder/here_reverse.py,sha256=_Yfcxul-cJUq_LXEfYyMoV7EOdkifqTU81Ud-dkwGyM,1473 geocoder/ipinfo.py,sha256=pspKFFLZpD9b8OBnReXBjfkk4xYcJg1PB1W_TXrKZb0,1857 geocoder/keys.py,sha256=1USRpuYyfzjhqFkDmxYbObV3PCSZy0YEfBr7SlVhlI8,823 geocoder/komoot.py,sha256=eQdjXfEzQlvao8UhGasfXo4n4PmoGqN7vMxOM3N8Mow,3225 geocoder/komoot_reverse.py,sha256=v18dPvJluJmtL-L5DKA8gQxISLP-COwR6h6ZYEnHcWA,923 geocoder/location.py,sha256=OP_ShzIVzjsc9kPLUVS4_rVzQMrFRTbMGD1EYznDBsg,3778 geocoder/mapbox.py,sha256=KhXtybXtctkcFZg-ILsT286ZF6OCaN9eLsoBGXtwRbw,3296 geocoder/mapbox_reverse.py,sha256=mLUe6D-17oSI7TpN7VpIrrZAMnLRbJa4nAqEhtcrg0Y,1454 geocoder/mapquest.py,sha256=TkPscllia3t4jiR-OWGlWgcEueU3-4mpgMZmNxLNoMQ,2650 geocoder/mapquest_reverse.py,sha256=3SmKKXz6Ynn_TaA6b7bHiTdL4BM6tsxK-GCm8KmGeAU,1346 geocoder/mapzen.py,sha256=acR1ojVvGxtD7ddapbe-KFBtvau6XaAzOYH-9nUj65g,2570 geocoder/mapzen_reverse.py,sha256=rAJ--kHf9IBsC0tJWSvlGFtOCiN4cgMoiQBKat-MeR8,1266 geocoder/maxmind.py,sha256=3F9RYlcY-u4mK5y6STm0F-stOTdS1C8gpFa509AMVO4,3106 geocoder/opencage.py,sha256=So-79-5ZjvIc9IK7Y01EZk9KUhsm62aw2p1Xjz7krmw,4463 geocoder/opencage_reverse.py,sha256=kGB6VTqZwmIUceHbA47OwP2LDjQbr_ljXqBhu2mFqpc,1352 geocoder/osm.py,sha256=_l1uJwGMT_eYiI5dSai6eo-vY8-wBuXCr_rFL2uGbi4,9557 geocoder/osm_reverse.py,sha256=3GMDP7Lne-MfmGMRDG6dA2yAc0rIq3QOrk_6M9fq6sA,969 geocoder/ottawa.py,sha256=tVPa_9jUkCvfjzFfKkxCsf6Rrih-dN2zc4gCj7VXdpc,2664 geocoder/ottawa_parcel.py,sha256=5HLbwwD1ZHx7P67Hy4lFcg4zdMF64HBX6qNX5TEfSqg,4130 geocoder/tamu.py,sha256=F6huIAc1VljFVISZgULinxnrWzJEiFllLgy7J2BIVPU,5234 geocoder/tomtom.py,sha256=Jm3Fu4YI4SHVyciNL5XD8Ttz1GRWCrgzxAUnCpxsagQ,2178 geocoder/w3w.py,sha256=db9hwXydFoIFlKQlKwRUjXDpSCivuq9YdSpKd0a0kp0,1652 geocoder/w3w_reverse.py,sha256=-oD-P5yRt7OtuClfNjUaiBG1QwnPjrEH0Aj25oqhGhs,1327 geocoder/yahoo.py,sha256=NmG7NZ3trWZQVUNOkJ04CpVRxw_tYg4-nbZ5BlLLjFg,2523 geocoder/yandex.py,sha256=ad7KLhNmUOsS3V6Kwg_8E8kstKRTiV2ocfjvWfSAuhc,4345 geocoder/yandex_reverse.py,sha256=yZ4K7mXGwpr7oQsafingN0d8IyFyC72kT5MaHbH2y2A,1936 geocoder-1.12.0.dist-info/DESCRIPTION.rst,sha256=fY0GEday0tZY6ysVgJELkAHp5WxR7-V1RYSC8ype7lI,13348 geocoder-1.12.0.dist-info/METADATA,sha256=pAXvK3TzIp-MB85n-Evcj0_i3VdUvWoNFadyXB4w1fQ,14620 geocoder-1.12.0.dist-info/RECORD,, geocoder-1.12.0.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 geocoder-1.12.0.dist-info/entry_points.txt,sha256=2GB66uYxNSmg06fbRH9qfXyR4nwV4WNA7YWv7W0Gcys,64 geocoder-1.12.0.dist-info/metadata.json,sha256=riw_i6JHA2i3y4Ax1fxViIaYKMn5RDGg5nDs2Jq3Vlo,1503 geocoder-1.12.0.dist-info/top_level.txt,sha256=zCI0Nwb2NHT105obkHfGCus-rCufzH0R1rUMPpaCZx0,9 PK,HؾҬ""geocoder/ottawa_parcel.pyPK,H@Z Z Ygeocoder/mapquest.pyPK,HP" " geocoder/maxmind.pyPK,H}d 8'geocoder/google.pyPK,HL5Ggeocoder/canadapost.pyPK,H\geocoder/google_reverse.pyPK,Hk dbgeocoder/komoot.pyPK,H'a$DHH-ogeocoder/opencage_reverse.pyPK,H^pGtttgeocoder/w3w.pyPK,HzB&} } P{geocoder/bing.pyPK,HΠBBgeocoder/mapquest_reverse.pyPK,Hhhwgeocoder/google_elevation.pyPK,H)_|kgeocoder/location.pyPK,H  geocoder/baidu.pyPK,Hq+bgeocoder/tomtom.pyPK,H#7 ͳgeocoder/yahoo.pyPK,Hh]Fs ׽geocoder/mapbox.pyPK,Hce//geocoder/w3w_reverse.pyPK,HdKgeocoder/mapzen_reverse.pyPK,Hiaaugeocoder/arcgis.pyPK,Ha5U%U%geocoder/osm.pyPK,Hط geocoder/arcgis_reverse.pyPK,Hג w geocoder/distance.pyPK,H;geocoder/mapbox_reverse.pyPK,H!geocoder/osm_reverse.pyPK,H:oo"geocoder/opencage.pyPK,H!]3geocoder/bing_reverse.pyPK,HB:e8geocoder/google_timezone.pyPK,H^dv DD@geocoder/geolytica.pyPK,Hv  zGgeocoder/mapzen.pyPKnHcQgeocoder/yandex_reverse.pyPK,Ha((|Ygeocoder/base.pyPK,Hأrrgeocoder/tamu.pyPK,HV==bgeocoder/cli.pyPKWHo\/̞geocoder/yandex.pyPKH! 44geocoder/api.pyPK,H t} <geocoder/freegeoip.pyPK,H\P5geocoder/komoot_reverse.pyPK,Hd) ) geocoder/geonames.pyPK,Htcgeocoder/here_reverse.pyPK,H?<AAZgeocoder/ipinfo.pyPK,H geocoder/here.pyPK,H}77geocoder/keys.pyPK,HUh h ^geocoder/ottawa.pyPKHOi&geocoder/__init__.pyPKHJ$4$4)+geocoder-1.12.0.dist-info/DESCRIPTION.rstPKH'n@@*)`geocoder-1.12.0.dist-info/entry_points.txtPKH}'`geocoder-1.12.0.dist-info/metadata.jsonPKHlx 'fgeocoder-1.12.0.dist-info/top_level.txtPKHndnn#ggeocoder-1.12.0.dist-info/WHEELPKH%b99"ggeocoder-1.12.0.dist-info/METADATAPKH8,, *geocoder-1.12.0.dist-info/RECORDPK44