Skip to content

Commit

Permalink
Add set_lightosm_defaults function to edit fallback values
Browse files Browse the repository at this point in the history
  • Loading branch information
jarodlam authored and captchanjack committed Aug 26, 2022
1 parent 9b46fc5 commit 7ae7423
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 72 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 <[email protected]>"]
version = "0.2.4"
version = "0.2.5"

[deps]
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Expand Down
5 changes: 5 additions & 0 deletions docs/src/defaults.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Default Values

```@docs
LightOSM.set_defaults
```
1 change: 1 addition & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Pages = [
"create_buildings.md",
"geolocation.md"
"graph_utilities.md"
"defaults.md"
]
```

Expand Down
6 changes: 3 additions & 3 deletions src/buildings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,12 @@ function height(tags::Dict)::Number
return height isa String ? max([remove_non_numeric(h) for h in split(height, r"[+^;,-]")]...) : height
elseif levels !== nothing
levels = levels isa String ? round(max([remove_non_numeric(l) for l in split(levels, r"[+^;,-]")]...)) : levels
levels = levels == 0 ? rand(1:DEFAULT_MAX_BUILDING_LEVELS) : levels
levels = levels == 0 ? rand(1:DEFAULT_MAX_BUILDING_LEVELS[]) : levels
else
levels = rand(1:DEFAULT_MAX_BUILDING_LEVELS)
levels = rand(1:DEFAULT_MAX_BUILDING_LEVELS[])
end

return levels * DEFAULT_BUILDING_HEIGHT_PER_LEVEL
return levels * DEFAULT_BUILDING_HEIGHT_PER_LEVEL[]
end

function parse_osm_buildings_dict(osm_buildings_dict::AbstractDict)::Dict{Integer,Building}
Expand Down
113 changes: 95 additions & 18 deletions src/constants.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
"""
Default data types used to construct OSMGraph object.
"""
const DEFAULT_OSM_ID_TYPE = Int64
const DEFAULT_OSM_INDEX_TYPE = Int32
const DEFAULT_OSM_EDGE_WEIGHT_TYPE = Float64
const DEFAULT_OSM_MAXSPEED_TYPE = Int16
const DEFAULT_OSM_LANES_TYPE = Int8

"""
Approximate radius of the Earth (km) used in geoemetry functions.
"""
Expand Down Expand Up @@ -133,7 +142,7 @@ const OSM_DOWNLOAD_FORMAT = Dict(
"""
Default maxspeed based on highway type.
"""
const DEFAULT_MAXSPEEDS = Dict(
const DEFAULT_MAXSPEEDS = Ref(Dict{String,DEFAULT_OSM_MAXSPEED_TYPE}(
"motorway" => 100,
"trunk" => 100,
"primary" => 100,
Expand All @@ -142,12 +151,12 @@ const DEFAULT_MAXSPEEDS = Dict(
"unclassified" => 50,
"residential" => 50,
"other" => 50
)
))

"""
Default number of lanes based on highway type.
"""
const DEFAULT_LANES = Dict(
const DEFAULT_LANES = Ref(Dict{String,DEFAULT_OSM_LANES_TYPE}(
"motorway" => 3,
"trunk" => 3,
"primary" => 2,
Expand All @@ -156,7 +165,7 @@ const DEFAULT_LANES = Dict(
"unclassified" => 1,
"residential" => 1,
"other" => 1
)
))

"""
Default oneway attribute based on highway type.
Expand Down Expand Up @@ -186,33 +195,101 @@ const ONEWAY_FALSE = Set(["false", "no", "0", 0])
"""
Default factor applied to maxspeed when the `lane_efficiency` weight is used to contruct OSMGraph object.
"""
const LANE_EFFICIENCY = Dict(
const LANE_EFFICIENCY = Ref(Dict{DEFAULT_OSM_LANES_TYPE,DEFAULT_OSM_EDGE_WEIGHT_TYPE}(
1 => 0.7,
2 => 0.8,
3 => 0.9,
4 => 1.0
)

"""
Default data types used to construct OSMGraph object.
"""
const DEFAULT_OSM_ID_TYPE = Int64
const DEFAULT_OSM_INDEX_TYPE = Int32
const DEFAULT_OSM_EDGE_WEIGHT_TYPE = Float64
const DEFAULT_OSM_MAXSPEED_TYPE = Int16
const DEFAULT_OSM_LANES_TYPE = Int8
))

"""
Default height of buildings in metres.
"""
const DEFAULT_BUILDING_HEIGHT_PER_LEVEL = 4
const DEFAULT_BUILDING_HEIGHT_PER_LEVEL = Ref{Float64}(4)

"""
Default maximum levels of buildings.
"""
const DEFAULT_MAX_BUILDING_LEVELS = 3
const DEFAULT_MAX_BUILDING_LEVELS = Ref{Int}(3)

"""
Delimiters used to clean maxspeed and lanes data.
"""
const COMMON_OSM_STRING_DELIMITERS = r"[+^:;,|-]"
const COMMON_OSM_STRING_DELIMITERS = r"[+^:;,|-]"

"""
LightOSM.set_defaults(kwargs...)
Sets default values that LightOSM uses when generating the graph. All arguments are
optional.
# Keyword Arguments
- `maxspeeds::AbstractDict{String,<:Real}`: If no `maxspeed` way tag is available, these
values are used instead based on the value of the `highway` way tag. If no
`highway` way tag is available, the value for `"other"` is used. Unit is km/h.
Default value:
```julia
Dict(
"motorway" => 100,
"trunk" => 100,
"primary" => 100,
"secondary" => 100,
"tertiary" => 50,
"unclassified" => 50,
"residential" => 50,
"other" => 50
)
```
- `lanes::AbstractDict{String,<:Integer}`: If no `lanes` way tag is available, these
values are used instead based on the value of the `highway` way tag. If no
`highway` way tag is available, the value for `"other"` is used.
Default value:
```julia
Dict(
"motorway" => 3,
"trunk" => 3,
"primary" => 2,
"secondary" => 2,
"tertiary" => 1,
"unclassified" => 1,
"residential" => 1,
"other" => 1
)
```
- `lane_efficiency::AbstractDict{<:Integer,<:Real}`: Gives the lane efficiency based on
number of lanes. `1.0` is used for any number of lanes not specified here.
Default value:
```julia
LANE_EFFICIENCY = Dict(
1 => 0.7,
2 => 0.8,
3 => 0.9,
4 => 1.0
)
```
- `building_height_per_level::Integer`: If the `height` building tag is not available,
it is calculated by multiplying this value by the number of levels from the
`building:levels` tag. Unit is metres. Default value:
```julia
4
```
- `max_building_levels::Integer`: If the `building:levels` tag is not available, a number
is randomly chosen between 1 and this value. Default value:
```julia
3
```
"""
function set_defaults(;
maxspeeds::AbstractDict{String,<:Real}=DEFAULT_MAXSPEEDS[],
lanes::AbstractDict{String,<:Integer}=DEFAULT_LANES[],
lane_efficiency::AbstractDict{<:Integer,<:Real}=LANE_EFFICIENCY[],
building_height_per_level::Real=DEFAULT_BUILDING_HEIGHT_PER_LEVEL[],
max_building_levels::Integer=DEFAULT_MAX_BUILDING_LEVELS[]
)
DEFAULT_MAXSPEEDS[] = maxspeeds
DEFAULT_LANES[] = lanes
LANE_EFFICIENCY[] = lane_efficiency
DEFAULT_BUILDING_HEIGHT_PER_LEVEL[] = building_height_per_level
DEFAULT_MAX_BUILDING_LEVELS[] = max_building_levels
return
end
30 changes: 21 additions & 9 deletions src/graph.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,30 @@
largest_connected_component::Bool=true
)::OSMGraph
Creates an `OSMGraph` object from download OpenStreetMap network data, use with `download_osm_network`.
Creates an `OSMGraph` object from download OpenStreetMap network data, use with
`download_osm_network`.
# 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`, `: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 `Graphs.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.
- `largest_connected_component::Bool=true`: Set true to keep only the largest connected components in the network.
- `osm_data_object::Union{XMLDocument,Dict}`: OpenStreetMap network data parsed as either
`XMLDocument` or `Dict` object depending on the download method. *NOTE* if you pass in
a `Dict`, the object will be modified to add missing tag information.
- `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 `Graphs.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.
- `largest_connected_component::Bool=true`: Set true to keep only the largest connected
components in the network.
# Return
- `OSMGraph`: Container for storing OpenStreetMap node, way, relation and graph related obejcts.
- `OSMGraph`: Container for storing OpenStreetMap node-, way-, relation- and graph-related
obejcts.
"""
function graph_from_object(osm_data_object::Union{XMLDocument,Dict};
network_type::Symbol=:drive,
Expand Down Expand Up @@ -353,7 +365,7 @@ function add_weights!(g::OSMGraph, weight_type::Symbol=:distance)
weight = dist / maxspeed
else
lanes = g.ways[highway].tags["lanes"]::DEFAULT_OSM_LANES_TYPE
lane_efficiency = get(LANE_EFFICIENCY, lanes, 1.0)
lane_efficiency = get(LANE_EFFICIENCY[], lanes, 1.0)
weight = dist / (maxspeed * lane_efficiency)
end
else
Expand Down
20 changes: 10 additions & 10 deletions src/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ function maxspeed(tags::AbstractDict)::DEFAULT_OSM_MAXSPEED_TYPE
end
else
highway_type = get(tags, "highway", "other")
key = getkey(DEFAULT_MAXSPEEDS, highway_type, "other")
return U(DEFAULT_MAXSPEEDS[key])
key = getkey(DEFAULT_MAXSPEEDS[], highway_type, "other")
return U(DEFAULT_MAXSPEEDS[][key])
end
end

Expand All @@ -55,8 +55,8 @@ function lanes(tags::AbstractDict)::DEFAULT_OSM_LANES_TYPE
end
else
highway_type = get(tags, "highway", "other")
key = getkey(DEFAULT_LANES, highway_type, "other")
return U(DEFAULT_LANES[key])
key = getkey(DEFAULT_LANES[], highway_type, "other")
return U(DEFAULT_LANES[][key])
end
end

Expand Down Expand Up @@ -217,12 +217,12 @@ function parse_osm_network_dict(osm_network_dict::AbstractDict, network_type::Sy
id = way["id"]
ways[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["rail_type"] = get(tags, "railway", "unknown")
tags["electrified"] = get(tags, "electrified", "unknown")
tags["gauge"] = get(tags, "gauge", nothing)
tags["usage"] = get(tags, "usage", "unknown")
tags["name"] = get(tags, "name", "unknown")
tags["lanes"] = get(tags, "tracks", 1)
tags["maxspeed"] = maxspeed(tags)
tags["oneway"] = is_oneway(tags)
tags["reverseway"] = is_reverseway(tags)
Expand Down
Loading

2 comments on commit 7ae7423

@captchanjack
Copy link
Collaborator

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/67126

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.2.5 -m "<description of version>" 7ae74237114f9eaadc8bd737d7d41862f0f3aef3
git push origin v0.2.5

Please sign in to comment.