SQL 实战:基于经纬度的距离计算与位置查询

news2025/2/4 7:01:51

在位置服务(LBS)系统中,基于地理位置查询和距离计算是核心功能之一。例如:

  • 查找附近的商铺、加油站或医院。
  • 计算两点之间的实际直线距离。
  • 筛选出指定范围内的用户或设备位置。

MySQL 提供了多种方式实现地理位置查询,包括 ST_Distance_Sphere() 和经典的 Haversine 公式。本文将介绍如何使用这两种方式在 MySQL 中进行距离计算与位置筛选。


一、经纬度距离计算原理

1. 地球模型与球面距离

在这里插入图片描述


二、方法 1:使用 ST_Distance_Sphere() 计算球面距离

函数介绍
  • ST_Distance_Sphere(point1, point2) 直接返回两点之间的球面距离,结果以米为单位。
  • POINT(lng, lat) 将经纬度转换为点对象。

案例 1:计算两点之间的直线距离

需求
计算从北京天安门到上海外滩的直线距离。

天安门坐标(39.9087, 116.3975)
外滩坐标(31.2335, 121.4920)


SQL 实现
SELECT ST_Distance_Sphere(  
    POINT(116.3975, 39.9087),  
    POINT(121.4920, 31.2335)  
) AS distance_meters;

查询结果
distance_meters
1064695.78

解释

  • 结果显示北京到上海外滩的直线距离约为 1064 公里。
  • POINT(lng, lat) 将经纬度转换为地理点,ST_Distance_Sphere 计算两点的球面距离。


案例 2:查询当前位置 5 公里范围内的商铺

