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

news2025/1/15 12:46:10

文章目录

  • 1 原理公式
  • 2 代码实现
    • 2.1 JavaScript
    • 2.2 C++
    • 2.3 Python
    • 2.4 MATLAB

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函数输出结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/944726.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言练习题解析:挑战与突破,开启编程新篇章!(1)

&#x1f493;博客主页&#xff1a;江池俊的博客⏩收录专栏&#xff1a;C语言刷题专栏&#x1f449;专栏推荐&#xff1a;✅C语言初阶之路 ✅C语言进阶之路&#x1f4bb;代码仓库&#xff1a;江池俊的代码仓库&#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐&a…

正则表达式 之 断言详解

正则表达式的先行断言和后行断言一共有 4 种形式&#xff1a; (?pattern) 零宽正向先行断言(zero-width positive lookahead assertion)(?!pattern) 零宽负向先行断言(zero-width negative lookahead assertion)(?<pattern) 零宽正向后行断言(zero-width positive lookb…

QML Book 学习基础5(An Image Viewer)

目录 桌面版&#xff08;win端&#xff09; 移动端 下面我们用更有挑战性例子来使用Qt控件&#xff0c;将创建一个简单的图像查看器。 桌面版&#xff08;win端&#xff09; 程序主要由四个主要区域组成&#xff0c;如下所示。菜单栏、工具栏和状态栏&#xff0c;通常由控件…

ApiPost软件会对数据进行预处理,有可能会导致数据报错

文章目录 测试数据正确的请求方式当URL有数据被修改之后&#xff08;数据就不一致了&#xff09; 测试数据 %257B%2522pageNum%2522:1,%2522pageSize%2522:10,%2522param%2522:%257B%2522flowType%2522:1,%2522workcardType%2522:%2522作者的请求方便大家一键复制 localhost:…

记录windows7无权安装

项目场景&#xff1a; electron 安装程序 windows上的C盘 progrom files 、 问题描述 安装过程中出现 不能打开写入文件 提示如上。 { "name": "intergeOM-goldwind","version": "1.0.0","author": "weile",&q…

事业单位D类 — — 理论攻坚-主题班会

一、书写模版 &#xff08;一&#xff09;活动主题 1.书写模板 &#xff08;1&#xff09;&#xff08;主动学习&#xff09;&#xff0c;从我做起/我能行&#xff1b;做&#xff08;环保、诚信&#xff09;卫士/标兵&#xff1b;&#xff08;网络安全、诚信&#xff09;伴…

RealVNC配置自定义分辨率(AlmaLinux 8)

RealVNC 配置自定义分辨率&#xff08;AlmaLinux8&#xff09; 参考RealVNC官网 how to set up resolution https://help.realvnc.com/hc/en-us/articles/360016058212-How-do-I-adjust-the-screen-resolution-of-a-virtual-desktop-under-Linux-#standard-dummy-driver-0-2 …

Linux操作系统的基本配置操作

Linux操作系统的基本操作 一、和网络有关的Linux操作二、网络如果修改完成&#xff0c;需要重启Linux的网卡服务三、在Linux上还有一个网络服务NetworkManagaer四、Linux上还有一个服务叫做firewalld&#xff08;防火墙的服务&#xff09;五、Linux安装的节点服务器我们一般都是…

数据结构体--5.0图

目录 一、定义 二、图的顶点与边之间的关系 三、图的顶点与边之间的关系 四、连通图 五、连通图的生成树定义 一、定义 图&#xff08;Graph&#xff09;是由顶点的又穷非空集合合顶点之间边的集合组成&#xff0c;通常表示为&#xff1a;G&#xff08;V&#xff0c;E&…

中国知网账号包月多少钱?怎样知网包月最划算

中国知网是我们在查找下载论文资料时常用的中文数据库&#xff0c;也是全球最大的中文数据库之一。那么&#xff0c;中国知网是否可以包月使用呢&#xff1f;包月费用又是多少呢&#xff1f;如何包月最划算呢&#xff1f;下面本文将为您一一解答。 一、中国知网可包月使用吗&a…

C 语言不同类型变量之间的大小比较

1. 示例代码&#xff1a; #include <stdio.h>int main(void) {int a -1;unsigned int b 1;if (a b) {printf("a b\n");} else if (a < b) {printf("a < b\n");} else {printf("a > b\n");}return 0; } 2. 输出结果&#xff…

用变压器实现德-英语言翻译【01/8】:嵌入层

一、说明 本文是“用变压器实现德-英语言翻译”系列的第一篇文章。它引入了小规模的嵌入来建立感知系统。接下来是嵌入层的变压器使用。下面简要概述了每种方法&#xff0c;然后是德语到英语的翻译。 二、技术背景 嵌入层的目标是使模型能够详细了解单词、标记或其他输入之间的…

简易虚拟培训系统-UI控件的应用2

目录 Text组件-文字显示 Text组件-文字动态显示 ScrollView组件 使用文件流动态读取硬盘文件 本篇介绍Text和ScrollView的简单应用&#xff0c;以及读取硬盘中.txt文本的内容 Text组件-文字显示 1. 加入Text&#xff1a;在mainCanvas上点右键->UI->选择Text和TextMe…

CocosCreator组件上的schedule

目录 1.首先看component.ts中schedule 函数&#xff0c;核心代码就是获取director.getScheduler()&#xff0c;并调用schedule方法&#xff0c;把callback等参数传递进去。 2.再看到scheduler.ts类中的schedule方法&#xff0c;只取一些主要代码&#xff0c;下面会分段详细拆…

dockerfile 例子(二)

Dockerfile由一行一行的命令语句组成&#xff0c;#开头的为注释行。Dockerfile文件内容分为四个部分&#xff1a;基础镜像信息、维护者信息、镜像操作指令以及容器启动执行指令。 接下来给大家列出Dockerfile中主要命令的说明。 FROM&#xff0c;指定所创建镜像的基础镜像。 …

Verilog基础:块语句

相关阅读 Verilog基础专栏https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 1、块语句 块语句(block statements)是一种把语句组织在一起&#xff0c;这样他们在语法上就像单个语句一样工作。Verilog HDL中有两种类型的块&#xff1a; …

“惠医通-医院挂号订单平台”

结合已学习过的vue3和TS完成的项目&#xff0c;便于患者对自己想要就诊的科室进行挂号&#xff0c;付款 一&#xff1a;项目简介 前端技术栈 Vue3 TS vue-router Element-ui Axios Pinia 项目架构 二&#xff1a;主要模块 1. axios二次封装 1.1 创建实例 //利用axios.creat…

如何调整DOSBOX软件的运行窗口大小

前言 小编最近正在学习微机原理&#xff0c;碰到一些问题&#xff0c;在安装DOSBOX后&#xff0c;打开应用&#xff0c;会出现运行窗口特别小&#xff0c;字体也很小的情况&#xff0c;使用时会感觉特别费劲&#xff0c;看着特别的不舒服&#xff0c;那么这个时候就需要调整一…

【LeetCode题目详解】第八章 贪心算法 part01 理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和 day31补

贪心算法理论基础 关于贪心算法&#xff0c;你该了解这些&#xff01; 题目分类大纲如下&#xff1a; # 什么是贪心 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 这么说有点抽象&#xff0c;来举一个例子&#xff1a; 例如&#xff0c;有一堆钞票&…

【C#】C#:“指派给常量数组的必须是常量”

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 记录一个有意思的代码片段。 首先&#xff0c;复习一下常量。…