106 lines
3.9 KiB
Python
106 lines
3.9 KiB
Python
import requests
|
|
import json
|
|
|
|
|
|
class HereMapsRoutingIsoline:
|
|
'A Here Maps Routing wrapper for python'
|
|
|
|
PRODUCTION_ROUTING_BASE_URL = 'https://isoline.route.api.here.com'
|
|
STAGING_ROUTING_BASE_URL = 'https://isoline.route.cit.api.here.com'
|
|
ISOLINE_PATH = '/routing/7.2/calculateisoline.json'
|
|
|
|
OPTIONAL_PARAMS = [
|
|
'departure',
|
|
'arrival',
|
|
'singlecomponent',
|
|
'resolution',
|
|
'maxpoints',
|
|
'quality'
|
|
]
|
|
|
|
def __init__(self, app_id, app_code, base_url=PRODUCTION_ROUTING_BASE_URL):
|
|
self._app_id = app_id
|
|
self._app_code = app_code
|
|
self._url = "{0}{1}".format(base_url, self.ISOLINE_PATH)
|
|
|
|
def calculate_isodistance(self, source, mode, data_range, options=[]):
|
|
return self.__calculate_isolines(source, mode, data_range, 'distance',
|
|
options)
|
|
|
|
def calculate_isochrone(self, source, mode, data_range, options=[]):
|
|
return self.__calculate_isolines(source, mode, data_range, 'time',
|
|
options)
|
|
|
|
def __calculate_isolines(self, source, mode, data_range, range_type,
|
|
options=[]):
|
|
parsed_options = self.__parse_options(options)
|
|
source_param = self.__parse_source_param(source, parsed_options)
|
|
mode_param = self.__parse_mode_param(mode, parsed_options)
|
|
request_params = self.__parse_request_parameters(source_param,
|
|
mode_param,
|
|
data_range,
|
|
range_type,
|
|
parsed_options)
|
|
response = requests.get(self._url, params=request_params)
|
|
if response.status_code == requests.codes.ok:
|
|
return self.__parse_isolines_response(response.text)
|
|
else:
|
|
response.raise_for_status()
|
|
|
|
def __parse_options(self, options):
|
|
return dict(option.split('=') for option in options)
|
|
|
|
def __parse_request_parameters(self, source, mode, data_range, range_type,
|
|
options):
|
|
filtered_options = {k: v for k, v in options.iteritems()
|
|
if k.lower() in self.OPTIONAL_PARAMS}
|
|
filtered_options.update(source)
|
|
filtered_options.update(mode)
|
|
filtered_options.update({'range': ",".join(data_range)})
|
|
filtered_options.update({'rangetype': range_type})
|
|
|
|
return filtered_options
|
|
|
|
def __parse_isolines_response(self, response):
|
|
parsed_response = json.loads(response)
|
|
isolines_response = parsed_response['response']['isoline']
|
|
isolines = []
|
|
for isoline in isolines_response:
|
|
isolines.append({'range': isoline['range'],
|
|
'geom': isoline['component'][0]['shape']})
|
|
|
|
return isolines
|
|
|
|
def __parse_source_param(self, source, options):
|
|
key = 'start'
|
|
if 'is_destination' in options and options['is_destination']:
|
|
key = 'destination'
|
|
|
|
return {key: source}
|
|
|
|
def __parse_mode_param(self, mode, options):
|
|
if 'mode_type' in options:
|
|
mode_type = options['mode_type']
|
|
else:
|
|
mode_type = 'shortest'
|
|
|
|
if 'mode_traffic' in options:
|
|
mode_traffic = "traffic:{0}".format(options['mode_traffic'])
|
|
else:
|
|
mode_traffic = None
|
|
|
|
if 'mode_feature' in options and 'mode_feature_weight' in options:
|
|
mode_feature = "{0}:{1}".format(options['mode_feature'],
|
|
options['mode_feature_weight'])
|
|
else:
|
|
mode_feature = None
|
|
|
|
mode_param = "{0};{1}".format(mode_type, mode)
|
|
if mode_traffic:
|
|
mode_param = "{0};{1}".format(mode_param, mode_traffic)
|
|
|
|
if mode_feature:
|
|
mode_param = "{0};{1}".format(mode_param, mode_feature)
|
|
|
|
return {'mode': mode_param}
|