You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将地图多边形近似为路网内多边形?求更优实现方案

解决:生成贴合路网的近似多边形(消除间隙问题)

问题背景

我处理地图多边形数据,拥有一个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,对每条边插值生成点后匹配最近路网边,但最终结果的多边形间存在多处间隙,需要更精准的实现方案。


改进方案

核心思路

  1. 全局路网统一构建:计算所有多边形的整体边界框,一次性获取完整路网,避免局部路网缺失导致的间隙。
  2. 最短路径替代单边匹配:针对多边形的每个顶点对,计算路网中的最短路径,保证路径连续无断点。
  3. 路径去重与闭合处理:拼接路径时去除重复端点,最终手动闭合多边形。

完整实现代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:05:55