Skip to content

Commit

Permalink
Merge pull request #19 from DeloitteDigitalAPAC/feature/add-rail-netw…
Browse files Browse the repository at this point in the history
…ork-type

Add network_type=:rail
  • Loading branch information
captchanjack committed Apr 16, 2021
2 parents 9571abc + 8c197b0 commit e215459
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "LightOSM"
uuid = "d1922b25-af4e-4ba3-84af-fe9bea896051"
authors = ["Jack Chan <jchan2@deloitte.com.au>"]
version = "0.1.7"
version = "0.1.8"

[deps]
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Expand Down
18 changes: 14 additions & 4 deletions src/constants.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ const WAY_EXCLUSION_FILTERS = Dict(
"area" => ["yes"],
"highway" => ["proposed", "construction", "abandoned", "platform", "raceway"]
),
:none => Dict{AbstractString,Vector{AbstractString}}()
:none => Dict{AbstractString,Vector{AbstractString}}(),
:rail => Dict("highway" => ["proposed", "platform"])
)

"""
Expand All @@ -96,14 +97,23 @@ const WAY_FILTERS_QUERY = Dict(
:bike => """["highway"]$(concatenate_exclusions(WAY_EXCLUSION_FILTERS[:bike]))""",
:all => """["highway"]$(concatenate_exclusions(WAY_EXCLUSION_FILTERS[:all]))""",
:all_private => """["highway"]$(concatenate_exclusions(WAY_EXCLUSION_FILTERS[:all_private]))""",
:none => """["highway"]$(concatenate_exclusions(WAY_EXCLUSION_FILTERS[:none]))"""
:none => """["highway"]$(concatenate_exclusions(WAY_EXCLUSION_FILTERS[:none]))""",
:rail => """["railway"]$(concatenate_exclusions(WAY_EXCLUSION_FILTERS[:rail]))"""
)

"""
OpenStreetMap query strings used for turn restrictions, ignores ["restriction:conditional"] and ["restriction:hgv"].
OpenStreetMap query strings used for getting relation data in addition to nodes and ways that are contained within.
"""
const RELATION_FILTERS_QUERY = Dict(
:restriction => """["type"="restriction"]["restriction"][!"conditional"][!"hgv"]"""
:drive_mainroads => """["type"="restriction"]["restriction"][!"conditional"][!"hgv"]""",
:drive => """["type"="restriction"]["restriction"][!"conditional"][!"hgv"]""",
:drive_service => """["type"="restriction"]["restriction"][!"conditional"][!"hgv"]""",
:walk => nothing,
:bike => nothing,
:all => """["type"="restriction"]["restriction"][!"conditional"][!"hgv"]""",
:all_private => """["type"="restriction"]["restriction"][!"conditional"][!"hgv"]""",
:none => nothing,
:rail => nothing
)

"""
Expand Down
39 changes: 24 additions & 15 deletions src/download.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ end
bbox::Union{Vector{AbstractFloat},Nothing}=nothing
)::String
Forms an Overpass query string.
Forms an Overpass query string. For a guide on the OSM query language, see https://wiki.openstreetmap.org/wiki/Overpass_API/Language_Guide.
# Arguments
- `filters::String`: Filters for the query, e.g. polygon filter, highways only, traffic lights only, etc.
Expand All @@ -88,7 +88,9 @@ function overpass_query(filters::String,
download_format_str = """[out:$(OSM_DOWNLOAD_FORMAT[download_format])]"""
bbox_str = bbox === nothing ? "" : """[bbox:$(replace("$bbox", r"[\[ \]]" => ""))]"""
metadata_str = metadata ? "meta" : ""
return """$download_format_str[timeout:180]$bbox_str;($filters);out count;out $metadata_str;"""
query = """$download_format_str[timeout:180]$bbox_str;($filters);out count;out $metadata_str;"""
@debug """Making overpass query: $query"""
return query
end

"""
Expand All @@ -102,7 +104,7 @@ Forms an Overpass query string using geojosn polygon coordinates as a filter.
# Arguments
- `geojson_polygons::Vector{Vector{Any}}`: Vector of `[lat, lon, ...]` polygon coordinates.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`, `:rail`.
- `metadata::Bool=false`: Set true to return metadata.
- `download_format::Symbol=:osm`: Download format, either `:osm`, `:xml` or `json`.
Expand All @@ -115,13 +117,16 @@ function overpass_polygon_network_query(geojson_polygons::AbstractVector{<:Abstr
download_format::Symbol=:osm
)::String
way_filter = WAY_FILTERS_QUERY[network_type]
relation_filter = RELATION_FILTERS_QUERY[:restriction]
relation_filter = RELATION_FILTERS_QUERY[network_type]

filters = ""
for polygon in geojson_polygons
polygon = map(x -> [x[2], x[1]], polygon) # switch lon-lat to lat-lon
polygon_str = replace("$polygon", r"[\[,\]]" => "")
filters *= """way$way_filter(poly:"$polygon_str");>;rel$relation_filter(poly:"$polygon_str");>;"""
filters *= """way$way_filter(poly:"$polygon_str");>;"""
if !isnothing(relation_filter)
filters *= """rel$relation_filter(poly:"$polygon_str");>;"""
end
end

return overpass_query(filters, metadata, download_format)
Expand Down Expand Up @@ -166,7 +171,7 @@ Downloads an OpenStreetMap network using any place name string.
# Arguments
- `place_name::String`: Any place name string used as a search argument to the Nominatim API.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`, `:rail`.
- `metadata::Bool=false`: Set true to return metadata.
- `download_format::Symbol=:osm`: Download format, either `:osm`, `:xml` or `json`.
Expand Down Expand Up @@ -194,7 +199,7 @@ Downloads an OpenStreetMap network using a polygon.
# Arguments
- `polygon::AbstractVector`: Vector of longitude-latitude pairs.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`, `:rail`.
- `metadata::Bool=false`: Set true to return metadata.
- `download_format::Symbol=:osm`: Download format, either `:osm`, `:xml` or `json`.
Expand All @@ -207,7 +212,7 @@ function osm_network_from_polygon(;polygon::AbstractVector{<:AbstractVector{<:Re
download_format::Symbol=:osm
)::String
query = overpass_polygon_network_query([polygon], network_type, metadata, download_format)
return overpass_request(query)
return overpass_request(query)
end

"""
Expand All @@ -221,7 +226,7 @@ Forms an Overpass query string using a bounding box as a filter.
# Arguments
- `bbox::Vector{AbstractFloat}`: Vector of bounding box coordinates `[minlat, minlon, maxlat, maxlon]`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`, `:rail`.
- `metadata::Bool=false`: Set true to return metadata.
- `download_format::Symbol=:osm`: Download format, either `:osm`, `:xml` or `json`.
Expand All @@ -234,8 +239,11 @@ function overpass_bbox_network_query(bbox::Vector{<:AbstractFloat},
download_format::Symbol=:osm
)::String
way_filter = WAY_FILTERS_QUERY[network_type]
relation_filter = RELATION_FILTERS_QUERY[:restriction]
filters = "way$way_filter;>;rel$relation_filter;>;"
relation_filter = RELATION_FILTERS_QUERY[network_type]
filters = "way$way_filter;>;"
if !isnothing(relation_filter)
filters *= """rel$relation_filter(poly:"$polygon_str");>;"""
end
return overpass_query(filters, metadata, download_format, bbox)
end

Expand All @@ -256,7 +264,7 @@ Downloads an OpenStreetMap network using bounding box coordinates.
- `minlon::AbstractFloat`: Bottom left bounding box longitude coordinate.
- `maxlat::AbstractFloat`: Top right bounding box latitude coordinate.
- `maxlon::AbstractFloat`: Top right bounding box longitude coordinate.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`, `:rail`.
- `metadata::Bool=false`: Set true to return metadata.
- `download_format::Symbol=:osm`: Download format, either `:osm`, `:xml` or `json`.
Expand Down Expand Up @@ -288,7 +296,7 @@ Downloads an OpenStreetMap network using bounding box coordinates calculated fro
# Arguments
- `point::GeoLocation`: Centroid point to draw the bounding box around.
- `radius::Number`: Distance (km) from centroid point to each bounding box corner.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`, `:rail`.
- `metadata::Bool=false`: Set true to return metadata.
- `download_format::Symbol=:osm`: Download format, either `:osm`, `:xml` or `json`.
Expand Down Expand Up @@ -335,12 +343,12 @@ Downloads an OpenStreetMap network by querying with a place name, bounding box,
# Arguments
- `download_method::Symbol`: Download method, choose from `:place_name`, `:bounding_box` or `:point`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`, `:rail`
- `metadata::Bool=false`: Set true to return metadata.
- `download_format::Symbol=:osm`: Download format, either `:osm`, `:xml` or `json`.
- `save_to_file_location::Union{String,Nothing}=nothing`: Specify a file location to save downloaded data to disk.
# Required Download Kwargs
# Required kwargs each Download Method
*`download_method=:place_name`*
- `place_name::String`: Any place name string used as a search argument to the Nominatim API.
Expand All @@ -366,6 +374,7 @@ Downloads an OpenStreetMap network by querying with a place name, bounding box,
- `:all`: All motorways, walkways and cycleways excluding private ways.
- `:all_private`: All motorways, walkways and cycleways including private ways.
- `:none`: No network filters.
- `:rail`: Railways excluding proposed and platform.
# Return
- `Union{XMLDocument,Dict{String,Any}}`: OpenStreetMap network data parsed as either XML or Dictionary object depending on the download method.
Expand Down
9 changes: 5 additions & 4 deletions src/graph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Creates an `OSMGraph` object from download OpenStreetMap network data, use with
# Arguments
- `osm_data_object::Symbol`: OpenStreetMap network data parsed as either XML or Dictionary object depending on the download method.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`, must match the network type used to download `osm_data_object`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`, `:rail`, must match the network type used to download `osm_data_object`.
- `weight_type::Symbol=:time`: Weight type for graph edges, pick from `:distance` (km), `:time` (hours), `:lane_efficiency` (time scaled by number of lanes).
- `graph_type::Symbol=:static`: Type of `LightGraphs.AbstractGraph`, pick from `:static` (StaticDiGraph), `:light` (DiGraph), `:simple_weighted` (SimpleWeightedDiGraph), `:meta` (MetaDiGraph).
- `precompute_dijkstra_states::Bool=false`: Set true to precompute dijkstra parent states for every source node in the graph, *NOTE* this may take a while and may not be possible for graphs with large amount of nodes due to memory limits.
Expand Down Expand Up @@ -61,7 +61,7 @@ Creates an `OSMGraph` object from a downloaded OpenStreetMap network data file,
# Arguments
- `file_path::String`: OpenStreetMap network data file location.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`, must match the network type used to download `osm_data_object`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`, `:rail`, must match the network type used to download `osm_data_object`.
- `weight_type::Symbol=:time`: Weight type for graph edges, pick from `:distance` (km), `:time` (hours), `:lane_efficiency` (time scaled by number of lanes).
- `graph_type::Symbol=:static`: Type of `LightGraphs.AbstractGraph`, pick from `:static` (StaticDiGraph), `:light` (DiGraph), `:simple_weighted` (SimpleWeightedDiGraph), `:meta` (MetaDiGraph).
- `precompute_dijkstra_states::Bool=false`: Set true to precompute dijkstra parent states for every source node in the graph, *NOTE* this may take a while and may not be possible for graphs with large amount of nodes due to memory limits.
Expand Down Expand Up @@ -106,7 +106,7 @@ Downloads OpenStreetMap network data and creates an `OSMGraph` object.
# Arguments
- `download_method::Symbol`: Download method, choose from `:place_name`, `:bounding_box` or `:point`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`.
- `network_type::Symbol=:drive`: Network type filter, pick from `:drive`, `:drive_service`, `:walk`, `:bike`, `:all`, `:all_private`, `:none`, `:rail`.
- `metadata::Bool=false`: Set true to return metadata.
- `download_format::Symbol=:osm`: Download format, either `:osm`, `:xml` or `json`.
- `save_to_file_location::Union{String,Nothing}=nothing`: Specify a file location to save downloaded data to disk.
Expand All @@ -115,7 +115,7 @@ Downloads OpenStreetMap network data and creates an `OSMGraph` object.
- `precompute_dijkstra_states::Bool=false`: Set true to precompute dijkstra parent states for every source node in the graph, *NOTE* this may take a while and may not be possible for graphs with large amount of nodes due to memory limits.
- `largest_connected_component::Bool=true`: Set true to keep only the largest connected components in the network.
# Required Download Kwargs
# Required kwargs each Download Method
*`download_method=:place_name`*
- `place_name::String`: Any place name string used as a search argument to the Nominatim API.
Expand All @@ -141,6 +141,7 @@ Downloads OpenStreetMap network data and creates an `OSMGraph` object.
- `:all`: All motorways, walkways and cycleways excluding private ways.
- `:all_private`: All motorways, walkways and cycleways including private ways.
- `:none`: No network filters.
- `:rail`: Railways excluding proposed and platform.
# Return
- `OSMGraph`: Container for storing OpenStreetMap node, way, relation and graph related obejcts.
Expand Down
21 changes: 20 additions & 1 deletion src/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,11 @@ Determine if way is of highway type given osm way tags dictionary.
"""
is_highway(tags::AbstractDict)::Bool = haskey(tags, "highway") ? true : false

"""
Determine if way is of railway type given osm way tags dictionary.
"""
is_railway(tags::AbstractDict)::Bool = haskey(tags, "railway") ? true : false

"""
Determine if way matches the specified network type.
"""
Expand Down Expand Up @@ -211,6 +216,20 @@ function parse_osm_network_dict(osm_network_dict::AbstractDict, network_type::Sy
union!(highway_nodes, nds)
id = way["id"]
highways[id] = Way(id, nds, tags)
elseif is_railway(tags) && matches_network_type(tags, network_type)
tags["rail_type"] = haskey(tags,"railway") ? tags["railway"] : "unknown"
tags["electrified"] = haskey(tags,"electrified") ? tags["electrified"] : "unknown"
tags["gauge"] = haskey(tags,"gauge") ? tags["gauge"] : nothing
tags["usage"] = haskey(tags,"usage") ? tags["usage"] : "unknown"
tags["name"] = haskey(tags,"name") ? tags["name"] : "unknown"
tags["lanes"] = haskey(tags,"tracks") ? tags["tracks"] : 1
tags["maxspeed"] = maxspeed(tags)
tags["oneway"] = is_oneway(tags)
tags["reverseway"] = is_reverseway(tags)
nds = way["nodes"]
union!(highway_nodes, nds)
id = way["id"]
highways[id] = Way(id, nds, tags)
end
end
end
Expand All @@ -228,7 +247,7 @@ function parse_osm_network_dict(osm_network_dict::AbstractDict, network_type::Sy
end

restrictions = Dict{T,Restriction{T}}()
if network_type != :walk && network_type != :bike
if haskey(osm_network_dict, "relation")
for relation in osm_network_dict["relation"]
if haskey(relation, "tags") && haskey(relation, "members")
tags = relation["tags"]
Expand Down

2 comments on commit e215459

@captchanjack
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/34447

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.1.8 -m "<description of version>" e2154590a9561051181ca788d6590106ef85ec2c
git push origin v0.1.8

Please sign in to comment.