获取多边形经纬度顶点坐标 用于绘制Plotly Choropleth地图
从经纬度散点提取多边形顶点用于Plotly Choropleth绘制
需要从给定的经纬度散点列表中提取多边形顶点坐标,以便在Python中使用Plotly Choropleth绘制多边形。当前挑战是这些经纬度点分布在美国某城市范围内,较为分散。试过基于BFS算法的实现,但它仅适用于整数坐标且点需处于相邻网格;其他方案多采用OpenCV,需调整才能适配经纬度数据。考虑过正交复合凸包算法,但未找到对应的Python实现。
经纬度样本列表
# Sample list of latitudes and longitudes coords = [ [-86.496774, 32.344437], [-86.717897, 32.402814], [-86.814912, 32.340803], [-86.890581, 32.502974], [-86.917595, 32.664169], [-86.71339, 32.661732], [-86.714219, 32.705694], [-86.413116, 32.707386], [-86.411172, 32.409937], [-86.496774, 32.344437], [-86.577799, 33.765316], [-86.759144, 33.840617], [-86.953664, 33.815297], [-86.954305, 33.844862], [-86.96296, 33.844865], [-86.963358, 33.858221], [-86.924387, 33.909222], [-86.793914, 33.952059], [-86.685365, 34.05914], [-86.692061, 34.092654], [-86.599632, 34.119914], [-86.514881, 34.25437], [-86.45302, 34.259317], [-86.303516, 34.099073], [-86.332723, 33.986109], [-86.370152, 33.93977], [-86.325622, 33.940147], [-86.377532, 33.861706], [-86.577528, 33.801977], [-86.577799, 33.765316] ]
解决方案与实现建议
1. 凸包算法(快速实现基础多边形)
Scipy的ConvexHull支持浮点数坐标,能直接处理经纬度数据,适合提取点集的外边界。如果样本包含多个独立区域(比如你的数据里有两个闭合块),需要先聚类拆分点集再分别计算凸包。
代码示例(单区域凸包)
from scipy.spatial import ConvexHull import numpy as np # 转换为numpy数组 points = np.array(coords) # 计算凸包 hull = ConvexHull(points) # 提取凸包顶点(按逆时针顺序排列) hull_vertices = points[hull.vertices].tolist() # 闭合多边形(首尾点相同) hull_vertices.append(hull_vertices[0]) print("凸包顶点坐标:") print(hull_vertices)
处理多区域:先聚类再凸包
用DBSCAN根据地理距离聚类,拆分独立点集:
from sklearn.cluster import DBSCAN from sklearn.metrics.pairwise import haversine_distances import numpy as np # 转换为弧度(haversine距离需要) coords_rad = np.radians(points) # 计算两两地理距离(单位:米) distances = haversine_distances(coords_rad) * 6371000 # 地球半径6371km # DBSCAN聚类:eps设为500米(可根据点密度调整),min_samples设为3 dbscan = DBSCAN(eps=500, min_samples=3, metric="precomputed") clusters = dbscan.fit_predict(distances) # 对每个簇计算凸包 polygons = [] for cluster_id in np.unique(clusters): if cluster_id == -1: continue # 跳过噪声点 cluster_points = points[clusters == cluster_id] hull = ConvexHull(cluster_points) cluster_polygon = cluster_points[hull.vertices].tolist() cluster_polygon.append(cluster_polygon[0]) polygons.append(cluster_polygon) print("多区域多边形顶点:") for i, poly in enumerate(polygons): print(f"区域{i+1}:{poly}")
2. Alpha Shape算法(生成贴合的凹多边形)
凸包只能生成凸边界,Alpha Shape可以生成更贴合实际的凹多边形,适合城市这类不规则区域。使用第三方库alphashape实现:
代码示例
import alphashape from shapely.geometry import Polygon # 生成alpha shape多边形,alpha值越小边界越贴合(需根据点密度调整) alpha = 0.001 shape = alphashape.alphashape(coords, alpha) # 提取顶点坐标(如果是MultiPolygon,需遍历每个子多边形) if isinstance(shape, Polygon): polygon_vertices = list(shape.exterior.coords) else: polygon_vertices = [] for poly in shape.geoms: polygon_vertices.append(list(poly.exterior.coords)) print("Alpha Shape多边形顶点:") print(polygon_vertices)
3. Plotly Choropleth适配
将提取的多边形顶点转换为Plotly要求的GeoJSON格式,即可用于Choropleth绘制:
import plotly.express as px import json # 构造GeoJSON geojson = { "type": "FeatureCollection", "features": [] } for i, poly in enumerate(polygons): feature = { "type": "Feature", "properties": {"id": i+1}, "geometry": { "type": "Polygon", "coordinates": [poly] } } geojson["features"].append(feature) # 绘制Choropleth fig = px.choropleth_mapbox( geojson=geojson, locations=[f"{i+1}" for i in range(len(polygons))], featureidkey="properties.id", mapbox_style="carto-positron", center={"lat": 33.0, "lon": -86.6}, zoom=8 ) fig.show()
内容的提问来源于stack exchange,提问作者prasanth_ntu
相关产品推荐
相关产品推荐

