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

获取多边形经纬度顶点坐标 用于绘制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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 08:15:34