diff --git a/Project.toml b/Project.toml index 79b2893..0ae9dcc 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "OpenStreetMapX" uuid = "86cd37e6-c0ff-550b-95fe-21d72c8d4fc9" authors = ["Przemyslaw Szufel ", "Bartosz Pankratz ", "Anna Szczurek ", "Bogumil Kaminski ", "Pawel Pralat "] -version = "0.1.12" +version = "0.1.13" [deps] DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" diff --git a/docs/Project.toml b/docs/Project.toml index dfa65cd..038a97f 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,2 +1,3 @@ [deps] Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +OpenStreetMapX = "86cd37e6-c0ff-550b-95fe-21d72c8d4fc9" diff --git a/docs/make.jl b/docs/make.jl index 0e41e21..95c3ab7 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -1,4 +1,6 @@ using Documenter +using Pkg + try using OpenStreetMapX catch diff --git a/docs/src/reference.md b/docs/src/reference.md index 8ed4cfb..3d8fe80 100644 --- a/docs/src/reference.md +++ b/docs/src/reference.md @@ -25,6 +25,7 @@ Bounds center inbounds onbounds +latlon ``` diff --git a/samples/plotting_with_folium.jl b/samples/plotting_with_folium.jl new file mode 100644 index 0000000..89fb606 --- /dev/null +++ b/samples/plotting_with_folium.jl @@ -0,0 +1,59 @@ +using OpenStreetMapX, LightGraphs, PyCall + +# This code assumes that folium has benn installed + + +function plot_map(m::MapData, filename::AbstractString; tiles="Stamen Toner" ) + MAP_BOUNDS = [ ( m.bounds.min_y, m.bounds.min_x), ( m.bounds.max_y, m.bounds.max_x) ] + flm = pyimport("folium") + m_plot = flm.Map(tiles=tiles) + for e in edges(m.g) + info = "Edge from: $(e.src) to $(e.dst)
[information from the
.e
and
.w
fields] " + flm.PolyLine( (latlon(m,e.src), latlon(m,e.dst)), + color="brown", weight=4, opacity=1).add_to(m_plot) + end + + for n in keys(m.nodes) + lla = LLA(m.nodes[n],m.bounds) + info = "Node: $(n)\n
Lattitude: $(lla.lat)\n
Longitude: $(lla.lon)
[information from the
.node
field] " + flm.Circle( + (lla.lat, lla.lon), + popup=info, + tooltip=info, + radius=10, + color="orange", + weight=3, + fill=true, + fill_color="orange" + ).add_to(m_plot) + end + + for nn in keys(m.n) + n = m.n[nn] + lla = LLA(m.nodes[n],m.bounds) + info = "Graph: $nn
Node: $(n)\n
Lattitude: $(lla.lat)\n
Longitude: $(lla.lon)
+ [The node identifiers are hold in the
.n
field and location in the
.nodes
field]" + flm.Rectangle( + [(lla.lat-0.00014, lla.lon-0.0002), (lla.lat+0.00014, lla.lon+0.0002)], + popup=info, + tooltip=info, + color="green", + weight=1.5, + fill=false, + fill_opacity=0.2, + fill_color="green", + ).add_to(m_plot) + end + + + MAP_BOUNDS = [( m.bounds.min_y, m.bounds.min_x),( m.bounds.max_y, m.bounds.max_x)] + flm.Rectangle(MAP_BOUNDS, color="black",weight=4).add_to(m_plot) + m_plot.fit_bounds(MAP_BOUNDS) + m_plot.save(filename) +end + +pth = joinpath(dirname(pathof(OpenStreetMapX)),"..","test","data","reno_east3.osm") + +m2 = OpenStreetMapX.get_map_data(pth,use_cache = false, trim_to_connected_graph=true); + +plot_map(m2, "mymap.html") diff --git a/samples/routing.jl b/samples/routing.jl index 3accb1d..08dc800 100644 --- a/samples/routing.jl +++ b/samples/routing.jl @@ -1,8 +1,8 @@ using OpenStreetMapX -mapfile = "reno_east3.osm"; # This file can be found in test/data folder -datapath = "/home/ubuntu/"; -map_data = get_map_data(datapath, mapfile,use_cache=false); + +pth = joinpath(dirname(pathof(OpenStreetMapX)),"..","test","data","reno_east3.osm") +map_data = OpenStreetMapX.get_map_data(pth,use_cache = false); using Random Random.seed!(0); @@ -21,7 +21,7 @@ println("fastest route nodes: ",fastest_route1) ### Create this file if you want to test routing with Google API ### The file should only contain your Google API key -google_api_file = joinpath(datapath,"googleapi.key") +google_api_file = joinpath("some_folder","googleapi.key") if isfile(google_api_file) google_api_key = readlines(google_api_file)[1] diff --git a/src/OpenStreetMapX.jl b/src/OpenStreetMapX.jl index e97489d..3d8fc0a 100644 --- a/src/OpenStreetMapX.jl +++ b/src/OpenStreetMapX.jl @@ -33,9 +33,12 @@ export get_google_route export encode, decode export generate_point_in_bounds, point_to_nodes +export latlon + export ROAD_CLASSES, CYCLE_CLASSES, PED_CLASSES, SPEED_ROADS_URBAN, SPEED_ROADS_RURAL + include("types.jl") #types used in the package include("classes.jl") #grouping highways into classes for routing and plotting include("speeds.jl") # speed limits in kilometers per hour diff --git a/src/conversion.jl b/src/conversion.jl index 726890f..74a834b 100644 --- a/src/conversion.jl +++ b/src/conversion.jl @@ -228,3 +228,15 @@ Converts a dictionary of `ENU` `nodes` into a dictionary of `LLA` values. Uses the center of the given `bounds` for linearization. """ LLA(nodes::Dict{Int,ENU}, bounds::Bounds{LLA}, datum::OpenStreetMapX.Ellipsoid = OpenStreetMapX.WGS84) = LLA(nodes, OpenStreetMapX.center(bounds), datum) + +""" + latlon(m::MapData,map_g_point_id::Int64)::Tuple{Float64, Float64} + +Returns a tuple of lattitute and longitude for a given graph node identifier +`map_g_point_id` in graph `m.g` (i.e. `map_g_point_id ∈ 1:nv(m.g)`). +""" +function latlon(m::MapData,map_g_point_id::Int64)::Tuple{Float64, Float64} + osm_node_ix = m.n[map_g_point_id] + lla = LLA(m.nodes[osm_node_ix], m.bounds) + return (lla.lat, lla.lon) +end diff --git a/src/intersections.jl b/src/intersections.jl index eab4d5f..6b5801f 100644 --- a/src/intersections.jl +++ b/src/intersections.jl @@ -2,8 +2,10 @@ ### Auxiliary Functions ### ########################### -### Check if Way is One - Way ### +""" +Check if Way is One - Way +""" function oneway(w::OpenStreetMapX.Way) v = get(w.tags,"oneway", "") if v == "false" || v == "no" || v == "0" @@ -16,12 +18,15 @@ function oneway(w::OpenStreetMapX.Way) return (highway == "motorway" || highway == "motorway_link" || junction == "roundabout") end -### Check if Way is Reverse ### +""" +Check if Way is Reverse +""" reverseway(w::OpenStreetMapX.Way) = (get(w.tags,"oneway", "") == "-1") -### Compute the distance of a route ### - +""" +Compute the distance of a route for some `nodes` data +""" function distance(nodes::Dict{Int,T}, route::Vector{Int}) where T<:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF}) if length(route) == 0 return Inf @@ -29,10 +34,9 @@ function distance(nodes::Dict{Int,T}, route::Vector{Int}) where T<:(Union{OpenSt dist = sum(distance(nodes[route[i-1]],nodes[route[i]]) for i = 2:length(route)) end -###################################### -### Find Intersections of Highways ### -###################################### - +""" +Find Intersections of Highways ### +""" function find_intersections(highways::Vector{OpenStreetMapX.Way}) seen = Set{Int}() intersections = Dict{Int,Set{Int}}() @@ -55,10 +59,9 @@ function find_intersections(highways::Vector{OpenStreetMapX.Way}) return intersections end -################################# -### Find Segments of Highways ### -################################# - +""" +Find Segments of Highways ### +""" function find_segments(nodes::Dict{Int,T}, highways::Vector{OpenStreetMapX.Way}, intersections::Dict{Int,Set{Int}}) where T<:Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF} segments = OpenStreetMapX.Segment[] intersect = Set(keys(intersections)) @@ -82,4 +85,4 @@ function find_segments(nodes::Dict{Int,T}, highways::Vector{OpenStreetMapX.Way}, end end return segments -end \ No newline at end of file +end diff --git a/src/nodes.jl b/src/nodes.jl index 6d279e2..c4f3b48 100644 --- a/src/nodes.jl +++ b/src/nodes.jl @@ -1,7 +1,6 @@ -###################### -### Add a New Node ### -###################### - +""" +Add a New Node +""" function add_new_node!(nodes::Dict{Int,T},loc::T, start_id::Int = reinterpret((Int), hash(loc))) where T <: (Union{OpenStreetMapX.LLA,OpenStreetMapX.ENU}) id = start_id while id <= typemax(Int) @@ -16,12 +15,11 @@ function add_new_node!(nodes::Dict{Int,T},loc::T, start_id::Int = reinterpret((I throw(error(msg)) end -############################# -### Find the Nearest Node ### -############################# -### Find the nearest node to a given location ### +""" +Find the nearest node to a given location `loc` +""" function nearest_node(nodes::Dict{Int,T}, loc::T) where T<:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF}) min_dist = Inf best_ind = 0 @@ -37,12 +35,16 @@ function nearest_node(nodes::Dict{Int,T}, loc::T) where T<:(Union{OpenStreetMapX return best_ind end +""" +Find the nearest node to a given location `loc` +""" function nearest_node(m::MapData, loc::ENU, vs_only::Bool=true) vs_only ? nearest_node(m.nodes,loc, keys(m.v)) : nearest_node(m.nodes,loc) end - -### Find nearest node in a list of nodes ### +""" +Find the nearest node in a list of nodes +""" function nearest_node(nodes::Dict{Int,T}, loc::T, node_list::AbstractSet{Int}) where T<:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF}) min_dist = Inf best_ind = 0 @@ -64,11 +66,9 @@ end #nearest_node(loc::T, m::OpenStreetMapX.MapData) where T<:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF}) = OpenStreetMapX.nearest_node(m.nodes,loc,collect(keys(m.v))) -############################# -### Find Node Within Range### -############################# - -### Find all nodes within range of a location ### +""" +Find all nodes within range of a location +""" function nodes_within_range(nodes::Dict{Int,T}, loc::T, range::Float64 = Inf) where T<:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF}) if range == Inf return keys(nodes) @@ -83,7 +83,9 @@ function nodes_within_range(nodes::Dict{Int,T}, loc::T, range::Float64 = Inf) wh return indices end -### Find nodes within range of a location using a subset of nodes ### +""" +Find nodes within range of a location using a subset of nodes +""" function nodes_within_range(nodes::Dict{Int,T}, loc::T, node_list::AbstractSet{Int}, range::Float64 = Inf) where T<:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF}) if range == Inf return node_list @@ -98,13 +100,14 @@ function nodes_within_range(nodes::Dict{Int,T}, loc::T, node_list::AbstractSet{I return indices end -### Find vertices of a routing network within range of a location ### +""" +Find vertices of a routing network within range of a location +""" nodes_within_range(nodes::Dict{Int,T},loc::T, m::OpenStreetMapX.MapData, range::Float64 = Inf) where T <:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF}) = OpenStreetMapX.nodes_within_range(nodes,loc,collect(keys(m.v)),range) -######################################### -### Compute Centroid of List of Nodes ### -######################################### - +""" +Compute Centroid of List of Nodes +""" function centroid(nodes::Dict{Int,T}, node_list::Vector{Int}) where T<:(Union{OpenStreetMapX.LLA,OpenStreetMapX.ENU}) sum_1 = 0 sum_2 = 0 diff --git a/src/parseMap.jl b/src/parseMap.jl index b6c6dbe..275c3a2 100644 --- a/src/parseMap.jl +++ b/src/parseMap.jl @@ -1,7 +1,6 @@ -############################# -### Parse Elements of Map ### -############################# - +""" +Parse Elements of Map +""" function parse_element(handler::LibExpat.XPStreamHandler, name::AbstractString, attr::Dict{AbstractString,AbstractString}) @@ -82,8 +81,10 @@ High level function - parses .osm file and create the road network based on the * `road_levels` : a set with the road categories (see: OpenStreetMapX.ROAD_CLASSES for more informations) * `use_cache` : a *.cache file will be crated with a serialized map image in the `datapath` folder * `only_intersections` : include only road system data +* `trim_to_connected_graph`: trim orphan nodes in such way that the map is a strongly connected graph """ -function get_map_data(filepath::String,filename::Union{String,Nothing}=nothing; road_levels::Set{Int} = Set(1:length(OpenStreetMapX.ROAD_CLASSES)),use_cache::Bool = true,only_intersections=true)::MapData +function get_map_data(filepath::String,filename::Union{String,Nothing}=nothing; road_levels::Set{Int} = Set(1:length(OpenStreetMapX.ROAD_CLASSES)), + use_cache::Bool = true,only_intersections::Bool = true, trim_to_connected_graph::Bool=false)::MapData #preprocessing map file datapath = (filename==nothing) ? dirname(filepath) : filepath; if filename == nothing @@ -98,42 +99,7 @@ function get_map_data(filepath::String,filename::Union{String,Nothing}=nothing; else mapdata = OpenStreetMapX.parseOSM(joinpath(datapath,filename)) OpenStreetMapX.crop!(mapdata,crop_relations = false) - #preparing data - bounds = mapdata.bounds - nodes = OpenStreetMapX.ENU(mapdata.nodes,OpenStreetMapX.center(bounds)) - highways = OpenStreetMapX.filter_highways(OpenStreetMapX.extract_highways(mapdata.ways)) - roadways = OpenStreetMapX.filter_roadways(highways, levels= road_levels) - intersections = OpenStreetMapX.find_intersections(roadways) - segments = OpenStreetMapX.find_segments(nodes,roadways,intersections) - - #remove unuseful nodes - roadways_nodes = unique(vcat(collect(way.nodes for way in roadways)...)) - nodes = Dict(key => nodes[key] for key in roadways_nodes) - - # e - Edges in graph, stored as a tuple (source,destination) - # class - Road class of each edgey - if only_intersections - vals = Dict((segment.node0,segment.node1) => (segment.distance,segment.parent) for segment in segments) - e = collect(keys(vals)) - vals = collect(values(vals)) - weights = map(val -> val[1],vals) - classified_roadways = OpenStreetMapX.classify_roadways(roadways) - class = [classified_roadways[id] for id in map(val -> val[2],vals)] - else - e,class = OpenStreetMapX.get_edges(nodes,roadways) - weights = OpenStreetMapX.distance(nodes,e) - end - # (node id) => (graph vertex) - v = OpenStreetMapX.get_vertices(e) - n = Dict(reverse.(collect(v))) - edges = [v[id] for id in reinterpret(Int, e)] - I = edges[1:2:end] - J = edges[2:2:end] - # w - Edge weights, indexed by graph id - w = SparseArrays.sparse(I, J, weights, length(v), length(v)) - g = LightGraphs.DiGraph(w) - - res = OpenStreetMapX.MapData(bounds,nodes,roadways,intersections,g,v,n,e,w,class) + res = MapData(mapdata, road_levels, only_intersections; trim_to_connected_graph=trim_to_connected_graph) if use_cache f=open(cachefile,"w"); Serialization.serialize(f,res); @@ -143,3 +109,66 @@ function get_map_data(filepath::String,filename::Union{String,Nothing}=nothing; end return res end + + +function MapData(mapdata::OSMData, road_levels::Set{Int}, only_intersections::Bool=true; + trim_to_connected_graph::Bool=false, remove_nodes::AbstractSet{Int}=Set{Int}()) + #preparing data + bounds = mapdata.bounds + nodes = OpenStreetMapX.ENU(mapdata.nodes,OpenStreetMapX.center(bounds)) + highways = OpenStreetMapX.filter_highways(OpenStreetMapX.extract_highways(mapdata.ways)) + roadways = OpenStreetMapX.filter_roadways(highways, levels= road_levels) + if length(remove_nodes) > 0 + delete!.(Ref(nodes), remove_nodes); + delcount = 0 + for rno in length(roadways):-1:1 + rr = roadways[rno] + for i in length(rr.nodes):-1:1 + if rr.nodes[i] in remove_nodes + deleteat!(rr.nodes,i) + delcount += 1 + end + end + length(rr.nodes) == 0 && deleteat!(roadways, rno) + end + end + intersections = OpenStreetMapX.find_intersections(roadways) + segments = OpenStreetMapX.find_segments(nodes,roadways,intersections) + #remove unuseful nodes + roadways_nodes = unique(vcat(collect(way.nodes for way in roadways)...)) + nodes = Dict(key => nodes[key] for key in roadways_nodes) + + # e - Edges in graph, stored as a tuple (source,destination) + # class - Road class of each edgey + if only_intersections && !trim_to_connected_graph + vals = Dict((segment.node0,segment.node1) => (segment.distance,segment.parent) for segment in segments) + e = collect(keys(vals)) + vals = collect(values(vals)) + weight_vals = map(val -> val[1],vals) + classified_roadways = OpenStreetMapX.classify_roadways(roadways) + class = [classified_roadways[id] for id in map(val -> val[2],vals)] + else + e,class = OpenStreetMapX.get_edges(nodes,roadways) + weight_vals = OpenStreetMapX.distance(nodes,e) + end + # (node id) => (graph vertex) + v = OpenStreetMapX.get_vertices(e) + n = Dict(reverse.(collect(v))) + edges = [v[id] for id in reinterpret(Int, e)] + I = edges[1:2:end] + J = edges[2:2:end] + # w - Edge weights, indexed by graph id + w = SparseArrays.sparse(I, J, weight_vals, length(v), length(v)) + g = LightGraphs.DiGraph(w) + + if trim_to_connected_graph + rm_list = Set{Int}() + conn_components = sort!(LightGraphs.strongly_connected_components(g), + lt=(x,y)->length(x) zero(Float64), get_distance::Bool = false, get_time::Bool = false) @@ -200,19 +200,15 @@ function find_route(m::OpenStreetMapX.MapData, node0::Int, node1::Int, end -######################################################### -### ### -######################################################### - """ - find_route(m::OpenStreetMapX.MapData, node0::Int, node1::Int, node2::Int, + find_route(m::MapData, node0::Int, node1::Int, node2::Int, weights::SparseArrays.SparseMatrixCSC{Float64,Int64}; routing::Symbol = :astar, heuristic::Function = (u,v) -> zero(Float64), get_distance::Bool = false, get_time::Bool = false) Find Route Connecting 3 Points (`node0`, `node1`, `node2`) with Given Weights """ -function find_route(m::OpenStreetMapX.MapData, node0::Int, node1::Int, node2::Int, +function find_route(m::MapData, node0::Int, node1::Int, node2::Int, weights::SparseArrays.SparseMatrixCSC{Float64,Int64}; routing::Symbol = :astar, heuristic::Function = (u,v) -> zero(Float64), get_distance::Bool = false, get_time::Bool = false) @@ -257,7 +253,7 @@ function shortest_route(m::MapData, node1::Int, node2::Int, node3::Int; routing: end """ - ffastest_route(m::MapData, node1::Int, node2::Int; + fastest_route(m::MapData, node1::Int, node2::Int; routing::Symbol = :astar, speeds::Dict{Int,Float64}=SPEED_ROADS_URBAN) @@ -293,13 +289,11 @@ function fastest_route(m::MapData, node1::Int, node2::Int, node3::Int; return route_nodes, distance, route_time end -########################################### -### Find waypoint minimizing the route ### -########################################### - -### Approximate solution ### - -function find_optimal_waypoint_approx(m::OpenStreetMapX.MapData, weights::SparseArrays.SparseMatrixCSC{Float64,Int64}, node0::Int, node1::Int, waypoints::Dict{Int,Int}) +""" +Find waypoint minimizing the route +Approximate solution +""" +function find_optimal_waypoint_approx(m::MapData, weights::SparseArrays.SparseMatrixCSC{Float64,Int64}, node0::Int, node1::Int, waypoints::Dict{Int,Int}) dists_start_waypoint = LightGraphs.dijkstra_shortest_paths(m.g, m.v[node0], weights).dists dists_waypoint_fin = LightGraphs.dijkstra_shortest_paths(m.g, m.v[node1], weights).dists node_id = NaN @@ -314,9 +308,11 @@ function find_optimal_waypoint_approx(m::OpenStreetMapX.MapData, weights::Sparse return node_id end -### Exact solution ### - -function find_optimal_waypoint_exact(m::OpenStreetMapX.MapData, weights::SparseArrays.SparseMatrixCSC{Float64,Int64}, node0::Int, node1::Int, waypoints::Dict{Int,Int}) +""" +Find waypoint minimizing the route +Exact solution +""" +function find_optimal_waypoint_exact(m::MapData, weights::SparseArrays.SparseMatrixCSC{Float64,Int64}, node0::Int, node1::Int, waypoints::Dict{Int,Int}) dists_start_waypoint = LightGraphs.dijkstra_shortest_paths(m.g, m.v[node0], weights).dists node_id = NaN min_dist = Inf @@ -336,7 +332,7 @@ end ######################################################################## ### Bellman Ford's Algorithm ### -function bellman_ford(m::OpenStreetMapX.MapData, w::SparseArrays.SparseMatrixCSC{Float64,Int64}, start_vertices::Vector{Int}) +function bellman_ford(m::MapData, w::SparseArrays.SparseMatrixCSC{Float64,Int64}, start_vertices::Vector{Int}) return LightGraphs.bellman_ford_shortest_paths(m.g, start_vertices, w) end @@ -364,40 +360,40 @@ end ### Based on Weights ### ############################################################################## -function nodes_within_weights(m::OpenStreetMapX.MapData, weights::SparseArrays.SparseMatrixCSC{Float64,Int64}, start_indices::Vector{Int}, limit::Float64=Inf) +function nodes_within_weights(m::MapData, weights::SparseArrays.SparseMatrixCSC{Float64,Int64}, start_indices::Vector{Int}, limit::Float64=Inf) start_vertices = [m.v[i] for i in start_indices] bellman_ford = OpenStreetMapX.bellman_ford(m, weights, start_vertices) return OpenStreetMapX.filter_vertices(m.v, bellman_ford.dists, limit) end -nodes_within_weights(nodes::Dict{Int,T}, m::OpenStreetMapX.MapData, weights::SparseArrays.SparseMatrixCSC{Float64,Int64}, loc::T, limit::Float64=Inf,locrange::Float64=500.0) where T<:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF}) = OpenStreetMapX.nodes_within_weights(m, weights, nodes_within_range(nodes, loc, network, locrange), limit) +nodes_within_weights(nodes::Dict{Int,T}, m::MapData, weights::SparseArrays.SparseMatrixCSC{Float64,Int64}, loc::T, limit::Float64=Inf,locrange::Float64=500.0) where T<:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF}) = OpenStreetMapX.nodes_within_weights(m, weights, nodes_within_range(nodes, loc, network, locrange), limit) ############################################################################## ### Extract Nodes from bellman_fordStates Object Within an (Optional) Limit ### ### Based on Driving Distance ### ############################################################################## -function nodes_within_driving_distance(m::OpenStreetMapX.MapData, start_indices::Vector{Int}, limit::Float64=Inf) +function nodes_within_driving_distance(m::MapData, start_indices::Vector{Int}, limit::Float64=Inf) start_vertices = [m.v[i] for i in start_indices] bellman_ford = OpenStreetMapX.bellman_ford(m, m.w, start_vertices) return OpenStreetMapX.filter_vertices(m.v, bellman_ford.dists, limit) end -nodes_within_driving_distance(nodes::Dict{Int,T}, m::OpenStreetMapX.MapData, loc::T, limit::Float64=Inf,locrange::Float64=500.0) where T<:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF})= OpenStreetMapX.nodes_within_driving_distance(m, nodes_within_range(nodes, loc ,network, locrange), limit) +nodes_within_driving_distance(nodes::Dict{Int,T}, m::MapData, loc::T, limit::Float64=Inf,locrange::Float64=500.0) where T<:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF})= OpenStreetMapX.nodes_within_driving_distance(m, nodes_within_range(nodes, loc ,network, locrange), limit) ############################################################################## ### Extract Nodes from bellman_fordStates Object Within an (Optional) Limit ### ### Based on Driving Time ### ############################################################################## -function nodes_within_driving_time(m::OpenStreetMapX.MapData, start_indices::Vector{Int}, limit::Float64=Inf, speeds::Dict{Int,Float64}=SPEED_ROADS_URBAN) +function nodes_within_driving_time(m::MapData, start_indices::Vector{Int}, limit::Float64=Inf, speeds::Dict{Int,Float64}=SPEED_ROADS_URBAN) w = OpenStreetMapX.create_weights_matrix(m,network_travel_times(m, speeds)) start_vertices = [m.v[i] for i in start_indices] bellman_ford = OpenStreetMapX.bellman_ford(m, w, start_vertices) return OpenStreetMapX.filter_vertices(m.v, bellman_ford.dists, limit) end -function nodes_within_driving_time(nodes::Dict{Int,T}, m::OpenStreetMapX.MapData, loc::T, limit::Float64=Inf, locrange::Float64=500.0, speeds::Dict{Int,Float64}=SPEED_ROADS_URBAN) where T<:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF}) +function nodes_within_driving_time(nodes::Dict{Int,T}, m::MapData, loc::T, limit::Float64=Inf, locrange::Float64=500.0, speeds::Dict{Int,Float64}=SPEED_ROADS_URBAN) where T<:(Union{OpenStreetMapX.ENU,OpenStreetMapX.ECEF}) w = OpenStreetMapX.create_weights_matrix(m,network_travel_times(m, speeds)) return OpenStreetMapX.nodes_within_driving_time(m,nodes_within_range(nodes, loc, m,locrange),limit,speeds) end diff --git a/test/runtests.jl b/test/runtests.jl index accec27..5d3ba1b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,7 +3,9 @@ using Random import LightGraphs -m = get_map_data("data/reno_east3.osm",use_cache=false); +pth = joinpath(dirname(pathof(OpenStreetMapX)),"..","test","data","reno_east3.osm") +m = OpenStreetMapX.get_map_data(pth,use_cache = false); + @testset "maps" begin @@ -66,6 +68,15 @@ m = get_map_data("data/reno_east3.osm",use_cache=false); #Returns seem to be equal yet returning false (?) @test distance(m.nodes,OpenStreetMapX.get_edges(m.nodes,m.roadways[1:2])[1]) == [30.2013937293296, 7.243941886194111, 35.492758006997796, 12.29992029473937, 11.290063259013777] + conn_components = sort!(LightGraphs.strongly_connected_components(m.g), + lt=(x,y)->length(x)length(x)