备注
单击 here 要下载完整的示例代码,请执行以下操作
来自一组线的图形#
这个例子展示了如何使用GeoPandas、Moepy和另一种选择PySAL从一组地理线(有时称为“线串”)构建图形。我们将绘制一些河流和街道,以及它们由线段组成的图表。
从线条几何图形创建图形对象通常有两种方法。让我们用一个街道网络的例子来说明这两个问题:
第一种方法是所谓的原始方法,其中每个交叉点是一个节点,连接两个交叉点的每个线串段都是一条边。
第二种方法是所谓的对偶方法,其中每条线都是一个节点,相交的拓扑结构被转化为边。将其用于街道网络分析的方式之一是角度分析,即通过交叉点上街道段之间的角度对路线进行加权。
我们将使用GeoPandas读取空间数据,并使用omepy生成第一个原始图形,然后生成对偶图形。此外,我们将使用PYSAL来说明创建原始对偶图的另一种方法。
import geopandas
import matplotlib.pyplot as plt
import momepy
import networkx as nx
from contextily import add_basemap
from libpysal import weights
阅读GeoJSON中的河流几何学示例。范例数据来源:https://doi.org/10.3390/data5010008(Nicolas Cadieux)
rivers = geopandas.read_file("rivers.geojson")
构造原始图。Moepy自动保留GeoDataFrame中的所有属性,然后将其存储为边属性。
G = momepy.gdf_to_nx(rivers, approach="primal")
每个节点都由它的坐标编码,这允许我们在绘图中使用它们。

一旦我们完成了基于图形的分析,我们就可以将图形转换回GeoDataFrames。Moepy可以以点几何形式返回节点,以原始线几何形式返回边和W对象,W对象是编码原始图形的PySAL空间权重矩阵,因此可以与节点GeoDataFrame一起使用。
nodes, edges, W = momepy.nx_to_gdf(G, spatial_weights=True)
# Read in example street network from GeoPackage
streets = geopandas.read_file(momepy.datasets.get_path("bubenec"), layer="streets")
# Construct the primal graph
G_primal = momepy.gdf_to_nx(streets, approach="primal")
# Plot
f, ax = plt.subplots(1, 2, figsize=(12, 6), sharex=True, sharey=True)
streets.plot(color="k", ax=ax[0])
for i, facet in enumerate(ax):
facet.set_title(("Streets", "Graph")[i])
facet.axis("off")
add_basemap(facet)
nx.draw(
G_primal, {n: [n[0], n[1]] for n in list(G_primal.nodes)}, ax=ax[1], node_size=50
)

构造对偶图。Omepy会将行属性存储为节点属性,并自动测量行之间的角度。
G_dual = momepy.gdf_to_nx(streets, approach="dual")
# Plot
f, ax = plt.subplots(1, 2, figsize=(12, 6), sharex=True, sharey=True)
streets.plot(color="k", ax=ax[0])
for i, facet in enumerate(ax):
facet.set_title(("Streets", "Graph")[i])
facet.axis("off")
add_basemap(facet)
nx.draw(G_dual, {n: [n[0], n[1]] for n in list(G_dual.nodes)}, ax=ax[1], node_size=50)
plt.show()
# Convert dual graph back to GeoDataFrame. Returns only original line geometry.
lines = momepy.nx_to_gdf(G_dual)

我们也可以使用PYSAL来构造对偶图。请注意,它只对几何图形之间的关系进行编码,而不存储任何属性。但是,它比omepy.gdf_to_nx()快得多。创建PYSAL权重(图表)。
W = weights.Queen.from_dataframe(streets)
# Convert the graph to networkx
G_dual = W.to_networkx()
Total running time of the script: ( 0 minutes 12.819 seconds)