139 lines
5.3 KiB
Python
139 lines
5.3 KiB
Python
"""Matrix API V1"""
|
|
|
|
import re
|
|
import warnings
|
|
|
|
from mapbox.encoding import encode_waypoints
|
|
from mapbox.errors import InvalidProfileError, MapboxDeprecationWarning
|
|
from mapbox.services.base import Service
|
|
|
|
|
|
class DirectionsMatrix(Service):
|
|
"""Access to the Matrix API V1"""
|
|
|
|
api_name = 'directions-matrix'
|
|
api_version = 'v1'
|
|
|
|
valid_profiles = [
|
|
'mapbox/driving', 'mapbox/cycling', 'mapbox/walking',
|
|
'mapbox/driving-traffic']
|
|
valid_annotations = ['duration', 'distance']
|
|
|
|
@property
|
|
def baseuri(self):
|
|
return 'https://{0}/{1}/{2}'.format(
|
|
self.host, self.api_name, self.api_version)
|
|
|
|
def _validate_profile(self, profile):
|
|
# Support for Distance v1 and Directions v4 profiles
|
|
profiles_map = {
|
|
'mapbox.driving': 'mapbox/driving',
|
|
'mapbox.cycling': 'mapbox/cycling',
|
|
'mapbox.walking': 'mapbox/walking',
|
|
'driving': 'mapbox/driving',
|
|
'cycling': 'mapbox/cycling',
|
|
'walking': 'mapbox/walking'}
|
|
if profile in profiles_map:
|
|
profile = profiles_map[profile]
|
|
warnings.warn("Converting deprecated profile, use {} instead".format(profile),
|
|
MapboxDeprecationWarning)
|
|
if profile not in self.valid_profiles:
|
|
raise InvalidProfileError(
|
|
"{0} is not a valid profile".format(profile))
|
|
return profile
|
|
|
|
def _validate_annotations(self, annotations):
|
|
results = []
|
|
if annotations is None:
|
|
return None
|
|
for annotation in annotations:
|
|
if annotation not in self.valid_annotations:
|
|
raise errors.InvalidParameterError(
|
|
"{0} is not a valid annotation".format(annotation))
|
|
else:
|
|
results.append(annotation)
|
|
return results
|
|
|
|
def _make_query(self, srcindexes, dstindexes):
|
|
params = {}
|
|
if srcindexes is not None and isinstance(srcindexes, list):
|
|
params['sources'] = ';'.join([str(idx) for idx in srcindexes])
|
|
if dstindexes is not None and isinstance(dstindexes, list):
|
|
params['destinations'] = ';'.join([str(idx) for idx in dstindexes])
|
|
return params
|
|
|
|
def matrix(self, coordinates, profile='mapbox/driving',
|
|
sources=None, destinations=None, annotations=None):
|
|
"""Request a directions matrix for trips between coordinates
|
|
|
|
In the default case, the matrix returns a symmetric matrix,
|
|
using all input coordinates as sources and destinations. You may
|
|
also generate an asymmetric matrix, with only some coordinates
|
|
as sources or destinations:
|
|
|
|
Parameters
|
|
----------
|
|
coordinates : sequence
|
|
A sequence of coordinates, which may be represented as
|
|
GeoJSON features, GeoJSON geometries, or (longitude,
|
|
latitude) pairs.
|
|
profile : str
|
|
The trip travel mode. Valid modes are listed in the class's
|
|
valid_profiles attribute.
|
|
annotations : list
|
|
Used to specify the resulting matrices. Possible values are
|
|
listed in the class's valid_annotations attribute.
|
|
sources : list
|
|
Indices of source coordinates to include in the matrix.
|
|
Default is all coordinates.
|
|
destinations : list
|
|
Indices of destination coordinates to include in the
|
|
matrix. Default is all coordinates.
|
|
|
|
Returns
|
|
-------
|
|
requests.Response
|
|
|
|
Note: the directions matrix itself is obtained by calling the
|
|
response's json() method. The resulting mapping has a code,
|
|
the destinations and the sources, and depending of the
|
|
annotations specified, it can also contain a durations matrix,
|
|
a distances matrix or both of them (by default, only the
|
|
durations matrix is provided).
|
|
|
|
code : str
|
|
Status of the response
|
|
sources : list
|
|
Results of snapping selected coordinates to the nearest
|
|
addresses.
|
|
destinations : list
|
|
Results of snapping selected coordinates to the nearest
|
|
addresses.
|
|
durations : list
|
|
An array of arrays representing the matrix in row-major
|
|
order. durations[i][j] gives the travel time from the i-th
|
|
source to the j-th destination. All values are in seconds.
|
|
The duration between the same coordinate is always 0. If
|
|
a duration can not be found, the result is null.
|
|
distances : list
|
|
An array of arrays representing the matrix in row-major
|
|
order. distances[i][j] gives the distance from the i-th
|
|
source to the j-th destination. All values are in meters.
|
|
The distance between the same coordinate is always 0. If
|
|
a distance can not be found, the result is null.
|
|
|
|
"""
|
|
annotations = self._validate_annotations(annotations)
|
|
profile = self._validate_profile(profile)
|
|
coords = encode_waypoints(coordinates)
|
|
|
|
params = self._make_query(sources, destinations)
|
|
|
|
if annotations is not None:
|
|
params.update({'annotations': ','.join(annotations)})
|
|
|
|
uri = '{0}/{1}/{2}'.format(self.baseuri, profile, coords)
|
|
res = self.session.get(uri, params=params)
|
|
self.handle_http_error(res)
|
|
return res
|