🌍 经纬度直线距离计算(Haversine公式)

📐 算法原理与公式

在这里插入图片描述

  • R:地球半径(6378137米)
  • φ:纬度(弧度)
  • λ:经度(弧度)
  • Δφ:纬度差
  • Δλ:经度差

🔍 Haversine公式实现

private static double Distance(double lon1, double lat1, double lon2, double lat2)
{
    double R = 6378137; // 地球赤道半径(WGS84标准)
    
    // 角度转弧度(三角函数需要弧度输入)
    lat1 = lat1 * Math.PI / 180.0;  // φ₁ → 弧度
    lat2 = lat2 * Math.PI / 180.0;  // φ₂ → 弧度
    
    // 计算纬度差的一半的正弦值
    double sa2 = Math.Sin((lat1 - lat2) / 2.0);  // sin(Δφ/2)
    
    // 计算经度差的一半的正弦值(先转弧度)
    double sb2 = Math.Sin(((lon1 - lon2) * Math.PI / 180.0) / 2.0);  // sin(Δλ/2)
    
    // Haversine核心公式:
    // a = sin²(Δφ/2) + cos(φ₁)cos(φ₂)sin²(Δλ/2)
    double a = sa2 * sa2 + Math.Cos(lat1) * Math.Cos(lat2) * sb2 * sb2;
    
    // 球面距离公式:d = 2R * arcsin(√a)
    return 2 * R * Math.Asin(Math.Sqrt(a));
}

📊 可视化计算流程

在这里插入图片描述


⚙️ C# 完整实现

using System;

public static class GeoDistanceCalculator
{
    // 地球赤道半径(WGS84标准)
    private const double EarthRadius = 6378137.0; 

    public static double CalculateDistance(double lon1, double lat1, double lon2, double lat2)
    {
        // 角度转弧度
        double radLat1 = lat1 * Math.PI / 180.0;
        double radLat2 = lat2 * Math.PI / 180.0;
        double radLonDiff = (lon2 - lon1) * Math.PI / 180.0;

        // 计算差值
        double sinHalfLatDiff = Math.Sin((radLat1 - radLat2) / 2.0);
        double sinHalfLonDiff = Math.Sin(radLonDiff / 2.0);

        // Haversine公式
        double a = sinHalfLatDiff * sinHalfLatDiff +
                   Math.Cos(radLat1) * Math.Cos(radLat2) *
                   sinHalfLonDiff * sinHalfLonDiff;

        // 球面距离计算
        return 2 * EarthRadius * Math.Asin(Math.Sqrt(a));
    }
}

⚙️ C++ 完整实现

#include <cmath>

class GeoDistanceCalculator {
public:
    static constexpr double EarthRadius = 6378137.0; // WGS84标准

    static double CalculateDistance(
        double lon1, double lat1, 
        double lon2, double lat2) 
    {
        // 角度转弧度
        double radLat1 = deg2rad(lat1);
        double radLat2 = deg2rad(lat2);
        double radLonDiff = deg2rad(lon2 - lon1);

        // 三角计算
        double sinHalfLatDiff = sin((radLat1 - radLat2) / 2.0);
        double sinHalfLonDiff = sin(radLonDiff / 2.0);

        // Haversine公式
        double a = sinHalfLatDiff * sinHalfLatDiff +
                   cos(radLat1) * cos(radLat2) *
                   sinHalfLonDiff * sinHalfLonDiff;

        // 球面距离计算
        return 2.0 * EarthRadius * asin(sqrt(a));
    }

private:
    static double deg2rad(double degrees) {
        return degrees * M_PI / 180.0;
    }
};

📌 关键注意事项

  1. 精度范围:适用于300km内计算(超过需考虑地球扁率)
  2. 性能优化:避免重复计算三角函数值
  3. 地球模型:WGS84标准半径(极半径6356752m,扁率1/298.257)
  4. 误差来源
    • 未考虑海拔高度
    • 地球非完美球体
    • 大规模距离计算时的球面近似误差

🌐 地球模型示意图

在这里插入图片描述

通过Haversine公式实现的高效距离计算,完美平衡了精度与计算效率,是GIS系统中位置服务的核心算法之一。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