计算两个经纬度之间的球面距离(基于Mysql和PHP实现)

news2024/11/17 5:54:41

计算两个经纬度之间的球面距离

1、MySQL实现方式 - 基于空间函数(ST_Distance_Sphere)实现

前置条件:确保您使用的是 MySQL 8.0 或更高版本,因为较早的版本对地理空间的支持有限。

1.1 创建表和索引

说明:设置 location 为 point 类型

# 建表
CREATE TABLE `test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `location` point NOT NULL,
  `name` varchar(30) NOT NULL,
  PRIMARY KEY (`id`),
  SPATIAL KEY `sp_index` (`location`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;

# 创建空间索引
CREATE SPATIAL INDEX sp_index ON `test` (location);

1.2 添加模拟数据

方式一:

INSERT INTO test (location,name) VALUES ( ST_GeomFromText('POINT(121.675702 31.281530)'),'恒越荣新广场');

方式二:

INSERT INTO test (location,name) VALUES ( POINT(121.675702,31.281530),'恒越荣新广场');

1.3 根据定位查询与目标位置的距离并排序

定位:121.658889,31.26485

SELECT *, ST_Distance_Sphere(location, Point(121.658889,31.26485)) AS distance
FROM test
ORDER BY distance asc;

查询结果:
说明: distance的单位: 米
在这里插入图片描述

2、MySQL实现方式 - 基于自定义函数实现

2.1 创建表和索引

说明:设置 location 为 varchar 类型,格式: 经度,纬度

# 建表
CREATE TABLE `test1` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `location` varchar(30) NOT NULL,
  `name` varchar(30) NOT NULL,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;

# 创建普通索引
ALTER TABLE `test1` ADD INDEX(`location`);

2.2 添加模拟数据

INSERT INTO test1 (location,name) VALUES ('121.675702,31.28153','恒越荣新广场');
INSERT INTO test1 (location,name) VALUES ('121.673772,31.2799','华美新苑');
INSERT INTO test1 (location,name) VALUES ('121.658889,31.26485','金泰广场');

2.3 封装计算函数

CREATE DEFINER = CURRENT_USER FUNCTION `calculate_distance_from_comma_separated`(`loc1` VARCHAR(50), `loc2` VARCHAR(50))
RETURNS DECIMAL(10,2)
DETERMINISTIC
BEGIN
    DECLARE lon1 DECIMAL(10, 7);
    DECLARE lat1 DECIMAL(9, 6);
    DECLARE lon2 DECIMAL(10, 7);
    DECLARE lat2 DECIMAL(9, 6);
    DECLARE earth_radius DECIMAL(10, 2) DEFAULT 6371.0; -- 地球平均半径,单位:千米
    DECLARE lat1_rad DECIMAL(11, 7);
    DECLARE lon1_rad DECIMAL(11, 7);
    DECLARE lat2_rad DECIMAL(11, 7);
    DECLARE lon2_rad DECIMAL(11, 7);
    DECLARE distance DECIMAL(10, 2);

    SET lon1 = CAST(SUBSTRING_INDEX(loc1, ',', 1) AS DECIMAL(10, 7));
    SET lat1 = CAST(SUBSTRING_INDEX(loc1, ',', -1) AS DECIMAL(9, 6));
    SET lon2 = CAST(SUBSTRING_INDEX(loc2, ',', 1) AS DECIMAL(10, 7));
    SET lat2 = CAST(SUBSTRING_INDEX(loc2, ',', -1) AS DECIMAL(9, 6));

    SET lon1_rad = RADIANS(lon1);
    SET lat1_rad = RADIANS(lat1);
    SET lon2_rad = RADIANS(lon2);
    SET lat2_rad = RADIANS(lat2);

    SET distance = earth_radius * ACOS(SIN(lat1_rad) * SIN(lat2_rad) + COS(lat1_rad) * COS(lat2_rad) * COS(lon2_rad - lon1_rad));

    RETURN distance;
END;

2.4 根据定位查询与目标位置的距离并排序

定位:121.658889,31.26485

SELECT *,(calculate_distance_from_comma_separated(location,'121.658889,31.26485')) AS distance
FROM test1
ORDER BY distance asc;

查询结果:
说明: distance的单位: 千米
在这里插入图片描述

3、PHP实现方式

3.1 函数封装

说明: 单位: 千米

<?php

/**
 * 计算两个定位的球面距离
 * @param $longitude1 string 经度1
 * @param $latitude1 string 纬度1
 * @param $longitude2 string 经度2
 * @param $latitude2 string 纬度2
 * @return float|int
 */
function calculateDistance($latitude1, $longitude1, $latitude2, $longitude2)
{
    $earthRadius = 6371; // 地球平均半径,单位:千米

    $lat1 = deg2rad($latitude1);
    $lon1 = deg2rad($longitude1);
    $lat2 = deg2rad($latitude2);
    $lon2 = deg2rad($longitude2);

    $distance = acos(sin($lat1) * sin($lat2) + cos($lat1) * cos($lat2) * cos($lon2 - $lon1)) * $earthRadius;

    return $distance;
}

$longitude1 = 121.658889;
$latitude1 = 31.26485;
$longitude2 = 121.675702;
$latitude2 = 31.28153;

$distance = calculateDistance($latitude1, $longitude1, $latitude2, $longitude2);
echo sprintf('%.2f', $distance); # 输出: 2.45
?>

4、其他工具

4.1 经纬度查询

https://jingweidu.bmcx.com/

4.2 经纬度距离计算

https://tools.fun/distance.html

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

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

相关文章

Wireshark - tshark支持iptables提供数据包

tshark现在的数据包获取方式有两种&#xff0c;分别是读文件、网口监听&#xff08;af-packet原始套接字&#xff09;。两种方式在包获取上&#xff0c;都是通过读文件的形式&#xff1b;存在文件io操作&#xff0c;在专门处理大流量的情境下&#xff0c; 我们复用wireshark去做…

DNS访问百度

DNS&#xff0c;英文全称是 domain name system&#xff0c;域名解析系统&#xff0c;它的作用也很明确&#xff0c;就是域名和 IP 相互映射。 假设你要查询 baidu.com 的 IP 地址: 首先会查找浏览器的缓存,看看是否能找到 baidu.com 对应的IP地址&#xff0c;找到就直接返回&…

【NOI-题解】1326. 需要安排几位师傅加工零件1228. 排队打水问题1229. 拦截导弹的系统数量求解

文章目录 一、前言二、问题问题&#xff1a;1326. 需要安排几位师傅加工零件问题&#xff1a;1228. 排队打水问题问题&#xff1a;1229. 拦截导弹的系统数量求解 三、感谢 一、前言 本章节主要对贪心问题进行讲解&#xff0c;包括《1326. 需要安排几位师傅加工零件》《1228. 排…

【嵌入式】探索嵌入式世界:在ARM上构建俄罗斯方块游戏的奇妙之旅

文章目录 前言&#xff1a;1. 简介2. 总体设计思路及功能描述2.1 设计思路2.2 功能描述2.3 程序流程图 3. 各部分程序功能及详细说明3.1 游戏界面函数3.1.1 游戏界面中的图片显示3.1.2 游戏开始界面3.1.3 游戏主界面3.1.4 游戏结束广告界面3.1.5 游戏界面中的触摸反馈3.1.6 游戏…

关于 Mybatis 的开启二级缓存返回对象不一致问题

做实验报告的时候&#xff0c;跟着学习&#xff0c;发现我已经将 开启 二级缓存的 配置都配置好了&#xff0c;但是返回值地址不一致&#xff0c;说明对象不一致&#xff0c;二级缓存命中失败。 跟着流程配置&#xff1a; mybatis-config <settings><!-- 启用 myba…

mst[讲课留档]

最小生成树(Minimum Spanning Tree) (1)概念 我们知道&#xff0c;树是有 n n n个结点&#xff0c; n − 1 n-1 n−1条边的无向无环的连通图。 一个连通图的生成树是一个极小的连通子图&#xff0c;它包含图中全部的 n n n个顶点&#xff0c;但只有构成一棵树的 n − 1 n-1 …

实验五 计数器的设计与仿真

仿真 链接&#xff1a;https://pan.baidu.com/s/1N1nR39Gws59laVZY2slzBw 提取码&#xff1a;01ct 一、实验目的 1、通过实验&#xff0c;能熟悉QUARTUS开发环境&#xff0c;能够掌握VHDL设计电路&#xff0c;掌握使用相关仿真工具进行功能和时序仿真的方法&#xff1b; 2、通…

.js.map文件泄露/Springboot信息泄露

目录 框架识别 Webpack 简述 .js.map文件泄露 利用 Spring boot 很多网站都使用的是现有的框架进行开发的&#xff0c;因此相当于很多目录和文件的路径都是开源可知的&#xff0c;因此我们就可以直接访问对应的路径&#xff0c;如果网站没有进行限制就有可能会导致敏感信…

Mac搭建anaconda环境并安装深度学习库

1. 下载anaconda安装包 根据自己的操作系统不同&#xff0c;选择不同的安装包Anaconda3-2024.06-1-MacOSX-x86_64.pkg&#xff0c;我用的还是旧的intel所以下载这个&#xff0c;https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/&#xff0c;如果mac用的是M1&#xff0…

Administrators就最高了???system是什么??本地用户提权内网学习第三天 你知道uac是什么??

我们今天来说说本地用户提权的操作&#xff0c;我们在有webshell过后我们要进行进一步的提权操作&#xff0c;要不然对我们后期的内网渗透会有一些阻碍的操作。比如说我们使用mimikatz来进行抓取密码&#xff0c;就不能够成功。 Administrators与system的区别 我们来说说Admin…

毫米波雷达深度学习技术-1.7训练一个神经网络

1.7 训练一个神经网络 对于训练神经网络&#xff0c;有两个步骤&#xff0c;即前向传递和误差反向传播。 1.7.1 前向传播和反向传播 在前向传递中&#xff0c;输入被馈送到模型并与权重向量相乘&#xff0c;并为每一层添加偏差以计算模型的输出。密集层或全连接层第l层的输入、…

微信小程序的运行机制与更新机制

1. 小程序运行机制 1.1. 冷启动与热启动 冷启动为用户第一次打开小程序时&#xff0c;因为之前没有打开过&#xff0c;这是第一种冷启动的情兑。第二种情况为虽然之前用户打开过&#xff0c;但是小程序被用户主动的销毁过&#xff0c;这种情况下我们再次打开小程序&#xff0…

西门子S120伺服驱动器F1910故障报警处理总结

西门子S120伺服驱动器F1910故障报警处理总结 热压机正常工作时出现故障,无上升和下降动作,伺服故障代码为1910, 同时发现压机的实际压力为13Mpa,没有达到设定的14Mpa, 查看S120的报警手册,如下图所示, F01910:现场总线设定值超时,与上位机控制器的通讯故障, 可能的原…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑复合指标优化模态分解和 Stacking 集成的综合能源系统多元负荷预测》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

巴西东南湾乌巴图巴 ANTARES 监测站数据

ANTARES monitoring station in Ubatuba, Southeast Brazilian Bight 巴西东南湾乌巴图巴 ANTARES 监测站 简介 ANTARES 区域网络由分布在拉丁美洲的沿岸时间序列站组成。主要目的是研究气候和人为影响引起的长期变化&#xff0c;以及用于卫星匹配和算法开发的海洋颜色。Uba…

一分钟学习数据安全—自主管理身份SSI分布式加密密钥管理

在这篇之前&#xff0c;我们已经对SSI有了一个全局的了解。这个系列的文章可以作为一个学习笔记来参考&#xff0c;真正要实践其中的一些方案、协议&#xff0c;还需要参考专业的书籍和官方文档。作为一个SSI系列学习笔记的最后一篇&#xff0c;我们做一个简单的延伸&#xff0…

【PLC】三菱PLC如何和汇川伺服实现485通信

前言 一开始选用的是汇川SV660P脉冲型伺服&#xff0c;由于生产需求需要对伺服的个别参数进行读取和写入操作&#xff0c;但是SV660P并不支持这种情况&#xff0c;因此需要使用485通信来满足。PLC这边选用的是三菱FX5U。 开始 1、首先准备按照下图的引脚提示准备好一根带屏蔽…

(七)glDrawArry绘制

几何数据&#xff1a;vao和vbo 材质程序&#xff1a;vs和fs(顶点着色器和片元着色器) 接下来只需要告诉GPU&#xff0c;使用几何数据和材质程序来进行绘制。 #include <glad/glad.h>//glad必须在glfw头文件之前包含 #include <GLFW/glfw3.h> #include <iostrea…

英伟达经济学:云服务商在GPU上每花1美元 就能赚7美元

NVIDIA超大规模和 HPC 业务副总裁兼总经理 Ian Buck 近日在美国银行证券 2024 年全球技术大会上表示&#xff0c;客户正在投资数十亿美元购买新的NVIDIA硬件&#xff0c;以跟上更新的 AI 大模型的需求&#xff0c;从而提高收入和生产力。 Buck表示&#xff0c;竞相建设大型数据…

flask中解决图片不显示的问题(很细微的点)

我在编写flask项目的时候&#xff0c;在编写html的时候&#xff0c;发现不管我的图片路径如何变化&#xff0c;其就是显示不出来。如下图我框中的地方。 我尝试过使用浏览器打开&#xff0c;是可以的。 一旦运行这个flask项目&#xff0c;就无法显示了。 我查阅资料后。发现…