【发布时间】:2021-12-04 01:02:06
【问题描述】:
我正在使用我已经丰富的 Open Street Data,并且正在通过 NetworkX 进行建模。 但是,存在大量节点来设计边的曲线,因为它们只有两条边。
因此,我需要通过聚合连接这些节点的边来简化 grah,同时保留聚合边的属性。
这是一个可重现的例子:
import networkx as nx
from shapely.geometry import LineString, Point
G = nx.Graph()
G.add_nodes_from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
G.add_edges_from([(1, 2, {'highway': 'primary', 'speed_kph': 90, 'slope': 1.2,
'geometry': LineString([Point(3.013832,42.785837), Point(3.010505, 42.787605)])}),
(2, 3, {'highway': 'primary', 'speed_kph': 70, 'slope': 0.8,
'geometry': LineString([Point(3.010505, 42.787605), Point(3.006227, 42.789605)])}),
(3, 4, {'highway': 'primary', 'speed_kph': 50, 'slope': -0.1,
'geometry': LineString([Point(3.006227, 42.789605), Point(3.001030, 42.789721)])}),
(4, 5, {'highway': 'secondary', 'speed_kph': 50, 'slope': 3.1,
'geometry': LineString([Point(3.001030, 42.789721), Point(3.000998, 42.79321)])}),
(5, 6, {'highway': 'primary', 'speed_kph': 70, 'slope': -1.3,
'geometry': LineString([Point(3.000998, 42.79321), Point(2.995483, 42.795675)])}),
(4, 10, {'highway': 'tertiary', 'speed_kph': 50, 'slope': 3.7,
'geometry': LineString([Point(3.001030, 42.789721), Point(2.998273, 42.787303)])}),
(10, 11, {'highway': 'tertiary', 'speed_kph': 30, 'slope': 2.9,
'geometry': LineString([Point(2.998273, 42.787303), Point(2.995231, 42.784279)])}),
(3, 7, {'highway': 'secondary', 'speed_kph': 50, 'slope': 5.6,
'geometry': LineString([Point(3.006227, 42.789605), Point(3.009407, 42.791873)])}),
(7, 8, {'highway': 'secondary', 'speed_kph': 50, 'slope': 6.4,
'geometry': LineString([Point(3.009407, 42.791873), Point(3.009217, 42.794710)])}),
(8, 9, {'highway': 'secondary', 'speed_kph': 50, 'slope': -4.3,
'geometry': LineString([Point(3.009217, 42.794710), Point(3.005858, 42.796036)])}),
(9, 5, {'highway': 'secondary', 'speed_kph': 50, 'slope': -7.2,
'geometry': LineString([Point(3.005858, 42.796036), Point(3.000998, 42.79321)])})])
nx.draw(G, with_labels=True)
plt.show()
如您所见,边 (1,2) 和 (2,3) 可以聚合在一起,以及 (4,10) 和 (10,11),甚至 (3,7), (7 ,8), (8,9), (9,5) 可以概括为一条边。
但是,在聚合时,我不想丢失 speed_kph 和 slope 属性,并选择保持边缘的均值组合。
至于几何,我想结合线串。所以生成的网络应该如下
import numpy as np
from shapely.ops import linemerge
new_G = nx.Graph()
new_G.add_nodes_from([1, 3, 4, 5, 6, 11])
new_G.add_edges_from([(1, 3, {'highway': 'primary', 'speed_kph': np.mean([90, 70]), 'slope': np.mean([1.2, 0.8]),
'geometry': linemerge([LineString([Point(3.013832,42.785837), Point(3.010505, 42.787605)]),
LineString([Point(3.010505, 42.787605), Point(3.006227, 42.789605)])])}),
(3, 4, {'highway': 'primary', 'speed_kph': 50, 'slope': -0.1,
'geometry': LineString([Point(3.006227, 42.789605), Point(3.001030, 42.789721)])}),
(4, 5, {'highway': 'secondary', 'speed_kph': 50, 'slope': 3.1,
'geometry': LineString([Point(3.001030, 42.789721), Point(3.000998, 42.79321)])}),
(5, 6, {'highway': 'primary', 'speed_kph': 70, 'slope': -1.3,
'geometry': LineString([Point(3.000998, 42.79321), Point(2.995483, 42.795675)])}),
(4, 11, {'highway': 'primary', 'speed_kph': np.mean([50, 30]), 'slope': np.mean([3.7, 2.9]),
'geometry': linemerge([LineString([Point(3.001030, 42.789721), Point(2.998273, 42.787303)]),
LineString([Point(2.998273, 42.787303), Point(2.995231, 42.784279)])])}),
(3, 5, {'highway': 'primary', 'speed_kph': np.mean([50, 50, 50, 50]), 'slope': np.mean([5.6, 6.4, -4.3, -7.2]),
'geometry': linemerge([LineString([Point(3.006227, 42.789605), Point(3.009407, 42.791873)]),
LineString([Point(3.009407, 42.791873), Point(3.009217, 42.794710)]),
LineString([Point(3.009217, 42.794710), Point(3.005858, 42.796036)]),
LineString([Point(3.005858, 42.796036), Point(3.000998, 42.79321)])])}),
])
nx.draw(new_G, with_labels=True)
plt.show()
有人知道我该怎么做吗?
当然,我的想法是自动检测可组合的边缘(可能使用degree 上的阈值),因为我正在处理比该玩具示例高得多的边缘数量并且无法手动进行。
【问题讨论】:
-
你看过边缘收缩吗?
-
我不知道这个词,不。但是我的搜索没有返回任何太有用的东西。你有什么想法吗?
-
OSMnx 完全符合您的要求osmnx.readthedocs.io/en/stable
-
对。因此我的回答如下。唯一的问题是 1. 它本质上只适用于 OSMnx 图和 2. 它暗示该图是一个 MultiDiGraph。
标签: python graph aggregate networkx