lab_weather/geocoder/geocodefarm.py

203 lines
5.8 KiB
Python

#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import logging
from geocoder.base import OneResult, MultipleResultsQuery
from geocoder.keys import geocodefarm_key
class GeocodeFarmResult(OneResult):
def __init__(self, json_content):
# create safe shortcuts
self._coordinates = json_content.get('COORDINATES', {})
self._boundaries = json_content.get('BOUNDARIES', {})
self._address = json_content.get('ADDRESS', {})
self._location_details = json_content.get('LOCATION_DETAILS', {})
# proceed with super.__init__
super(GeocodeFarmResult, self).__init__(json_content)
@property
def lat(self):
lat = self._coordinates.get('latitude')
if lat:
return float(lat)
@property
def lng(self):
lng = self._coordinates.get('longitude')
if lng:
return float(lng)
@property
def accuracy(self):
return self.raw.get('accuracy')
@property
def bbox(self):
south = self._boundaries.get('southwest_latitude')
west = self._boundaries.get('southwest_longitude')
north = self._boundaries.get('northeast_latitude')
east = self._boundaries.get('northeast_longitude')
return self._get_bbox(south, west, north, east)
@property
def address(self):
return self.raw.get('formatted_address')
@property
def housenumber(self):
return self._address.get('street_number')
@property
def street(self):
return self._address.get('street_name')
@property
def neighborhood(self):
return self._address.get('neighborhood')
@property
def city(self):
return self._address.get('locality')
@property
def county(self):
return self._address.get('admin_2')
@property
def state(self):
return self._address.get('admin_1')
@property
def country(self):
return self._address.get('country')
@property
def postal(self):
return self._address.get('postal_code')
@property
def elevation(self):
return self._location_details.get('elevation')
@property
def timezone_long(self):
return self._location_details.get('timezone_long')
@property
def timezone_short(self):
return self._location_details.get('timezone_short')
class GeocodeFarmQuery(MultipleResultsQuery):
"""
Geocode.Farm
============
Geocode.Farm is one of the few providers that provide this highly
specialized service for free. We also have affordable paid plans, of
course, but our free services are of the same quality and provide the same
results. The major difference between our affordable paid plans and our
free API service is the limitations. On one of our affordable paid plans
your limit is set based on the plan you signed up for, starting at 25,000
query requests per day (API calls). On our free API offering, you are
limited to 250 query requests per day (API calls).
Params
------
:param location: The string to search for. Usually a street address.
:param key: (optional) API Key. Only Required for Paid Users.
:param lang: (optional) 2 digit lanuage code to return results in. Currently only "en"(English) or "de"(German) supported.
:param country: (optional) The country to return results in. Used for biasing purposes and may not fully filter results to this specific country.
API Reference
-------------
https://geocode.farm/geocoding/free-api-documentation/
"""
provider = 'geocodefarm'
method = 'geocode'
_URL = 'https://www.geocode.farm/v3/json/forward/'
_RESULT_CLASS = GeocodeFarmResult
_KEY = geocodefarm_key
_KEY_MANDATORY = False
def __init__(self, location, **kwargs):
super(GeocodeFarmQuery, self).__init__(location, **kwargs)
self.api_status = {}
self.api_account = {}
def _build_params(self, location, provider_key, **kwargs):
return {
'addr': location,
'key': provider_key,
'lang': kwargs.get('lang', ''),
'country': kwargs.get('country', ''),
'count': kwargs.get('maxRows', 1),
}
def _catch_errors(self, json_response):
status = json_response['geocoding_results']['STATUS'].get('status')
if not status == 'SUCCESS':
self.error = status
return self.error
def _adapt_results(self, json_response):
return json_response['geocoding_results']['RESULTS']
def _parse_results(self, json_response):
super(GeocodeFarmQuery, self)._parse_results(json_response)
# store status and account details
self.api_status = json_response['geocoding_results']['STATUS']
self.api_account = json_response['geocoding_results']['ACCOUNT']
@property
def access(self):
return self.api_status.get('access')
@property
def address_provided(self):
return self.api_status.get('address_provided')
@property
def ip_address(self):
return self.api_account.get('ip_address')
@property
def distribution_license(self):
return self.api_account.get('distribution_license')
@property
def usage_limit(self):
usage_limit = self.api_account.get('usage_limit')
if usage_limit:
return int(usage_limit)
@property
def used_today(self):
used_today = self.api_account.get('used_today')
if used_today:
return int(used_today)
@property
def used_total(self):
used_total = self.api_account.get('used_total')
if used_total:
return int(used_total)
@property
def first_used(self):
return self.api_account.get('first_used')
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
g = GeocodeFarmQuery("New York City")
g.debug()