Customizable Routing

Let's try customizable routing inside a Jupyter Notebook. Read the details in this blog post and also here. You can install the open source GraphHopper routing engine locally and replace the route_url with

route_url = 'http://localhost:8989/route?

Documentation for the folium library.

In [1]:
route_url = 'http://148.251.46.152:8989/route-custom'
In [2]:
import requests
import folium # https://python-visualization.github.io/folium/

def latlon ( point_arr ): return [point_arr[1],point_arr[0]]
def plot_route ( map, start, end, route, name, color ): 
    print(f'{name}: distance {(int)(route["distance"]/1000)}km and time {(int)(route["time"]/60000)}min');
    def style_function(feature):
        return { 'opacity': 0.5, 'weight': 5, 'color': color }
    m = folium.Map(location=start, zoom_start=12)
    folium.Marker(location=latlon(start), popup='start', icon=folium.Icon(color='green')).add_to(map)
    folium.Marker(location=latlon(end), popup='end', icon=folium.Icon(color='red')).add_to(map)
    folium.GeoJson(route["points"], name=name, style_function=style_function).add_to(map)
    # folium.Choropleth(geo_data=geojson, name=name, line_color=color).add_to(m)

Plot a first custom route with a green start marker and a red destination marker

In [3]:
start=[13.384094,52.495323]
end=[13.447952,52.521235]

m = folium.Map(location=latlon(start), zoom_start=12)

route = requests.post(url=route_url, json={'profile':'car', 'points':[start,end], 'points_encoded':False}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "route", "blue")

priorityJson = {'road_class': {'primary': 0.5}}
route = requests.post(url=route_url, json={'profile':'car', 'points':[start,end], 'points_encoded':False, 'priority': priorityJson}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "other", "red")

m
route: distance 6km and time 9min
other: distance 6km and time 10min
Out[3]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Safe Biking

Avoid roads with max_speed greater than 50 km/h.

In [4]:
start=[11.555686,49.954506]
end=[11.531997,49.963368]

m = folium.Map(location=latlon(start), zoom_start=14)

route = requests.post(url=route_url, json={'profile':'bike', 'points':[start,end], 'points_encoded':False}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "route", "blue")

priorityJson = {'max_speed': {'>50': 0.1}}
route = requests.post(url=route_url, json={'profile':'bike', 'points':[start,end], 'points_encoded':False, 'priority': priorityJson}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "other", "red")

m
route: distance 2km and time 8min
other: distance 2km and time 10min
Out[4]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Avoid tunnels

In [5]:
start=[11.58268,49.950157]
end=[11.579322,49.946898]

m = folium.Map(location=latlon(start), zoom_start=16)

route = requests.post(url=route_url, json={'profile':'bike', 'points':[start,end], 'points_encoded':False}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "route", "blue")

priorityJson = {'road_environment': {'tunnel': 0.01}}
route = requests.post(url=route_url, json={'profile':'bike', 'points':[start,end], 'points_encoded':False, 'priority': priorityJson}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "other", "red")

m
route: distance 0km and time 2min
other: distance 0km and time 2min
Out[5]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Cargo Bike

Cargo bikes require a certain width

In [6]:
start=[13.358881,52.502368]
end=[13.359187,52.502136]

m = folium.Map(location=latlon(start), zoom_start=18)

route = requests.post(url=route_url, json={'profile':'bike', 'points':[start,end], 'points_encoded':False}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "route", "blue")

priorityJson = {'road_class': {'steps': 0}, 'max_width': {'<1.5': 0.}}
route = requests.post(url=route_url, json={'profile':'bike', 'points':[start,end], 'points_encoded':False, 'priority': priorityJson}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "other", "red")

m
route: distance 0km and time 0min
other: distance 0km and time 0min
Out[6]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Walking for Tourists

Let's prefer roads from the official foot network

In [7]:
start=[13.227196,52.600389]
end=[13.275261,52.597652]

m = folium.Map(location=latlon(start), zoom_start=15)

route = requests.post(url=route_url, json={'profile':'foot', 'points':[start,end], 'points_encoded':False}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "route", "blue")

priorityJson = {'foot_network': {'other': 0.5}}
route = requests.post(url=route_url, json={'profile':'foot', 'points':[start,end], 'points_encoded':False, 'priority': priorityJson}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "other", "red")

