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

在位置服务(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 场景。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一个最简单的ios程序(object_c)的编写

前言 如何在苹果系统MacOS创建一个简单的ios&#xff08;iphone&#xff09;程序&#xff0c;貌似非常的简单。但是&#xff0c;作为习惯了Windows开发的程序员来说&#xff0c;有时候还觉得有点麻烦&#xff0c;至少开始有点很不习惯。 本博文试着把这个过程展现一下&#xff…

高效搭建Nacos:实现微服务的服务注册与配置中心

一、关于Nacos 1.1 简介 Nacos&#xff08;Dynamic Naming and Configuration Service&#xff09;是阿里巴巴开源的一款动态服务发现、配置管理和服务管理平台。它旨在帮助开发者更轻松地构建、部署和管理分布式系统&#xff0c;特别是在微服务架构中。Nacos 提供了简单易用…

Visual Studio 中增加的AI功能

前言&#xff1a; 人工智能的发展&#xff0c;在现在&#xff0c;编程技术的IDE里面也融合了AI的基本操做。本例&#xff0c;以微软的Visual Studio中的人工智能的功能介绍例子。 本例的环境&#xff1a; Visual Studio 17.12 1 AI 智能变量检测&#xff1a; 上图展示了一…

【SpringMVC】SpringMVC 快速入门

通常&#xff0c;Web 应用的工作流程如下&#xff1a; 用户通过浏览器访问前端页面&#xff1b; 前端页面通过异步请求向后端服务器发送数据&#xff1b; 后端采用“表现层-业务层-数据层”三层架构进行开发&#xff1a; 表现层接收页面请求将请求参数传递给业务层业务层访问…

如果你的网站是h5网站,如何将h5网站变成小程序-除开完整重做方法如何快速h5转小程序-h5网站转小程序的办法-优雅草央千澈

如果你的网站是h5网站&#xff0c;如何将h5网站变成小程序-除开完整重做方法如何快速h5转小程序-h5网站转小程序的办法-优雅草央千澈 h5如何转小程序 如果当年你们开发网站是用的h5但是没有开发小程序&#xff0c;也没有使用uniapp这样的混开框架&#xff0c;但是目前根据业务需…

C语言:位段

位段的内存分配: 1. 位段的成员可以是 int unsigned int signed int 或者是char &#xff08;属于整形家族&#xff09;类型 2. 位段的空间上是按照需要以4个字节&#xff08; 类型 int &#xff09;或者1个字节&#xff08; char &#xff09;的方式来开辟的。 3. 位段涉及…

如何在LabVIEW中更好地使用ActiveX控件?

在LabVIEW中&#xff0c;ActiveX控件可以帮助实现与其他应用程序或第三方组件的集成&#xff08;例如Microsoft Excel、Word、Internet Explorer等&#xff09;。以下是一些建议&#xff0c;帮助您更好地在LabVIEW中使用ActiveX控件&#xff1a; ​ 1. 理解ActiveX控件的基本原…

Speckly:基于Speckle文档的RAG智能问答机器人

前言 Speckly 是一个基于 检索增强生成 (RAG) 技术的智能问答机器人&#xff0c;它能像一位经验丰富的工程师&#xff0c;理解你的问题&#xff0c;并从 Speckle 文档中精准地找到答案。更厉害的是&#xff0c;它甚至可以帮你生成代码片段&#xff01;&#x1f680; 本文将详…

TencentOS 2.4 final 安装mysql8.0备忘录

准备 tencentOS 2.4 与Red Hat Enterprise Linux 7 是兼容的。 我们首先从oracle官网上下载mysql的源文件。 下载完成后你会得到以下文件&#xff1a; mysql84-community-release-el7-1.noarch.rpm 安装 首先你需要切换到root用户下。 1.安装源文件 yum localinstall my…

怎么在家访问公司服务器?

在日常工作中&#xff0c;特别是对信息技术从业者而言&#xff0c;工作往往离不开公司的服务器。他们需要定期访问服务器&#xff0c;获取一些关键的机密文件或数据。如果您在家办公&#xff0c;并且需要处理未完成的任务&#xff0c;同时需要从公司服务器获取所需的数据&#…

快速搭建springcloud 3.X+mybatis+nacos本地项目

环境&#xff1a; jdk17 idea 2019 springboot:3.2.4 spring-cloud:2023.0.1 大概记录下关键配置 1 创建父工程 创建项目 删除src目录 因为是父子结构不需要。 引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"ht…

衣物褶皱织物褶皱检测数据集VOC+YOLO格式939张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;939 标注数量(xml文件个数)&#xff1a;939 标注数量(txt文件个数)&#xff1a;939 标注…

【C++】B2064 斐波那契数列

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述输入格式输出格式输入输出样例输入输出 &#x1f4af;思路分析**题目本质** &#x1f4af;代码实现与对比**我的代码实现**代码展示思路解析优点不足 **老师的代码…

springboot521基于Spring Boot的校园闲置物品交易系统(论文+源码)_kaic

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装校园闲置物品交易系统软件来发挥其高效地信息处理的作用&am…

el-table动态行和列及多级表头

主页面 <template><div class"result-wrapper"><dynamic-table :table-data"tableData" :table-header"tableConfig" :tableTitle"tableTitle" :flowParams"flowParams"></dynamic-table></div…

【MySQL】数据库 Navicat 可视化工具与 MySQL 命令行基本操作

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

2024年12月30日Github流行趋势

项目名称&#xff1a;free-programming-books 项目地址url&#xff1a;https://github.com/EbookFoundation/free-programming-books项目语言&#xff1a;HTML历史star数&#xff1a;343,398今日star数&#xff1a;246项目维护者&#xff1a;vhf, eshellman, davorpa, MHM5000,…

Mysql数据库Redo日志和Undo日志的理解

数据库redo日志和undo日志 1、redo日志1.1 redo日志的作用1.1.1 不使用redo日志的问题1.1.2 使用redo日志的好处 1.2 redo日志刷盘策略 2、undo日志2.1 undo日志的作用2.2 undo日志的简要生成过程 1、redo日志 事务的4大特性&#xff08;ACID&#xff09;&#xff1a;原子性、…

Windows配置cuda,并安装配置Pytorch-GPU版本

文章目录 1. CUDA Toolkit安装2. 安装cuDNN3. 添加环境变量配置Pytorch GPU版本 博主的电脑是Windows11&#xff0c;在安装cuda之前&#xff0c;请先查看pytorch支持的版本&#xff0c;cuda可以向下兼容&#xff0c;但是pytorch不行&#xff0c;请先进入&#xff1a;https://py…

Oracle 数据库 dmp文件从高版本导入低版本的问题处理

当前有个需求是将oracle 19c上的数据备份恢复到oracle 11g上使用。我们通过exp命令远程进行备份&#xff0c;然后通过imp进行恢复时出现IMP-00010: not a valid export file, header failed verification报错。 这是数据库版本问题&#xff0c;在使用exp命令导出的时候使用的客…