56 lines
1.8 KiB
Python
56 lines
1.8 KiB
Python
import json
|
|
|
|
from uritemplate import URITemplate
|
|
|
|
from mapbox import errors
|
|
from mapbox.services.base import Service
|
|
|
|
|
|
class MapMatcher(Service):
|
|
"""Access to the Map Matching API V4"""
|
|
|
|
api_name = 'matching'
|
|
api_version = 'v4'
|
|
valid_profiles = ['mapbox.driving', 'mapbox.cycling', 'mapbox.walking']
|
|
|
|
def _validate_profile(self, profile):
|
|
if profile not in self.valid_profiles:
|
|
raise errors.InvalidProfileError(
|
|
"{0} is not a valid profile".format(profile))
|
|
return profile
|
|
|
|
def _validate_feature(self, val):
|
|
# validate single feature with linestring geometry up to 100 pts
|
|
try:
|
|
assert val['type'] == 'Feature'
|
|
assert val['geometry']['type'] == 'LineString'
|
|
assert len(val['geometry']['coordinates']) <= 100
|
|
except (TypeError, KeyError, AssertionError):
|
|
raise errors.InvalidFeatureError(
|
|
"Feature must have LineString geometry with <= 100 points")
|
|
return val
|
|
|
|
def match(self, feature, gps_precision=None, profile='mapbox.driving'):
|
|
"""Match features to OpenStreetMap data."""
|
|
profile = self._validate_profile(profile)
|
|
|
|
feature = self._validate_feature(feature)
|
|
geojson_line_feature = json.dumps(feature)
|
|
|
|
uri = URITemplate(self.baseuri + '/{profile}.json').expand(
|
|
profile=profile)
|
|
|
|
params = None
|
|
if gps_precision:
|
|
params = {'gps_precision': gps_precision}
|
|
|
|
res = self.session.post(uri, data=geojson_line_feature, params=params,
|
|
headers={'Content-Type': 'application/json'})
|
|
self.handle_http_error(res)
|
|
|
|
def geojson():
|
|
return res.json()
|
|
|
|
res.geojson = geojson
|
|
return res
|