m
route: distance 3km and time 42min
other: distance 4km and time 48min
Out[7]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Economically Driving

In [8]:
start=[13.90367,51.263607]
end=[13.11656,51.117263]

m = folium.Map(location=latlon(start), zoom_start=11)

route = requests.post(url=route_url, json={'profile':'car', 'points':[start,end], 'points_encoded':False}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "route", "blue")

di = 200
maxSpeedJson = {'road_class': {'*': 110}}
speedFactorJson = {}
priorityJson = {'road_class': {'motorway': 0.8}}
route = requests.post(url=route_url, json={'profile':'car', 'points':[start,end], 'points_encoded':False, 
                                        'distance_influence': di, 'speed_factor':speedFactorJson,'max_speed':maxSpeedJson,'priority': priorityJson}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "other", "red")

m
route: distance 71km and time 47min
other: distance 66km and time 70min
Out[8]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Block Area

In [9]:
start=[14.358444,51.711502]
end=[14.302139,51.799274]

m = folium.Map(location=latlon(start), zoom_start=12)

route = requests.post(url=route_url, json={'profile':'car', 'points':[start,end], 'points_encoded':False}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "route", "blue")

area = { "type": "Feature", "properties": {}, 
         "geometry": { 
           "type": "Polygon", 
           "coordinates": [[[14.31, 51.75], [14.34,51.75], [14.34,51.77], [14.31,51.77], [14.31,51.75]]]
         }}
priorityJson = {'area_cottbus': 0}
route = requests.post(url=route_url, json={'profile':'car', 'points':[start,end], 'points_encoded':False, 
                                        'priority': priorityJson, 'areas': {'cottbus': area}}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "other", "red")

folium.GeoJson(area, name='blocked area').add_to(m)

m
route: distance 11km and time 16min
other: distance 14km and time 18min
Out[9]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Truck

Exclude ferries and tracks. And avoid smaller roads like residential and tertiary.

In [10]:
start=[4.760513,52.456637]
end=[4.727898,52.430897]

m = folium.Map(location=latlon(start), zoom_start=13)

route = requests.post(url=route_url, json={'profile':'car', 'points':[start,end], 'points_encoded':False}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "route", "blue")

priorityJson = {'road_environment': {'ferry': 0.1}, 'road_class': {'residential':0.3, 'tertiary':0.3, 'track':0.0} }
route = requests.post(url=route_url, json={'profile':'car', 'points':[start,end], 'points_encoded':False, 
                                        'priority': priorityJson}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "other", "red")

m
route: distance 4km and time 8min
other: distance 22km and time 19min
Out[10]:
Make this Notebook Trusted to load map: File -> Trust Notebook

avoid toll

In [11]:
start=[7.334747,47.746711]
end=[6.027374,47.236355]

m = folium.Map(location=latlon(start), zoom_start=10)

route = requests.post(url=route_url, json={'profile':'car', 'points':[start,end], 'points_encoded':False}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "route", "blue")

priorityJson = {'toll': {'no': 1, '*': 0.01} }
route = requests.post(url=route_url, json={'profile':'car', 'points':[start,end], 'points_encoded':False, 
                                        'priority': priorityJson}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "other", "red")

m
route: distance 132km and time 85min
other: distance 135km and time 131min
Out[11]:
Make this Notebook Trusted to load map: File -> Trust Notebook

width or height limitations

In [12]:
start=[13.580818,52.406294]
end=[13.429928,52.479539]

m = folium.Map(location=latlon(start), zoom_start=11)

route = requests.post(url=route_url, json={'profile':'car', 'points':[start,end], 'points_encoded':False}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "route", "blue")

priorityJson = {'hazmat': {'no': 0}, 
                'hazmat_water':{'no': 0}, 
                'hazmat_tunnel': {'D': 0, 'E': 0},
                'max_width': {'<3': 0},   # in meter
                'max_height': {'<4': 0},  # in meter
                'max_weight': {'<3.5': 0}}# in tons
route = requests.post(url=route_url, json={'profile':'car', 'points':[start,end], 'points_encoded':False, 
                                        'priority': priorityJson}).json()
if 'message' in route: raise Exception(route["message"])
plot_route(m, start, end, route["paths"][0], "other", "red")

m
route: distance 15km and time 20min
other: distance 16km and time 24min
Out[12]:
Make this Notebook Trusted to load map: File -> Trust Notebook