关于将经纬度坐标转换为适用于距离计算的米制XY坐标的技术咨询
将经纬度坐标转换为适用于距离计算的米制XY坐标的技术咨询
嘿,这个问题我之前处理过!你碰到的核心问题是选了不合适的投影坐标系——EPSG:3857(Web墨卡托)本来就不是为精确距离/几何计算设计的,它的强项是适配网页地图的可视化,但在高纬度地区会有严重的尺度变形,这就是为啥你算出来两个不同纬度的区间距离完全一样的原因。
给你两个靠谱的解决方案,都能满足你3km小范围集群的精确计算需求:
优先用UTM投影(最通用、易实现)
UTM(通用横轴墨卡托)是分带设计的,每6个经度一个带,每个带内的尺度变形小于1%,完全能覆盖你3km的计算精度要求。关键是要给每个集群匹配对应的UTM带:- 先计算点所在的UTM带:公式是
utm_zone = int((经度 + 180) / 6) + 1 - 北半球的UTM带EPSG代码是
326{带号},南半球是327{带号}(你是美国的点,基本都是北半球,用326开头的) - 用pyproj转换的示例代码:
import pyproj from pyproj import Transformer # 拿你提到的(-90., 50.)举例 lon, lat = -90.0, 50.0 # 计算UTM带号 utm_zone = int((lon + 180) / 6) + 1 # 构建对应的UTM坐标系 crs_utm = f"EPSG:326{utm_zone}" # 创建转换器(注意always_xy=True,因为EPSG:4326是先经度后纬度) transformer = Transformer.from_crs("EPSG:4326", crs_utm, always_xy=True) # 转换后的x、y就是米为单位的坐标 x, y = transformer.transform(lon, lat)
转换后你再做距离计算、点-in-多边形判断,结果就和实际地理位置的精度一致了。
- 先计算点所在的UTM带:公式是
备选:美国州平面坐标系(更精准但复杂)
如果你需要极致精度,可以用美国的州平面坐标系(State Plane Coordinate System),每个州有自己专属的投影,变形更小,但需要你明确每个集群所在的州,然后找到对应的EPSG代码,实现起来比UTM麻烦一点,所以如果UTM能满足需求,优先选它。
再补一句为啥EPSG:3857不行:Web墨卡托为了把地球变成正方形适配网页,强行拉伸了高纬度区域的经度方向,导致相同的坐标差在不同纬度对应的实际距离差完全不一样——你测试的50°N区域,实际1度经度的距离比30°N短很多,但3857里的坐标差是一样的,自然算出来的距离就错了。
备注:内容来源于stack exchange,提问作者user1554752




