如何将地图多边形近似为路网内多边形?求更优实现方案
解决:生成贴合路网的近似多边形(消除间隙问题)
问题背景
我处理地图多边形数据,拥有一个DataFrame df_polygons,每行对应一个多边形,df_polygons['polygon'] 可获取由有序点集定义的具体多边形,示例如下:
polygon_1 = [[41.2169494797, -8.6778177263], [41.2169902336, -8.692729496], [41.2282499337, -8.6926767872], [41.2282887721, -8.7075911445], [41.2339186214, -8.7075660584], [41.2451783036, -8.7075158648], [41.2451394423, -8.6925976679], [41.2507692675, -8.6925712798], [41.250749108, -8.6851115523], [41.2563789237, -8.6850845162], [41.2563582769, -8.6776241559], [41.2394688256, -8.6777071617], [41.2393814564, -8.6478734838], [41.2281218289, -8.6479339004], [41.2282091637, -8.6777624597], [41.2169494797, -8.6778177263]] polygon_2 = [[41.194470767, -8.6928348239], [41.2057305114, -8.6927821749], [41.2056897735, -8.6778729616], [41.2169494797, -8.6778177263], [41.2169902336, -8.692729496], [41.2282499337, -8.6926767872], [41.2282887721, -8.7075911445], [41.2508081364, -8.7074907573], [41.2508800748, -8.737329796200001], [41.1945813563, -8.7375549721], [41.194470767, -8.6928348239]]
现有方案通过多边形边界框生成路网图G,对每条边插值生成点后匹配最近路网边,但最终结果的多边形间存在多处间隙,需要更精准的实现方案。
改进方案
核心思路
- 全局路网统一构建:计算所有多边形的整体边界框,一次性获取完整路网,避免局部路网缺失导致的间隙。
- 最短路径替代单边匹配:针对多边形的每个顶点对,计算路网中的最短路径,保证路径连续无断点。
- 路径去重与闭合处理:拼接路径时去除重复端点,最终手动闭合多边形。
完整实现代码
import folium import numpy as np import pandas as pd import osmnx as ox # 初始化地图 m = folium.Map(location=(41.25387369401857, -8.781923733405996), zoom_start=12) # 读取多边形数据(替换为你的实际数据源) df_polygons = pd.read_json() df_polygons = df_polygons.loc[0:2] # 步骤1:计算所有多边形的全局边界框 all_coords = [] for idx, row in df_polygons.iterrows(): all_coords.extend(row['polygon']) lats = [lat for lat, lon in all_coords] lons = [lon for lat, lon in all_coords] north, south = max(lats), min(lats) east, west = max(lons), min(lons) # 一次性获取全局路网(投影到平面坐标系提升计算精度) G = ox.graph.graph_from_bbox(north, south, east, west, network_type='drive') G_proj = ox.project_graph(G) # 步骤2:定义路网路径获取函数 def get_road_path(G, start_coord, end_coord): # 获取起点、终点的最近路网节点 start_node = ox.distance.nearest_nodes(G, X=start_coord[1], Y=start_coord[0]) end_node = ox.distance.nearest_nodes(G, X=end_coord[1], Y=end_coord[0]) # 计算最短路径(长度权重) route = ox.shortest_path(G, start_node, end_node, weight='length') if not route: # 无路径时返回原线段作为兜底 return [start_coord, end_coord] # 转换路径节点为坐标 route_coords = [(G.nodes[node]['y'], G.nodes[node]['x']) for node in route] return route_coords # 步骤3:为每个多边形生成路网贴合的闭合路径 for idx, row in df_polygons.iterrows(): polygon_coords = row['polygon'] road_polygon = [] # 遍历多边形每条边,生成对应路网路径 for i in range(len(polygon_coords)-1): start = polygon_coords[i] end = polygon_coords[i+1] path_coords = get_road_path(G, start, end) road_polygon.extend(path_coords[:-1]) # 跳过重复端点 # 闭合多边形 road_polygon.append(road_polygon[0]) # 添加到地图 folium.PolyLine( road_polygon, color='blue', weight=2, fill_color='blue', fill_opacity=0.1 ).add_to(m) # 保存并展示地图 m.save("test-figure.html") m
关键改进说明
- 全局路网:避免每个多边形单独构建路网导致的边界区域路网不连续,从根源上减少间隙。
- 最短路径匹配:不再依赖插值点匹配单条边,而是通过路网节点的最短路径连接多边形顶点,保证路径的连通性。
- 端点去重:拼接路径时跳过相邻边的重复端点,防止路径重叠或错位。
- 闭合处理:手动添加起点作为终点,确保生成的多边形是完整闭合的。
内容的提问来源于stack exchange,提问作者Beatriz Santos
相关产品推荐
相关产品推荐

