@@ -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
4848function total_weight (g:: OSMGraph , path:: Vector{<:Integer} )
4949 sum ((g. weights[path[[i, i+ 1 ]]. .. ] for i in 1 : length (path)- 1 ))
5050end
51+
5152"""
5253Build a new graph which simplifies the topology of osmg.graph.
5354The resulting graph only contains intersections and dead ends from the original graph.
5455The geometry of the contracted nodes is kept in the edge_gdf DataFrame
5556"""
56- function simplify_graph (osmg:: OSMGraph )
57+ function simplify_graph (osmg:: OSMGraph{U, T, W} ) where {U, T, W}
5758 g = osmg. graph
5859 relevant_nodes = collect (endpoints (g))
59- n = length (relevant_nodes)
60- (n == nv (g)) && return g # nothing to simplify here
61-
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-
60+ n_relevant = length (relevant_nodes)
61+ graph = DiGraph (n_relevant)
62+ weights = similar (osmg. weights, (n_relevant, n_relevant))
63+ node_coordinates = Vector {Vector{W}} (undef, n_relevant)
64+ node_to_index = OrderedDict {T,U} ()
65+ index_to_node = OrderedDict {U,T} ()
7466
75- index_mapping = Dict {Int,Int } ()
67+ index_mapping = Dict {U,U } ()
7668 for (new_i, old_i) in enumerate (relevant_nodes)
7769 index_mapping[old_i] = new_i
78- geo = createpoint (osmg. node_coordinates[old_i])
79- push! (node_gdf, (new_i, geo))
70+ node_coordinates[new_i] = osmg. node_coordinates[old_i]
71+ node = osmg. index_to_node[old_i]
72+ index_to_node[new_i] = node
73+ node_to_index[node] = new_i
8074 end
8175
76+ edges = Dict {NTuple{3,U}, Vector{U}} ()
77+ edge_count = Dict {Tuple{U,U}, Int} ()
8278 for path in paths_to_reduce (g)
8379 u = index_mapping[first (path)]
8480 v = index_mapping[last (path)]
8581 path_weight = total_weight (osmg, path)
86- geo = createlinestring (osmg. node_coordinates[path])
8782
88- if add_edge! (G_simplified , (u, v))
83+ if add_edge! (graph , (u, v))
8984 key = 0
9085 weights[u, v] = path_weight
86+ edge_count[u,v] = 1
9187 else # parallel edge
92- key = sum ((edge_gdf. u .== u) .& (edge_gdf. v .== v))
88+ key = edge_count[u,v]
89+ edge_count[u,v] += 1
9390 weights[u, v] = min (path_weight, weights[u, v])
9491 end
95- push! (edge_gdf, (u, v, key, path_weight, geo))
92+ edges[u,v, key] = path
9693 end
9794
98- return G_simplified, weights, node_gdf, edge_gdf
95+ return SimplifiedOSMGraph (
96+ osmg,
97+ node_coordinates,
98+ node_to_index,
99+ index_to_node,
100+ Dict {Vector{T}, Vector{T}} (),
101+ graph,
102+ edges,
103+ weights,
104+ nothing
105+ )
99106end
0 commit comments