Package: routingpy
One lib to route them all-routingpyis a Python 3 client for several
popular routing webservices.Inspired bygeopyand its great community of contributors,routingpyenables
easy and consistent access to third-party spatial webservices to requestroute directions,isochronesortime-distance matrices.routingpycurrently includes support for the following services:Mapbox, either Valhalla or OSRMOpenrouteserviceHere MapsGoogle MapsGraphhopperOpenTripPlannerV2Local ValhallaLocal OSRMThis list is hopefully growing with time and contributions by other developers. An up-to-date list is always available
in ourdocumentation.routing-pyis tested against CPython versions 3.8, 3.9, 3.10, 3.11. PyPy3 is currently not supported, see#60.© routingpy contributors 2022 under theApache 2.0 License.Why routingpy?You want toget from A to B by transit, foot, bike, car or hgvcompute a region of reachabilitycalculate a time distance matrix for a N x M tableand don’t know which provider to use? Great. Thenroutingpyis exactly what you’re looking for.For the better or worse, every provider works on different spatial global datasets and uses a plethora of algorithms on top.
While Google or HERE build on top of proprietary datasets, providers such as Mapbox or Graphhopper consume OpenStreetMap data
for their base network. Also, all providers offer a different amount of options one can use to restrict the wayfinding.
Ultimately this means thatresults may differ- and our experience tells us: they do, and not
too little. This calls for a careful evaluation which service provider to use for which specific use case.Withroutingpywe have made an attempt to simplify this process for you.InstallationRecommended: Install viapoetry:poetryaddroutingpyInstall usingpipwithpipinstallroutingpyOr the lastest from sourcepipinstallgit+git://github.com/gis-ops/routingpyAPIEvery provider has its own specifications and features. However the basic blueprints are the same across all. We tried hard
to make the transition from one provider to the other as seamless as possible. We follow two dogmas for all implementations:All basic parameters have to be the same for all routers for each endpointAll routers still retain their special parameters for their endpoints, which make them unique in the endThis naturally means that usually thosebasic parameters are not named the same wayas the endpoints they query. However,
allprovider specific parameters are named the exact sameas their remote counterparts.The following table gives you an overview which basic arguments are abstracted:EndpointArgumentFunctiondirectionslocationsSpecify the locations to be visited in order. Usually thisis done with[Lon, Lat]tuples, but some routers offeradditional options to create a location element.profileThe mode of transport, i.e. car, bicycle, pedestrian. Eachrouter specifies their own profiles.isochroneslocationsSpecify the locations to calculate isochrones for. Usuallythis is done with[Lon, Lat]tuples, but some routersoffer additional options to create a location element.profileThe mode of transport, i.e. car, bicycle, pedestrian. Eachrouter specifies their own profiles.intervalsThe ranges to calculate isochrones for. Either in secondsor in meters, depending oninterval_type.intervals _typeThe dimension ofintervals, which takes routerdependent values, but generally describes time or distancematrixlocationsSpecify all locations you want to calculate a matrixfor. Ifsourcesordestinationsis not set, thiswill return a symmetrical matrix. Usually this is donewith[Lon, Lat]tuples, but some routers offeradditional options to create a location element.profileThe mode of transport, i.e. car, bicycle, pedestrian. Eachrouter specifies their own profiles.sourcesThe indices of thelocationsparameter iterable totake as sources for the matrix calculation. If notspecified alllocationsare considered to be sources.destinationsThe indices of thelocationsparameter iterable totake as destinations for the matrix calculation. If notspecified alllocationsare considered to bedestinations.ContributingWe :heart: contributions and realistically think that’s the only way to support and maintain most
routing engines in the long run. To get you started, we created aContribution guideline.ExamplesFollow our examples to understand how simpleroutingpyis to use.On top of the examples listed below, find interactive notebook(s) onmybinder.org.Basic UsageGet all attributesroutingpyis designed to take the burden off your shoulder to parse the JSON response of each provider, exposing
the most important information of the response as attributes of the response object. The actual JSON is always accessible via
therawattribute:fromroutingpyimportMapboxValhallafrompprintimportpprint# Some locations in Berlincoords=[[13.413706,52.490202],[13.421838,52.514105],[13.453649,52.507987],[13.401947,52.543373]]client=MapboxValhalla(api_key='mapbox_key')route=client.directions(locations=coords,profile='pedestrian')isochrones=client.isochrones(locations=coords[0],profile='pedestrian',intervals=[600,1200])matrix=client.matrix(locations=coords,profile='pedestrian')pprint((route.geometry,route.duration,route.distance,route.raw))pprint((isochrones.raw,isochrones[0].geometry,isochrones[0].center,isochrones[0].interval))pprint((matrix.durations,matrix.distances,matrix.raw))Multi ProviderEasily calculate routes, isochrones and matrices for multiple providers:fromroutingpyimportGraphhopper,ORS,MapboxOSRMfromshapely.geometryimportPolygon# Define the clients and their profile parameterapis=((ORS(api_key='ors_key'),'cycling-regular'),(Graphhopper(api_key='gh_key'),'bike'),(MapboxOSRM(api_key='mapbox_key'),'cycling'))# Some locations in Berlincoords=[[13.413706,52.490202],[13.421838,52.514105],[13.453649,52.507987],[13.401947,52.543373]]forapiinapis:client,profile=apiroute=client.directions(locations=coords,profile=profile)print("Direction -{}:\n\tDuration:{}\n\tDistance:{}".format(client.__class__.__name__,route.duration,route.distance))isochrones=client.isochrones(locations=coords[0],profile=profile,intervals=[600,1200])forisoinisochrones:print("Isochrone{}secs -{}:\n\tArea:{}sqm".format(client.__class__.__name__,iso.interval,Polygon(iso.geometry).area))matrix=client.matrix(locations=coords,profile=profile)print("Matrix -{}:\n\tDurations:{}\n\tDistances:{}".format(client.__class__.__name__,matrix.durations,matrix.distances))Dry run - DebugOften it is crucial to examine the request before it is sent. Mostly useful for debugging:fromroutingpyimportORSclient=ORS(api_key='ors_key')route=client.directions(locations=[[13.413706,52.490202],[13.421838,52.514105]],profile='driving-hgv',dry_run=True)Advanced UsageLocal instance of FOSS routerAll FOSS routing engines can be run locally, such as openrouteservice, Valhalla, OSRM and GraphHopper. To be able
to useroutingpywith a local installation, just change thebase_urlof the client. This assumes that you did
not change the URL(s) of the exposed endpoint(s):fromroutingpyimportValhalla# no trailing slash, api_key is not necessaryclient=Valhalla(base_url='http://localhost:8088/v1')Proxies, Rate limiters and API errorsProxies are easily set up using followingrequestsscheme for proxying. Also, when batch requesting,routingpycan be set up to resume its requests when the remote API rate limits (i.e. responds
with HTTP 429). Also, it can be set up to ignore API errors and instead print them as warnings tostdout. Be careful,
when ignoringRouterApiErrors, those often count towards your rate limit.All these parameters, and more, can optionally beglobally setfor all router modules or individually per instance:fromroutingpyimportGraphhopper,ORSfromroutingpy.routersimportoptionsrequest_kwargs=dict(proxies=dict(https='129.125.12.0'))client=Graphhopper(api_key='gh_key',retry_over_query_limit=False,skip_api_error=True,requests_kwargs=request_kwargs)# Or alternvatively, set these options globally:options.default_proxies={'https':'129.125.12.0'}options.default_retry_over_query_limit=Falseoptions.default_skip_api_error=True