使用 OSMnx 提取约束多边形
Extract constrained polygon using OSMnx
我正在研究 OSMnx 包以解决以下任务:
- 地图上有一个由经纬度定义的点 X
- 我们需要检测包含该点 X 并受相邻道路约束的多边形
- 所以基本上 X 点在多边形内部,相邻的道路将是该多边形的边界。
到目前为止,我只设法在地图上绘制图形的可视化并找到最接近 edge/node 点 X。
在附图中,我用红色突出显示了我要提取的区域。
当您试图找到包含您的点的多边形时,您首先需要从多线串几何图形中生成多边形。由于您没有提供数据,我正在使用 OSMnx 从 OSM 下载示例。
import osmnx as ox
import geopandas as gpd
import shapely
point = (40.742623, -73.977857)
streets_graph = ox.graph_from_point(point, distance=500, network_type='drive')
streets_graph = ox.project_graph(streets_graph)
我重新投影了它,因为它比使用度数更方便,尤其是当您想测量任何东西时。
然后您必须将 OSMnx 图转换为 geopandas GeoDataFrame。
streets = ox.save_load.graph_to_gdfs(streets_graph, nodes=False, edges=True,
node_geometry=False, fill_edge_geometry=True)
为了获得一些我可以使用的点,我将只使用此地理数据框中心的点。
point = streets.unary_union.centroid
这就是它的样子。
接下来,您需要使用我在上面评论中建议的 shapely.ops.polygonize
获取由街道定义的街区的多边形,并将它们存储为 GeoSeries。
polygons = shapely.ops.polygonize(streets.geometry)
polygons = gpd.GeoSeries(polygons)
接下来您唯一要做的就是找出哪个多边形包含您的点。
target = polygons.loc[polygons.contains(point)]
再次绘制:
ax = target.plot()
gpd.GeoSeries([point]).plot(ax=ax, color='r')
如果您想知道哪些街道构成了这个多边形的边界,只需将它与原始网络相交即可。我过滤 MultiLineString
以排除仅在一个点与多边形相交的街道。
target_streets = streets.loc[streets.intersection(target.iloc[0]).type == 'MultiLineString']
这就是结果的样子。
ax = target_streets2.plot()
gpd.GeoSeries([point]).plot(ax=ax, color='r')
希望对您有所帮助。
我正在研究 OSMnx 包以解决以下任务: - 地图上有一个由经纬度定义的点 X - 我们需要检测包含该点 X 并受相邻道路约束的多边形 - 所以基本上 X 点在多边形内部,相邻的道路将是该多边形的边界。
到目前为止,我只设法在地图上绘制图形的可视化并找到最接近 edge/node 点 X。
在附图中,我用红色突出显示了我要提取的区域。
当您试图找到包含您的点的多边形时,您首先需要从多线串几何图形中生成多边形。由于您没有提供数据,我正在使用 OSMnx 从 OSM 下载示例。
import osmnx as ox
import geopandas as gpd
import shapely
point = (40.742623, -73.977857)
streets_graph = ox.graph_from_point(point, distance=500, network_type='drive')
streets_graph = ox.project_graph(streets_graph)
我重新投影了它,因为它比使用度数更方便,尤其是当您想测量任何东西时。
然后您必须将 OSMnx 图转换为 geopandas GeoDataFrame。
streets = ox.save_load.graph_to_gdfs(streets_graph, nodes=False, edges=True,
node_geometry=False, fill_edge_geometry=True)
为了获得一些我可以使用的点,我将只使用此地理数据框中心的点。
point = streets.unary_union.centroid
这就是它的样子。
接下来,您需要使用我在上面评论中建议的 shapely.ops.polygonize
获取由街道定义的街区的多边形,并将它们存储为 GeoSeries。
polygons = shapely.ops.polygonize(streets.geometry)
polygons = gpd.GeoSeries(polygons)
接下来您唯一要做的就是找出哪个多边形包含您的点。
target = polygons.loc[polygons.contains(point)]
再次绘制:
ax = target.plot()
gpd.GeoSeries([point]).plot(ax=ax, color='r')
如果您想知道哪些街道构成了这个多边形的边界,只需将它与原始网络相交即可。我过滤 MultiLineString
以排除仅在一个点与多边形相交的街道。
target_streets = streets.loc[streets.intersection(target.iloc[0]).type == 'MultiLineString']
这就是结果的样子。
ax = target_streets2.plot()
gpd.GeoSeries([point]).plot(ax=ax, color='r')
希望对您有所帮助。