lab_weather/geocoder/here.py

167 lines
4.4 KiB
Python

#!/usr/bin/python
# coding: utf8
from __future__ import absolute_import
import logging
from geocoder.base import OneResult, MultipleResultsQuery
from geocoder.keys import here_app_id, here_app_code
from geocoder.location import BBox
class HereResult(OneResult):
def __init__(self, json_content):
self._display_position = json_content.get('DisplayPosition', {})
self._address = json_content.get('Address', {})
self._mapview = json_content.get('MapView', {})
for item in json_content['Address']['AdditionalData']:
json_content[item['key']] = item['value']
super(HereResult, self).__init__(json_content)
@property
def lat(self):
return self._display_position.get('Latitude')
@property
def lng(self):
return self._display_position.get('Longitude')
@property
def address(self):
return self._address.get('Label')
@property
def postal(self):
return self._address.get('PostalCode')
@property
def housenumber(self):
return self._address.get('HouseNumber')
@property
def street(self):
return self._address.get('Street')
@property
def neighborhood(self):
return self.district
@property
def district(self):
return self._address.get('District')
@property
def city(self):
return self._address.get('City')
@property
def county(self):
return self._address.get('County')
@property
def state(self):
return self._address.get('State')
@property
def country(self):
return self._address.get('Country')
@property
def quality(self):
return self.raw.get('MatchLevel')
@property
def accuracy(self):
return self.raw.get('MatchType')
@property
def bbox(self):
south = self._mapview['BottomRight'].get('Latitude')
north = self._mapview['TopLeft'].get('Latitude')
west = self._mapview['TopLeft'].get('Longitude')
east = self._mapview['BottomRight'].get('Longitude')
return self._get_bbox(south, west, north, east)
class HereQuery(MultipleResultsQuery):
"""
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']
_URL = 'http://geocoder.cit.api.here.com/6.2/geocode.json'
_RESULT_CLASS = HereResult
@classmethod
def _get_api_key(cls, key=None):
# API key is split between app_id and app_code -> managed in _build_params
pass
def _build_params(self, location, provider_key, **kwargs):
# 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
params = {
'searchtext': location,
'app_id': app_id,
'app_code': app_code,
'gen': 9,
'maxresults': kwargs.get('maxRows', 1),
'language': kwargs.get('language', 'en'),
}
# bounding box if present
bbox = kwargs.get('bbox')
if bbox:
bbox = BBox(bbox=bbox)
# do not forget to convert bbox to mapbox expectations...
params['bbox'] = u'{north},{west};{south},{east}'.format(
west=bbox.west,
east=bbox.east,
south=bbox.south,
north=bbox.north
)
for value in self.qualified_address:
if kwargs.get(value) is not None:
params[value] = kwargs.get(value)
return params
def _catch_errors(self, json_response):
status = json_response.get('type')
if not status == 'OK':
self.error = status
return self.error
def _adapt_results(self, json_response):
# Build intial Tree with results
return [item['Location']
for item in json_response['Response']['View'][0]['Result']]
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
g = HereQuery("New York City")
g.debug()