def match(ctx, features, profile, gps_precision): """Mapbox Map Matching API lets you use snap your GPS traces to the OpenStreetMap road and path network. $ mapbox mapmatching trace.geojson An access token is required, see `mapbox --help`. """ access_token = (ctx.obj and ctx.obj.get('access_token')) or None features = list(features) if len(features) != 1: raise click.BadParameter( "Mapmatching requires a single LineString feature") service = mapbox.MapMatcher(access_token=access_token) try: res = service.match(features[0], profile=profile, gps_precision=gps_precision) except mapbox.errors.ValidationError as exc: raise click.BadParameter(str(exc)) if res.status_code == 200: stdout = click.open_file('-', 'w') click.echo(res.text, file=stdout) else: raise MapboxCLIException(res.text.strip())
def snap2road(pts_lon_lat, timestamps=(), pause=False): """ params: pts_lon_lat: [[lon, lat], [], ...] timestamps: ['2015-10-15T12:06:50Z', ...] return: new_gps: [[lon, lat], [], ...], len(new_gps) not necessarily equals to len(pts_lon_lat) confidences: [ (which batch, # origin pts, # snapped pts, confidence), (), ..] """ import mapbox as mp from utils import even_chunks, work_every_sec from constants import mapbox_access service = mp.MapMatcher(access_token=mapbox_access) snapped = [] raw = [] for bidx, (s, e) in enumerate(even_chunks(pts_lon_lat, 100, indices=True)): batch_pts = pts_lon_lat[s:e] batch_tss = timestamps[s:e] raw.append({ 'batch': bidx, 'raw_len': len(batch_pts), 'raw': batch_pts }) # request service for snapped geojson = { 'type': 'Feature', 'properties': { 'coordTimes': batch_tss }, 'geometry': { 'type': 'LineString', 'coordinates': batch_pts } } response = service.match(geojson, profile='mapbox.cycling') var = response.geojson() features = var['features'] # parse response for fidx, f in enumerate(features): coords = f['geometry']['coordinates'] properties = f['properties'] snapped.append({ 'batch': bidx, 'sub_batch': fidx, 'snapped_len': len(coords), 'confidence': properties['confidence'], 'snapped': coords }) if pause: work_every_sec(sec=0.5) return {'snapped': snapped, 'raw': raw}
def test_matching(line_feature): body = '{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"confidence":0.8165504318718629,"matchedPoints":[[13.418805122375488,52.5005989074707],[13.419145584106445,52.501094818115234],[13.419618606567383,52.50175094604492],[13.420042037963867,52.50233459472656],[13.420494079589844,52.50298309326172]],"indices":[0,1,2,3,4]},"geometry":{"type":"LineString","coordinates":[[13.418805,52.500599],[13.418851,52.500659],[13.419121,52.501057],[13.419146,52.501095],[13.419276,52.501286],[13.419446,52.501518],[13.419619,52.501753],[13.419981,52.502249],[13.420042,52.502335],[13.420494,52.502984]]}}]}' responses.add( responses.POST, 'https://api.mapbox.com/matching/v4/mapbox.driving.json?access_token=pk.test', match_querystring=True, body=body, status=200, content_type='application/json') service = mapbox.MapMatcher(access_token='pk.test') res = service.match(line_feature) assert res.status_code == 200 assert res.json() == res.geojson()
import click import cligj import mapbox from mapboxcli.errors import MapboxCLIException @click.command('mapmatching', short_help="Snap GPS traces to OpenStreetMap") @cligj.features_in_arg @click.option("--gps-precision", default=4, type=int, help="Assumed precision of tracking device (default 4 meters)") @click.option('--profile', default="mapbox.driving", type=click.Choice(mapbox.MapMatcher().valid_profiles), help="Mapbox profile id") @click.pass_context def match(ctx, features, profile, gps_precision): """Mapbox Map Matching API lets you use snap your GPS traces to the OpenStreetMap road and path network. $ mapbox mapmatching trace.geojson An access token is required, see `mapbox --help`. """ access_token = (ctx.obj and ctx.obj.get('access_token')) or None features = list(features) if len(features) != 1: raise click.BadParameter(
def test_invalid_profile(line_feature): service = mapbox.MapMatcher(access_token='pk.test') with pytest.raises(ValueError): service.match(line_feature, profile="covered_wagon")
def test_invalid_feature(): service = mapbox.MapMatcher(access_token='pk.test') with pytest.raises(ValueError) as exc: service.match({'type': 'not-a-feature'}) assert 'feature must have' in exc.message
def test_class_attrs(): """Get expected class attr values""" serv = mapbox.MapMatcher() assert serv.api_name == 'matching' assert serv.api_version == 'v4'