计算两个经纬度坐标点之间的距离,支持WGS84和CGCS2000坐标系
本工具使用 Haversine公式 计算两点之间的球面距离,这是计算地球表面两点间最短距离(大圆距离)的标准方法。
由于WGS84和CGCS2000的椭球参数非常接近(差异在厘米级),在大多数应用场景下可以认为两者等效。
/**
* 使用Haversine公式计算两个经纬度点之间的距离
* @param {number} lat1 - 起点纬度
* @param {number} lng1 - 起点经度
* @param {number} lat2 - 终点纬度
* @param {number} lng2 - 终点经度
* @param {string} crs - 坐标系 ('WGS84' | 'CGCS2000')
* @returns {number} 距离(米)
*/
function calculateDistance(lat1, lng1, lat2, lng2, crs = 'WGS84') {
// 椭球长半轴(米)
const radius = {
'WGS84': 6378137,
'CGCS2000': 6378137
}[crs] || 6378137;
const toRad = (deg) => deg * Math.PI / 180;
const dLat = toRad(lat2 - lat1);
const dLng = toRad(lng2 - lng1);
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(toRad(lat1)) * Math.cos(toRad(lat2)) *
Math.sin(dLng / 2) * Math.sin(dLng / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return radius * c;
}
// 使用示例
const distance = calculateDistance(39.90923, 116.397428, 31.239703, 121.499718);
console.log(`距离: ${distance.toFixed(2)} 米`);
console.log(`距离: ${(distance / 1000).toFixed(4)} 千米`);import java.lang.Math;
public class GisDistanceCalculator {
// 椭球长半轴(米)
private static final double WGS84_RADIUS = 6378137.0;
private static final double CGCS2000_RADIUS = 6378137.0;
/**
* 使用Haversine公式计算两个经纬度点之间的距离
* @param lat1 起点纬度
* @param lng1 起点经度
* @param lat2 终点纬度
* @param lng2 终点经度
* @param crs 坐标系 ("WGS84" | "CGCS2000")
* @return 距离(米)
*/
public static double calculateDistance(double lat1, double lng1,
double lat2, double lng2,
String crs) {
double radius = "CGCS2000".equals(crs) ? CGCS2000_RADIUS : WGS84_RADIUS;
double dLat = Math.toRadians(lat2 - lat1);
double dLng = Math.toRadians(lng2 - lng1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLng / 2) * Math.sin(dLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return radius * c;
}
public static void main(String[] args) {
// 北京天安门到上海东方明珠
double distance = calculateDistance(39.90923, 116.397428,
31.239703, 121.499718, "WGS84");
System.out.printf("距离: %.2f 米%n", distance);
System.out.printf("距离: %.4f 千米%n", distance / 1000);
}
}import math
from typing import Literal
def calculate_distance(
lat1: float,
lng1: float,
lat2: float,
lng2: float,
crs: Literal["WGS84", "CGCS2000"] = "WGS84"
) -> float:
"""
使用Haversine公式计算两个经纬度点之间的距离
Args:
lat1: 起点纬度
lng1: 起点经度
lat2: 终点纬度
lng2: 终点经度
crs: 坐标系 ('WGS84' | 'CGCS2000')
Returns:
距离(米)
"""
# 椭球长半轴(米)
radius = {
"WGS84": 6378137,
"CGCS2000": 6378137
}.get(crs, 6378137)
d_lat = math.radians(lat2 - lat1)
d_lng = math.radians(lng2 - lng1)
a = (math.sin(d_lat / 2) ** 2 +
math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) *
math.sin(d_lng / 2) ** 2)
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
return radius * c
if __name__ == "__main__":
# 北京天安门到上海东方明珠
distance = calculate_distance(39.90923, 116.397428, 31.239703, 121.499718)
print(f"距离: {distance:.2f} 米")
print(f"距离: {distance / 1000:.4f} 千米")