需求
查询距离当前定位(广州塔 23.1056, 113.32485 公里范围内的商铺信息。


表结构 shops
shop_idnamelatlng
1星巴克23.1100113.3300
2肯德基23.0920113.3100
3麦当劳23.1500113.3700
4德克士23.0900113.2500

SQL 实现
SELECT shop_id, name,  
       ST_Distance_Sphere(POINT(lng, lat), POINT(113.3248, 23.1056)) AS distance_meters  
FROM shops  
WHERE ST_Distance_Sphere(POINT(lng, lat), POINT(113.3248, 23.1056)) <= 5000  
ORDER BY distance_meters;

查询结果
shop_idnamedistance_meters
1星巴克566.43
2肯德基1887.29

解释

  • 查询范围限定为 5000 米(5 公里)。
  • 使用 WHERE 过滤距离条件,同时按照距离升序排序,方便查看最近的商铺。


三、方法 2:Haversine 公式计算距离

在不支持 ST_Distance_Sphere 的 MySQL 版本中,可以使用 Haversine 公式 实现经纬度距离计算。


案例 3:Haversine 公式计算两点间距离

SQL 实现
SELECT  
    6371000 * 2 * ASIN(  
        SQRT(  
            POWER(SIN(RADIANS((39.9087 - 31.2335) / 2)), 2) +   
            COS(RADIANS(39.9087)) * COS(RADIANS(31.2335)) *  
            POWER(SIN(RADIANS((116.3975 - 121.4920) / 2)), 2)  
        )  
    ) AS distance_meters;

结果

distance_meters
1064695.78

解释

  • 手动实现 Haversine 公式,使用三角函数计算地球表面的两点距离。
  • 6371000 表示地球平均半径,单位为米。


四、复杂位置查询:筛选指定范围内的对象


案例 4:查询用户 10 公里范围内的餐厅

需求
用户当前位置 (30.5702, 104.0648),查询 10 公里内的餐厅。


表结构 restaurants
rest_idnamelatlng
1火锅店30.5800104.0700
2烧烤店30.5000104.0000
3自助餐厅30.6100104.1100
4小吃店30.4000103.9500

SQL 实现
SELECT rest_id, name,  
       6371000 * 2 * ASIN(  
           SQRT(  
               POWER(SIN(RADIANS((30.5702 - lat) / 2)), 2) +   
               COS(RADIANS(30.5702)) * COS(RADIANS(lat)) *  
               POWER(SIN(RADIANS((104.0648 - lng) / 2)), 2)  
           )  
       ) AS distance_meters  
FROM restaurants  
HAVING distance_meters <= 10000  
ORDER BY distance_meters;

查询结果
rest_idnamedistance_meters
1火锅店1200.43
2烧烤店7890.10


五、性能优化与注意事项

  1. 建立空间索引
    如果表中存储大量地理位置数据,可以使用 空间索引 提升查询速度:
ALTER TABLE shops ADD SPATIAL INDEX (lat, lng);
  1. 限制结果集大小
    在大数据量环境下,添加 LIMIT 和分页,提高查询效率:
ORDER BY distance_meters LIMIT 10;

六、总结

  • MySQL 提供了两种方式实现基于经纬度的距离计算:
    • ST_Distance_Sphere():直接计算,简单高效,推荐使用。
    • Haversine 公式:适用于不支持 ST_Distance_Sphere 的旧版本。
  • 通过位置查询可以实现商铺筛选、附近用户查找等功能,广泛应用于 LBS 场景。

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

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

相关文章

DAY1牛客题库1-3算法题:C语言版本(思路仅供参考)

挑战一下7天刷完牛客题库的108个题&#xff0c;今天是第一天思密达~一直以来都特别懒的做题&#xff0c;还是得勤奋点我觉得~今天只做了3个~嘻嘻明天去玩回家多弄几个~ 1.输出字符串最后一个单词长度 【1】题目&#xff1a; #include"stdio.h" #include"string…

LeetCode 83 :删除排链表中的重复元素

题目&#xff1a; 地址&#xff1a;https://leetcode.cn/problems/remove-duplicates-from-sorted-list/ 方法一&#xff1a; 方法二&#xff1a; package com.zy.leetcode.LeetCode_04;/*** Author: zy* Date: 2024-12-25-15:19* Description: 删除排链表中的里复元素* …

微信流量主挑战:用户破16!新增文档转换(新纪元3)

朋友们&#xff0c;报告好消息&#xff01;我的小程序用户数量已经涨到16个了&#xff01;没错&#xff0c;真没拉朋友圈亲戚好友来撑场子&#xff0c;全靠实力&#xff08;和一点点运气&#xff09;吸引了16位陌生小伙伴光临&#xff01;这波进步&#xff0c;连我自己都感动了…

Java-38 深入浅出 Spring - AOP切面增强 核心概念 相关术语 Proxy配置

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

基于Docker+模拟器的Appium自动化测试(二)

模拟器的设置 打开“夜神模拟器”的系统设置&#xff0c;切换到“手机与网络”页&#xff0c;选中网络设置下的“开启网络连接”和“开启网络桥接模式”复选框&#xff0c;而后选择“静态IP”单选框&#xff0c;在IP地址中输入“192.168.0.105”&#xff0c;网关等内容不再赘述…

【从零开始入门unity游戏开发之——C#篇36】C#的out协变和in逆变如何解决泛型委托的类型转换问题

文章目录 一、知识回顾和问题分析1、回顾强制转换和as转换知识2、问题分析 二、为什么泛型委托不行&#xff1f;1、泛型类型的严格类型检查2、**as 和强制类型转换不能直接使用** 三、如何解决这个问题&#xff1f;1、**协变&#xff08;out&#xff09;**2、**逆变&#xff08…

深度学习使用Anaconda打开Jupyter Notebook编码

新手入门深度学习使用Anaconda打开Jupyter Notebook编码 1. 安装Anaconda 第一种是Anaconda官网下载安装包&#xff0c;但是很慢&#xff0c;不太建议 第二种使用国内清华大学镜像源下载 选择适合自己电脑的版本&#xff0c;支持windows&#xff0c;linux系统 下载完之后自行…

Linux套接字通信学习

Linux套接字通信 代码源码&#xff1a;https://github.com/say-Hai/TcpSocketLearn/tree/CThreadSocket 在网络通信的时候, 程序猿需要负责的应用层数据的处理(最上层)&#xff0c;而底层的数据封装与解封装&#xff08;如TCP/IP协议栈的功能&#xff09;通常由操作系统、网络协…

git clone 和 conda 换源

文章目录 git clone 通过 sshconda 创建虚拟环境通过 env.yml 文件conda 换源 git clone 通过 ssh git clone ssh://用户名IP地址:/仓库名字.gitconda 创建虚拟环境通过 env.yml 文件 conda env create -f environment.ymlconda 换源 Step 1 生成 .bashrc 文件在家目录下。…

机床数据采集网关在某机械制造企业的应用

随着工业4.0时代的到来&#xff0c;智能制造已成为制造业转型升级的重要方向。数控机床作为现代制造业的核心设备&#xff0c;其运行状态和加工参数的数据实时采集与分析对于提升生产效率、优化生产流程具有关键意义。 背景概述 某机械制造企业拥有多台数控机床&#xff0c;这…

c# RSA加解密工具,.netRSA加解密工具

软件介绍 名称: c# RSA加解密工具,.netRSA加解密工具依赖.net版本: .net 8.0工具类型: WinForm源码下载 c# RSA加解密工具,.netRSA加解密工具 依赖项 WinFormsRSA.csproj <Project

穷举vs暴搜vs深搜vs回溯vs剪枝_全排列_子集

46. 全排列 递归解决&#xff1a;一开始选一个数&#xff0c;递归进入下一层再选一个新的数&#xff0c;直到到最后一个数。反会上一层遍历其它数。 每次递归到叶子节点就找到了一种组合&#xff0c;思路有了具体怎么实现&#xff1f; 1.怎么记录每条路径&#xff1f; 定义一个…

【Trick】获取kaggle账号的token和api(用于数据集下载)

0&#xff1a;操作背景 由于未来的科研需要用到Unet&#xff0c;但是运行学长的史山代码无法跑通&#xff0c;自己写了一个Unet并load学长的数据集效果也很差&#xff0c;于是打算从最最基础的开始&#xff0c;上github调用一个Unet并成功在公有数据集上跑一遍实例。 Unet的g…

VS Code AI开发之Copilot配置和使用详解

随着AI开发工具的迅速发展&#xff0c;GitHub Copilot在Cursor、Winsuf、V0等一众工具的冲击下&#xff0c;推出了免费版本。接下来&#xff0c;我将为大家介绍GitHub Copilot的配置和使用方法。GitHub Copilot基于OpenAI Codex模型&#xff0c;旨在为软件开发者提供智能化的代…

论文解读 | NeurIPS'24 Lambda:学习匹配先验以处理无标记垂悬问题场景下的实体对齐任务...

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 点击 阅读原文 观看作者讲解回放&#xff01; 作者简介 尹航&#xff0c;上海交通大学博士生 内容简介 我们研究了带有无标记悬挂问题的实体对齐&#xff08;EA&#xff09;任务&#xff0c;即部分实体在另一个…

评分模型在路网通勤习惯分析中的应用——提出问题(1)

1、问题的由来、目标和意义 最近一段时间和公司其它业务部门讨论时&#xff0c;发现一个有趣的交通路网问题&#xff0c;车辆从S点行驶到V点共用时40分钟&#xff0c;这段时间内路网中的卡口摄像头识别到了车辆通过的信息。如下图所示&#xff1a; 设计师需要通过这些有限的路…

Spring Security day 11.23

ok了今天学习一个关于登录角色权限的管理框架&#xff0c;我们一起取看看吧 一.权限控制 1.1 认证和授权概念 前面我们已经完成了后台管理系统的部分功能&#xff0c;例如检查项管 理、检查组管理、套餐管理、预约设置等。接下来我们需要思 考 2 个问题&#xff1a; 问题 1 …

【IC验证】verilog及systemverilog特殊特性的分析

verilog及systemverilog特殊特性的分析 1.概述2.赋值延迟&#xff08;0&#xff09;总结&#xff08;1&#xff09;情况一&#xff1a;initial中进行阻塞赋值和非阻塞赋值&#xff08;不延迟&#xff09;a代码b 电路图c 结果 &#xff08;2&#xff09;时钟a 代码b 电路图c 结果…

FPGA流水线考虑因素

流水线考虑因素 另一种提升性能的方法是对拥有多个逻辑级数的长数据路径进行重新组织&#xff0c;并将其分配在多个时钟周期上。这种方法 以时延和流水线开销逻辑管理为代价&#xff0c;来达到加快时钟周期和提高数据吞吐量的目的。 由于 FPGA 器件带有大量的寄存器&#x…

关于 PCB线路板细节锣槽问题 的解决方法

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/144783817 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…