In this tutorial we will run a vehicle routing simulation in Julia with the OpenStreetMapX.jl library and use Python's folium package for providing an interactive vizualization of results.
This notebook can be downloaded in Jupyter ipynb format here (right-click to download).
Firstly, start by installing the required Julia and Python packages.
#required installation for map vizualiztion
using Pkg
Pkg.add("PyCall")
Pkg.add("Conda")
Pkg.add("OpenStreetMapX")
using Conda
Conda.runconda(`install folium -c conda-forge`)
Let us load the map of east of Reno (this file is provided together with the OpenStreetMapX.jl
package) and move few thousands of cars around it between random pairs of destinations
using OpenStreetMapX
# you can replace the line below with a String representing another path to an OSM map file.
map_file_path = joinpath(dirname(pathof(OpenStreetMapX)),"..","test/data/reno_east3.osm")
mx = get_map_data(map_file_path, use_cache=false);
using Random
Random.seed!(0)
node_ids = collect(keys(mx.nodes))
routes = Vector{Vector{Int}}()
visits = Dict{Int,Int}()
for i in 1:5000
a,b = [point_to_nodes(generate_point_in_bounds(mx), mx) for _ in 1:2]
route, route_time = OpenStreetMapX.shortest_route(mx,a,b)
if route_time < Inf # when we select points neaer edges no route might be found
push!(routes, route)
for n in route
visits[n] = get(visits, n,0)+1
end
end
end
println("We have generated ",length(routes)," non-empty routes")
Now we vizualize the first 20 random paths in the actual map.
Note that the map is interactive - you can browse around etc..
using PyCall
flm = pyimport("folium")
matplotlib_cm = pyimport("matplotlib.cm")
matplotlib_colors = pyimport("matplotlib.colors")
cmap = matplotlib_cm.get_cmap("prism")
SHOW_PATHS=20
m = flm.Map()
for k=1:min(SHOW_PATHS, length(routes))
locs = [LLA(mx.nodes[n],mx.bounds) for n in routes[k]]
info = "Sample route number $k\n<BR>"*
"Length: $(length(routes[k])) nodes\n<br>" *
"From: $(routes[k][1]) $(round.((locs[1].lat, locs[1].lon),digits=4))\n<br>" *
"To: $(routes[k][end]) $(round.((locs[end].lat, locs[end].lon),digits=4))"
flm.PolyLine(
[(loc.lat, loc.lon) for loc in locs ],
popup=info,
tooltip=info,
color=matplotlib_colors.to_hex(cmap(k/SHOW_PATHS))
).add_to(m)
end
MAP_BOUNDS = [(mx.bounds.min_y,mx.bounds.min_x),(mx.bounds.max_y,mx.bounds.max_x)]
flm.Rectangle(MAP_BOUNDS, color="black",weight=6).add_to(m)
m.fit_bounds(MAP_BOUNDS)
m
Now let show the most freqeuntly visited intersections in our simulation.
m = flm.Map()
max_visits= maximum(values(visits))
for k=keys(visits)
visits[k] < 25 && continue #skip nodes infrequently visited
loc = LLA(mx.nodes[k],mx.bounds)
info = "Node $(k) at ($(round(loc.lat,digits=4)), $(round(loc.lon,digits=4)))\n<br>"*
"visits: $(visits[k])"
flm.Circle(
location=[loc.lat,loc.lon],
popup=info,
tooltip=info,
radius=500*visits[k]/max_visits,
color="crimson",
weight=0.5,
fill=true,
fill_color="crimson"
).add_to(m)
end
flm.Rectangle(MAP_BOUNDS, color="black",weight=6).add_to(m)
m.fit_bounds(MAP_BOUNDS)
m
(c) Przemysław Szufel, 2019
This documentation and samples are licensed under the terms of MIT license.