GIS距离计算工具

计算两个经纬度坐标点之间的距离,支持WGS84和CGCS2000坐标系

距离计算器

起点坐标

终点坐标

算法说明

本工具使用 Haversine公式 计算两点之间的球面距离,这是计算地球表面两点间最短距离(大圆距离)的标准方法。

坐标系说明

  • WGS84:世界大地测量系统1984,GPS使用的标准坐标系,椭球长半轴 a = 6378137m
  • CGCS2000(大地2000):中国国家大地坐标系2000,椭球长半轴 a = 6378137m,与WGS84非常接近

由于WGS84和CGCS2000的椭球参数非常接近(差异在厘米级),在大多数应用场景下可以认为两者等效。

代码实现

JavaScript

/**
 * 使用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)} 千米`);

Java

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);
    }
}

Python

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} 千米")