What's the general algorithm to draw a road network of a certain area?

Hi, this might be a naive question. But I would really appreciate it if someone can give me some hints. I was wondering, how do people usually plot the road network of a certain area in a map? Of course, certain coding function is called, but how? Thank you so much for your time and attention.

You can checkout GitHub - pszufe/OpenStreetMapXPlot.jl: Plotting functionality for the OpenStreetMapX.jl (Supports PyPlot.jl and Plots.jl with GR backend) that is the plotting frontend of https://github.com/pszufe/OpenStreetMapX.jl and uses data from OpenStreetMap.

@pszufe is an expert here, so he might have some more advice to share.

2 Likes

OpenStreetMapX.jl allows you to process data in Open Street Map format (if you do not know how to get this data - it is described in project website). In particular a map in OpenStreetMapX.jl is represnted as a LightGraphs.jl graph.

For plotting you can use OpenStreetMapXPlot.jl - this is particularly useful for coloring routes or marking nodes on the map.

For interactive plotting the best tools out there seems to be LeafletJS. There is a Julia wrapper for it LeafletJS.jl but unfortunately it is unmaintained. What I usually do to process map data/analytics with Julia and if I need interactivity I use R-Leaflet integration.

2 Likes

I think I have tried the OpenStreetMapx.jl, with my osm map data. But the data is too large, and the map finally obtained does not look very good. Someone told me that I need to leave out certain information from the data, and eventually I tried the other way around, by using a python package osmnx and then tried to call this python function from juilia. I’d prefer to mainly use Julia though.

Is there a standard way to process the huge osm file obtained from the open street map website?

Use the osmfilter utility first. I do vehicle traffic modellig/agent-based simulations and usually this command works for me:

osmfilter myfile.osm --keep="highway=motorway highway=motorway_link highway=trunk highway=trunk_link     highway=primary highway=primary_link highway=secondary highway=secondary_link highway=tertiary highway=tertiary_link highway=unclassified highway=residential" --drop-author -o=myfileout.osm 

After running this command your file will be around 6x smaller.
Of course you might need different filtering depending on your needs.

3 Likes

@pszufe, One more question. How did you actually draw the edges, I mean, what’s the underlying principle? What I understand is that, if it’s a straight line, then it’s fairly easy to draw, because we basically can know the location of each point along this line. On the other hand, if it’s a curved line, then how did you know the shape / function of the line to draw it? I hope this is not a naive question to ask. I think this has something to do with the open street map data format.

Because I was thinking to model / visualize the movement of a vehicle along the road network. It would be much easier if each edge of the road network is a straight line, since in this case, I can just use linear function as the line/edge along any given two points. On the other hand, if it’s not a straight line, then things would be really complicated. I wonder how you handle this when you draw/plot the map.

@bsnyh - have a look at OpenStreetMapXPlot.jl source code. There are straight lines - just a lot of them. You can easily use OpenStreetMapXPlot.jl to render images of animation frames (with vehicle location), than you can use some other tool to combine the frames into a movie.

1 Like

so, all of them are straight lines, not some kind of curves? If so, then linear interpolation would work.

the frames you’re talking about, do you mean geo-dataframes?

  1. yes they are straight lines and you can use simple interpolation
  2. I mean simply animation frames, you could generate subsequent frames, save the to files and combine into a movie.
1 Like
julia> m=OpenStreetMapX.get_map_data("/home/Desktop/country.osm")
ERROR: MethodError: no method matching get_map_data(::String)
Closest candidates are:
  get_map_data(::String, ::String; road_levels, use_cache) at /home/.julia/packages/OpenStreetMapX/lK8gq/src/parseMap.jl:82
Stacktrace:
 [1] top-level scope at none:0

julia> using Pkg

julia> Pkg.installed()
Dict{String,Union{Nothing, VersionNumber}} with 7 entries:
  "Juno"               => v"0.5.3"
  "OpenStreetMapX"     => v"0.1.1"
  "IJulia"             => v"1.14.1"
  "Plots"              => v"0.22.5"
  "Atom"               => v"0.7.12"
  "PyCall"             => v"1.18.5"
  "OpenStreetMapXPlot" => v"0.1.0"

julia> methods(get_map_data)
# 1 method for generic function "get_map_data":
[1] get_map_data(datapath::String, filename::String; road_levels, use_cache) in OpenStreetMapX at /home/.julia/packages/OpenStreetMapX/lK8gq/src/parseMap.jl:82

I’m using Julia 1.0.2. That might be the issue. In this case, I think I will need to install Julia 1.0.3, right?

No. It does not work for Julia version 1.0.3 either. This is strange.

  | | |_| | | | (_| |  |  Version 1.0.3 (2018-12-18)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

[ Info: Recompiling stale cache file /home/.julia/compiled/v1.0/OpenStreetMapX/rxMhI.ji for OpenStreetMapX [5c67c38e-c187-11e8-2be6-e3a6a3a5610f]
julia> using Pkg

julia> Pkg.installed()
Dict{String,Union{Nothing, VersionNumber}} with 7 entries:
  "Juno"               => v"0.5.3"
  "OpenStreetMapX"     => v"0.1.1"
  "IJulia"             => v"1.14.1"
  "Plots"              => v"0.22.5"
  "Atom"               => v"0.7.12"
  "PyCall"             => v"1.18.5"
  "OpenStreetMapXPlot" => v"0.1.0"

julia> m = OpenStreetMapX.get_map_data("/home/devel/Desktop/sweden.osm")
ERROR: MethodError: no method matching get_map_data(::String)
Closest candidates are:
  get_map_data(::String, ::String; road_levels, use_cache) at /home/.julia/packages/OpenStreetMapX/lK8gq/src/parseMap.jl:82
Stacktrace:
 [1] top-level scope at none:0

I’m using Linux Ubuntu.

Generally, the error stack provide some good info on the error.

Closest candidates are:
  get_map_data(::String, ::String; road_levels, use_cache)

So it suggesting that it need to take 2 strings as input. And going to the manual:
get_map_data

It needs the path and filename in 2 separate strings.

So probably something like this

m = OpenStreetMapX.get_map_data("/home/devel/Desktop","sweden.osm")
1 Like

What are the programming tools to use to combine them into a movie?

However, there is one thing that the stack trace does not show this time.

I have registered OpenStreetMapX as an official Julia package. In the registration process I was forced to change package ID to the one assigned in the registration process (package id in the form d3d4fdd0-c191-11e8-3358-a3629b56487d). Now I am getting feedback from people who have problem updating OpenStreetMapX.

I propose to remove the package and then install it again (maybe there is a more elegant solution but I do not know it):
Press ] to go to the package manager:


(v1.0) pkg> rm OpenStreetMapXPlot

(v1.0) pkg> rm OpenStreetMapX

(v1.0) pkg> add OpenStreetMapX

(v1.0) pkg> add https://github.com/pszufe/OpenStreetMapXPlot.jl

Now you should be able to work with the new API (that contains get_map_data(::String) function)

1 Like

Regarding the animation follow the steps

  1. Use Plots.jl GR.jl backend (this is the default in OpenStreetMapXPlot) because despite of long compilation time it has very fast rendering
  2. Plots.jl has the function savefig() for rendering output to file (https://docs.juliaplots.org/latest/output/)
  3. There is lots of software that is able to combine frame images, several years ago I have used ffmpeg and got excellent results (for example see this StackOverflow post)
1 Like

Perhaps you can use @animate or @gif to create animations more easily? Documentation here, and example code and resulting animation here.

1 Like