请教:如何用Python根据已知的经纬度坐标在地图上给定半径画圆
最近项目上需要在地图上根据商圈经纬度坐标画圆,用来确定两个坐标范围是否有重合,然后再将该圆形区域标记成等面积的 n 块。
然后遍历数据库里的坐标,判断坐标属于哪个商圈区块。
现在卡在了,不知道如何利用经纬度在地图上画圆,请教各位大佬,有什么方法能够实现!
谢谢
请教:如何用Python根据已知的经纬度坐标在地图上给定半径画圆
画圆的目的是判断两个坐标是否重合?还是要在地图上画一个圆形出来?
import numpy as np
import matplotlib.pyplot as plt
from shapely.geometry import Point
from shapely.ops import transform
import pyproj
def draw_circle_on_map(center_lat, center_lon, radius_km, num_points=100):
"""
根据经纬度中心点和半径(公里)在地图上画圆
参数:
center_lat: 中心点纬度
center_lon: 中心点经度
radius_km: 圆半径(公里)
num_points: 圆的点数(默认100)
"""
# 创建中心点
center_point = Point(center_lon, center_lat)
# 定义投影转换:WGS84经纬度 -> UTM投影(用于计算距离)
wgs84 = pyproj.CRS('EPSG:4326')
# 自动选择UTM区域
utm_zone = int((center_lon + 180) / 6) + 1
utm_crs = pyproj.CRS(f'EPSG:326{utm_zone:02d}' if center_lat >= 0 else f'EPSG:327{utm_zone:02d}')
# 创建投影转换器
transformer = pyproj.Transformer.from_crs(wgs84, utm_crs, always_xy=True)
# 将中心点转换到UTM坐标
center_utm = transform(transformer.transform, center_point)
# 在UTM坐标系中创建圆
angles = np.linspace(0, 2 * np.pi, num_points)
circle_points_utm = []
for angle in angles:
# 计算圆上的点(UTM坐标)
x = center_utm.x + radius_km * 1000 * np.cos(angle) # 公里转米
y = center_utm.y + radius_km * 1000 * np.sin(angle)
circle_points_utm.append(Point(x, y))
# 将圆点转换回经纬度
transformer_back = pyproj.Transformer.from_crs(utm_crs, wgs84, always_xy=True)
circle_points_wgs84 = [transform(transformer_back.transform, pt) for pt in circle_points_utm]
# 提取经纬度坐标
lons = [pt.x for pt in circle_points_wgs84]
lats = [pt.y for pt in circle_points_wgs84]
return lons, lats
# 使用示例
if __name__ == "__main__":
# 示例:以北京天安门为中心,画一个50公里半径的圆
center_lat = 39.9042 # 纬度
center_lon = 116.4074 # 经度
radius_km = 50
# 获取圆的经纬度坐标
circle_lons, circle_lats = draw_circle_on_map(center_lat, center_lon, radius_km)
# 可视化
plt.figure(figsize=(10, 8))
plt.plot(circle_lons, circle_lats, 'b-', linewidth=2, label=f'{radius_km}km半径')
plt.plot(center_lon, center_lat, 'ro', markersize=10, label='中心点')
plt.xlabel('经度')
plt.ylabel('纬度')
plt.title(f'以({center_lat}, {center_lon})为中心,{radius_km}公里半径的圆')
plt.legend()
plt.grid(True, alpha=0.3)
plt.axis('equal')
plt.show()
# 打印前5个点的坐标
print("圆的前5个点坐标:")
for i in range(5):
print(f"点{i+1}: 经度={circle_lons[i]:.6f}, 纬度={circle_lats[i]:.6f}")
核心思路:
- 使用
pyproj进行坐标投影转换,因为经纬度是球面坐标,不能直接使用平面几何 - 先将中心点转换到UTM投影坐标系(平面直角坐标系)
- 在UTM坐标系中用三角函数计算圆上的点
- 将圆点坐标转换回WGS84经纬度坐标系
需要的库:
pip install numpy matplotlib shapely pyproj
关键点:
- 必须进行投影转换,直接在经纬度上画圆会变形
- UTM投影适合小范围区域的距离计算
- 使用
shapely处理几何对象更方便
一句话建议:用投影转换解决球面坐标画圆问题。
圆上的点到圆心距离是相同的,你每隔一个角度计算出另一端的坐标就可以了,一般用等角线算法,距离很长的话可以用大圆算法
图层覆盖物,圆形的直径 /半径预先计算好,然后描绘的时候,将圆形对准坐标点。
画圆就简单了吧,前段用样式或者画布都可以,app 也类似
我做过一个类似 LBS,不过要求不太严格,经纬度要先转化成米的空间尺度计算。经纬度公式、转化代码网上能查到很多。
画圈嘛,很简单,比如取 60 个采样点的平滑程度,把 360 度 60 等分,有了圆心半径,就知道采样点位置了,每个点连线不就好了。
“经纬度要先转化成米的空间尺度计算”
补充下这个,就是取个位置点作为空间原点,然后计算其他位置在该相对坐标系下的数值。
在地图上画出圆形
最简单的方法:
把商铺的经纬度位置放入 redis,存为 geohash,
然后 redis 的 api 可以根据给定的坐标和半径返回范围内的全部商铺.
这其实就是根据 geohash 的特性做文章.
复杂点的就是 postgres+postgis 做空间数据库,直接进行空间查询.
你的需求是在地图上画图?用的什么地图控件?

