已知两地经纬度,计算两地直线距离

1 原理公式

在地球上,计算两点之间的直线距离通常使用地理坐标系(例如WGS84)。计算两地直线距离的公式是根据经纬度之间的大圆距离(Great Circle Distance)来计算的。该公式基于球面三角学,常用的公式是 H a v e r s i n e Haversine Haversine 公式。

形式一:
d l o n = l o n 2 − l o n 1 d_{lon} = lon_2 - lon_1 dlon=lon2lon1
d l a t = l a t 2 − l a t 1 d_{lat} = lat_2 - lat_1 dlat=lat2lat1
a = s i n 2 ( d l a t / 2 ) + c o s ( l a t 1 ) ∗ c o s ( l a t 2 ) ∗ s i n 2 ( d l o n / 2 ) a = sin²(d_{lat}/2) + cos(lat_1) * cos(lat_2) * sin²(d_{lon}/2) a=sin2(dlat/2)+cos(lat1)cos(lat2)sin2(dlon/2)
c = 2 ∗ a t a n 2 ( a , ( 1 − a ) ) c = 2 * atan^2(\sqrt{a}, \sqrt{(1-a)}) c=2atan2(a ,(1a) )
d = R ∗ c d = R * c d=Rc

形式二:
d = R ∗ a c o s ( s i n ( l o n 1 ) ∗ s i n ( l o n 2 ) + c o s ( l o n 1 ) ∗ c o s ( l o n 2 ) ∗ c o s ( l a t 2 − l a t 1 ) ) d = R*acos(sin(lon_1)*sin(lon_2) + cos(lon_1)*cos(lon_2)*cos(lat_2-lat_1)) d=Racos(sin(lon1)sin(lon2)+cos(lon1)cos(lon2)cos(lat2lat1))

其中:

  • R R R 是地球的半径,约为6371千米。

在这里插入图片描述

请注意,这个公式假设地球是一个完美的球形。实际上,地球的形状更像一个椭球,因此使用更精确的地理信息系统(GIS)软件或库(如proj.4或GeographicLib)可能会得到更准确的结果。

此外,经纬度通常以度为单位,但上述公式中的角度应被视为弧度。如果经纬度是以度数形式给出的,需要将其转换为弧度。可以通过将度数乘以π/180并取整数部分得到弧度值。例如, 30 ° 30° 30°转换为弧度为 π / 180 ∗ 30 π/180*30 π/18030

2 代码实现

2.1 JavaScript

function calculateDistance(lat1, lon1, lat2, lon2) {
    
    
  const R = 6371; // 地球半径,单位为千米
  const rad = (angle) => angle * Math.PI / 180; // 将角度转换为弧度

  const lat1Rad = rad(lat1);
  const lon1Rad = rad(lon1);
  const lat2Rad = rad(lat2);
  const lon2Rad = rad(lon2);

  const dLat = lat2Rad - lat1Rad;
  const dLon = lon2Rad - lon1Rad;

  const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(lat1Rad) * Math.cos(lat2Rad) *
    Math.sin(dLon / 2) * Math.sin(dLon / 2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

  const distance = R * c; // 返回单位为千米的距离
  return distance;
}

// 示例用法
const lat1 = 39.9087; // 北京的经纬度
const lon1 = 116.4074;
const lat2 = 31.2304; // 上海的经纬度
const lon2 = 121.4737;

const distance = calculateDistance(lat1, lon1, lat2, lon2);
console.log(distance); // 输出直线距离(单位:千米)

2.2 C++

#include <cmath>
#include <iostream>

// 计算两个经纬度之间的距离(单位:千米)
double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
    
    
  const double R = 6371; // 地球半径,单位为千米

  // 将经纬度转换为弧度
  double lat1Rad = std::atan(std::tan(lat1 * (M_PI / 180)) * std::cos(lon1 * (M_PI / 180)));
  double lon1Rad = lon1 * (M_PI / 180);
  double lat2Rad = std::atan(std::tan(lat2 * (M_PI / 180)) * std::cos(lon2 * (M_PI / 180)));
  double lon2Rad = lon2 * (M_PI / 180);

  // 计算两个经纬度之间的弧度差
  double dLat = lat2Rad - lat1Rad;
  double dLon = lon2Rad - lon1Rad;

  // 根据球面三角法公式计算距离
  double a = std::sin(dLat / 2) * std::sin(dLat / 2) +
    std::cos(lat1Rad) * std::cos(lat2Rad) *
    std::sin(dLon / 2) * std::sin(dLon / 2);
  double c = 2 * std::atan2(std::sqrt(a), std::sqrt(1 - a));

  // 返回距离
  return R * c;
}

// 示例用法
int main() {
    
    
  double lat1 = 39.9087; // 北京的经纬度
  double lon1 = 116.4074;
  double lat2 = 31.2304; // 上海的经纬度
  double lon2 = 121.4737;

  double distance = calculateDistance(lat1, lon1, lat2, lon2);
  std::cout << "距离:" << distance << " 千米" << std::endl;

  return 0;
}

请注意,此代码使用了C++标准库中的数学函数和常量。此外,将经纬度转换为弧度的方法需要使用std::atan和std::tan函数。

2.3 Python

import math

def calculate_distance(lat1, lon1, lat2, lon2):
    R = 6371  # 地球半径,单位为千米
    rad = lambda angle: angle * math.pi / 180  # 将角度转换为弧度

    lat1_rad = rad(lat1)
    lon1_rad = rad(lon1)
    lat2_rad = rad(lat2)
    lon2_rad = rad(lon2)

    dLat = lat2_rad - lat1_rad
    dLon = lon2_rad - lon1_rad

    a = math.sin(dLat / 2) ** 2 + math.cos(lat1_rad) * math.cos(lat2_rad) * math.sin(dLon / 2) ** 2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))

    distance = R * c  # 返回单位为千米的距离
    return distance

# 示例用法
lat1 = 39.9087  # 北京的经纬度
lon1 = 116.4074
lat2 = 31.2304  # 上海的经纬度
lon2 = 121.4737

distance = calculate_distance(lat1, lon1, lat2, lon2)
print(distance)  # 输出直线距离(单位:千米)

请注意,由于Python和JavaScript之间的一些语法差异,需要使用math模块来进行数学计算。另外,由于Python中没有lambda函数的功能,因此需要使用普通的函数定义来代替。

2.4 MATLAB

function distance = calculateDistance(lat1, lon1, lat2, lon2)
    const R = 6371; % 地球半径,单位为千米

    lat1Rad = rad(lat1);
    lon1Rad = rad(lon1);
    lat2Rad = rad(lat2);
    lon2Rad = rad(lon2);

    dLat = lat2Rad - lat1Rad;
    dLon = lon2Rad - lon1Rad;

    a = sin(dLat / 2) .^ 2 + cos(lat1Rad) .* cos(lat2Rad) .* sin(dLon / 2) .^ 2;
    c = 2 * atan2(sqrt(a), sqrt(1 - a));

    distance = R * c; % 返回单位为千米的距离
end

% 示例用法
lat1 = 39.9087; % 北京的经纬度
lon1 = 116.4074;
lat2 = 31.2304; % 上海的经纬度
lon2 = 121.4737;

distance = calculateDistance(lat1, lon1, lat2, lon2);
disp(distance); % 输出直线距离(单位:千米)

请注意,MATLAB中的函数定义以function开头,输入参数以逗号分隔,输出结果使用变量名返回。此外,MATLAB中用.*表示元素之间的相乘,而^表示乘方。最后,使用disp函数输出结果。

猜你喜欢

转载自blog.csdn.net/weixin_46098577/article/details/132553284