Skip to content

Commit 0a728bb

Browse files
committed
add SimplifiedOSMGraph type and adjust simplifiy_graph
1 parent 5ae3fbf commit 0a728bb

File tree

2 files changed

+60
-26
lines changed

2 files changed

+60
-26
lines changed

src/simplification.jl

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ function is_endpoint(g::AbstractGraph, v)
1010
return true
1111
elseif outdegree(g, v) == 0 || indegree(g, v) == 0 # sink or source
1212
return true
13-
elseif length(neighbors) != 2 || indegree(g, v) != outdegree(g, v) # change to one way
13+
elseif length(neighbors) != 2 || indegree(g, v) != outdegree(g, v) # change to/from one way
1414
return true
1515
end
1616
return false
@@ -45,55 +45,78 @@ function path_to_endpoint(g::AbstractGraph, (ep, ep_succ)::Tuple{T,T}) where {T<
4545
return path
4646
end
4747

48+
"""
49+
Return the total weight of a path given as a Vector of Ids.
50+
"""
4851
function total_weight(g::OSMGraph, path::Vector{<:Integer})
4952
sum((g.weights[path[[i, i+1]]...] for i in 1:length(path)-1))
5053
end
54+
55+
function ways_in_path(g::OSMGraph, path::Vector{<:Integer})
56+
ways = Set{Int}()
57+
for i in 1:(length(path)-1)
58+
edge = [g.index_to_node[path[i]], g.index_to_node[path[i+1]]]
59+
push!(ways, g.edge_to_way[edge])
60+
end
61+
return collect(ways)
62+
end
63+
5164
"""
5265
Build a new graph which simplifies the topology of osmg.graph.
5366
The resulting graph only contains intersections and dead ends from the original graph.
5467
The geometry of the contracted nodes is kept in the edge_gdf DataFrame
5568
"""
56-
function simplify_graph(osmg::OSMGraph)
69+
function simplify_graph(osmg::OSMGraph{U, T, W}) where {U, T, W}
5770
g = osmg.graph
5871
relevant_nodes = collect(endpoints(g))
59-
n = length(relevant_nodes)
60-
(n == nv(g)) && return g # nothing to simplify here
72+
n_relevant = length(relevant_nodes)
73+
graph = DiGraph(n_relevant)
74+
weights = similar(osmg.weights, (n_relevant, n_relevant))
75+
node_coordinates = Vector{Vector{W}}(undef, n_relevant)
76+
node_to_index = OrderedDict{T,U}()
77+
index_to_node = OrderedDict{U,T}()
6178

62-
63-
G_simplified = DiGraph(n)
64-
weights = similar(osmg.weights, (n, n))
65-
edge_gdf = DataFrame(
66-
u = Int[],
67-
v = Int[],
68-
key = Int[],
69-
weight = Vector{eltype(osmg.weights)}(),
70-
geom = IGeometry[],
71-
)
72-
node_gdf = DataFrame(id = Int[], geom = IGeometry[])
73-
74-
75-
index_mapping = Dict{Int,Int}()
79+
index_mapping = Dict{U,U}()
7680
for (new_i, old_i) in enumerate(relevant_nodes)
7781
index_mapping[old_i] = new_i
78-
geo = createpoint(osmg.node_coordinates[old_i])
79-
push!(node_gdf, (new_i, geo))
82+
node_coordinates[new_i] = osmg.node_coordinates[old_i]
83+
node = osmg.index_to_node[old_i]
84+
index_to_node[new_i] = node
85+
node_to_index[node] = new_i
8086
end
8187

88+
edges = Dict{NTuple{3,U}, Vector{U}}()
89+
edge_count = Dict{Tuple{U,U}, Int}()
8290
for path in paths_to_reduce(g)
8391
u = index_mapping[first(path)]
8492
v = index_mapping[last(path)]
8593
path_weight = total_weight(osmg, path)
86-
geo = createlinestring(osmg.node_coordinates[path])
87-
88-
if add_edge!(G_simplified, (u, v))
94+
if add_edge!(graph, (u, v))
8995
key = 0
9096
weights[u, v] = path_weight
97+
edge_count[u,v] = 1
9198
else # parallel edge
92-
key = sum((edge_gdf.u .== u) .& (edge_gdf.v .== v))
99+
key = edge_count[u,v]
100+
edge_count[u,v] += 1
93101
weights[u, v] = min(path_weight, weights[u, v])
94102
end
95-
push!(edge_gdf, (u, v, key, path_weight, geo))
103+
edges[u,v,key] = path
104+
end
105+
106+
edge_to_way = Dict{NTuple{3,U}, Vector{T}}()
107+
for (edge, path) in edges
108+
edge_to_way[edge] = ways_in_path(osmg, path)
96109
end
97110

98-
return G_simplified, weights, node_gdf, edge_gdf
111+
return SimplifiedOSMGraph(
112+
osmg,
113+
node_coordinates,
114+
node_to_index,
115+
index_to_node,
116+
edge_to_way,
117+
graph,
118+
edges,
119+
weights,
120+
nothing
121+
)
99122
end

src/types.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,17 @@ function Base.getproperty(g::OSMGraph, field::Symbol)
164164
else
165165
return getfield(g, field)
166166
end
167+
168+
struct SimplifiedOSMGraph{U <: Integer, T <: Union{Integer, String}, W <: Real}
169+
parent::OSMGraph{U,T,W}
170+
node_coordinates::Vector{Vector{W}} # needed for astar heuristic
171+
node_to_index::OrderedDict{T,U}
172+
index_to_node::OrderedDict{U,T}
173+
edge_to_way::Dict{Vector{T},Vector{T}}
174+
graph::Union{AbstractGraph,Nothing}
175+
edges::Dict{NTuple{3, U}, Vector{U}}
176+
weights::Union{SparseMatrixCSC{W,U},Nothing}
177+
dijkstra_states::Union{Vector{Vector{U}},Nothing}
167178
end
168179

169180
"""

0 commit comments

Comments
 (0)