Python获取点周围指定半径Polygon/Multi-polygon坐标及scattermapbox绘制
Plotly scattermapbox 绘制指定半径覆盖多边形解决方案
核心问题答复
- 你可以通过先生成圆形多边形坐标、再添加填充trace的方式,实现中心点周围指定英里半径范围的渲染填充
- Mapbox生态有配套工具可以直接生成符合距离要求的多边形几何数据,Python端使用Plotly时也可以通过地理计算库本地生成,无需调用外部接口
方案1:Python本地生成多边形(Plotly场景推荐)
该方案无需依赖Mapbox额外服务,本地即可完成坐标计算,适配Plotly的Python调用场景:
- 单位换算:1英里≈1609.34米,先把你需要的半径值从英里转换为米
- 坐标投影转换:因为WGS84经纬度是球面坐标,直接做缓冲计算会有误差,需要先转到平面的UTM投影,计算完成后再转回到WGS84经纬度
- 生成多边形:对中心点做指定半径的缓冲,得到圆形多边形的顶点坐标
- 接入Plotly:新增
Scattermapboxtrace,设置fill='toself'实现填充效果
示例代码
import math import plotly.graph_objects as go from shapely.geometry import Point from pyproj import Transformer, CRS def generate_circle_polygon(lon: float, lat: float, radius_mile: float, num_points: int = 64) -> list: # 英里转米 radius_m = radius_mile * 1609.34 # 定义WGS84坐标系 wgs84_crs = CRS.from_epsg(4326) # 自动匹配当前中心点所在的UTM投影带,保证平面计算精度 utm_zone = int(math.floor((lon + 180) / 6) + 1) utm_crs = CRS.from_epsg(32600 + utm_zone if lat >= 0 else 32700 + utm_zone) # 定义坐标转换器 trans_to_utm = Transformer.from_crs(wgs84_crs, utm_crs, always_xy=True) trans_to_wgs84 = Transformer.from_crs(utm_crs, wgs84_crs, always_xy=True) # 中心点转UTM坐标后做缓冲,生成圆形 center_utm = Point(trans_to_utm.transform(lon, lat)) circle_utm = center_utm.buffer(radius_m, resolution=num_points) # 转回WGS84经纬度得到多边形顶点列表 return [trans_to_wgs84.transform(*coord) for coord in circle_utm.exterior.coords] # ========== 绘图示例 ========== # 示例POI中心点:纽约帝国大厦 center_lon, center_lat = -73.985422, 40.748817 # 生成5英里半径的圆形多边形 circle_coords = generate_circle_polygon(center_lon, center_lat, radius_mile=5) circle_lon = [x[0] for x in circle_coords] circle_lat = [x[1] for x in circle_coords] fig = go.Figure() # 添加POI散点 fig.add_trace(go.Scattermapbox( lon=[center_lon], lat=[center_lat], mode='markers', marker=dict(size=14, color='crimson'), name='目标POI' )) # 添加半径覆盖填充层 fig.add_trace(go.Scattermapbox( lon=circle_lon, lat=circle_lat, mode='lines', fill='toself', fillcolor='rgba(30, 144, 255, 0.3)', line=dict(width=1, color='dodgerblue'), name='5英里覆盖范围' )) # 配置底图样式 fig.update_layout( mapbox=dict( style='carto-positron', # 无token也可使用的开源底图,也可替换为mapbox官方样式 zoom=9, center=dict(lon=center_lon, lat=center_lat) ), margin=dict(l=0, r=0, t=0, b=0) ) fig.show()
依赖安装:需要提前安装shapely、pyproj、plotly三个库,执行pip install shapely pyproj plotly即可。
方案2:Mapbox前端侧直接生成(自定义前端场景适用)
如果你是基于Mapbox GL JS开发前端应用,不需要手动计算坐标:
- 使用Mapbox生态配套的turf.js库,调用
turf.circle(中心点坐标, 半径, {units: 'miles'})方法,可直接得到符合WGS84标准的圆形多边形GeoJSON - 将生成的GeoJSON作为
fill类型图层添加到Mapbox实例中即可完成渲染,性能和精度都有保障
注意:Python端的Plotly是封装好的组件,无法直接调用前端Mapbox的接口,该方案仅适合自主开发前端Mapbox应用的场景使用。
内容的提问来源于stack exchange,提问作者kms
相关产品推荐
相关产品推荐

