Geo Distance Search with MySQL Presentation

简介: Mysql: LBS实现查找附近的人 (两经纬度之间的距离)

1. 利用GeoHash封装成内置数据库函数的简易方案;

A:Mysql 内置函数方案,适合于已有业务,新增加LBS功能,增加经纬度字段方可,避免数据迁移

B:Mongodb 内置函数方案,适合中小型应用,快速实现LBS功能,性能优于A(推荐)

方案A: (MySQL Spatial)

1、先简历一张表:(MySQL 5.0 以上 仅支持 MyISAM 引擎)

1 CREATE TABLE address (
2   
3     address CHAR(80) NOT NULL,
4   
5     address_loc POINT NOT NULL,
6   
7     PRIMARY KEY(address)
8   
9 );

空间索引:

1 ALTER TABLE address ADD SPATIAL INDEX(address_loc);

插入数据:(注:此处Point(纬度,经度) 标准写法)

1 INSERT INTO address VALUES('Foobar street 12', GeomFromText('POINT(30.620076 104.067221)'));
2   
3 INSERT INTO address VALUES('Foobar street 13', GeomFromText('POINT(31.720076 105.167221)'));

查询: 查找(30.620076,104.067221)附近 10 公里

01 SELECT  *
02     FROM    address
03     WHERE   MBRContains
04                     (
05                     LineString
06                             (
07                             Point
08                                     (
09                                     30.620076 + 10 / ( 111.1 / COS(RADIANS(104.067221))),
10                                     104.067221 + 10 / 111.1
11                                     ),
12                             Point
13                                     (
14                                     30.620076 - 10 / ( 111.1 / COS(RADIANS(104.067221))),
15                                     104.067221 - 10 / 111.1
16                                     )
17                             ),
18                     address_loc
19                     )

 

方案B:

1、先建立一张简单的表user,两条数据如下:

01 {
02   "_id": ObjectId("518b1f1a83ba88ca60000001"),
03   "account": "simplephp1@163.com",
04   "gps": [
05     104.067221,
06     30.620076
07   ]
08 }
09   
10 {
11   "_id": ObjectId("518b1dae83ba88d660000000"),
12   "account": "simplephp6@163.com",
13   "gps": [
14     104.07958,
15     30.653936
16   ]
17 }

 

其中,gps为二维数组,分别为经度,纬度

(注:此处必须按照(经度,纬度)顺序存储。我们平时表示经纬度,都是(纬度,精度),此处这种方式有木有很亲民)

2、使用之前,先建立二维索引

//建立索引 最大范围在经度-180~180

1 db.user.ensureIndex({"gps":"2d"},{"min":-180,"max":180})

//删除索引

1 db.user.dropIndex({"gps":"2d"})

 

3、Mongodb有两中方式可以查找附近的XXX;其中方案2)会返回距离(推荐)

1)标准查询,为地球经纬度查询内置;参数一为查询条件利用$near查找附近,参数二$maxDistance为经纬弧度(1° latitude = 111.12 kilometers)即 1/111.12,表示查找附近一公里。

1 db.user.find({ gps :{ $near : [104.065847, 30.657554] , $maxDistance : 1/111.12} })

2)执行命名方式,模拟成一个圆球;参数一指定geoNear方式和表名;参数二坐标,参数三是否为球形,参数四弧度(弧度=弧长/半径 一千米的弧度1000/6378000),参数五指定球形半径(地球半径)

1 db.runCommand({geoNear:'user', near:[104.065847, 30.657554], spherical:true, maxDistance:1000/6378000, distanceMultiplier:6378000});

转自:http://stackoverflow.com/a/1006668/4484798

 

2 利用谷歌方案

The SQL statement that will find the closest 20 locations that are within a radius of 30 miles to the 78.3232, 65.3234 coordinate. It calculates the distance based on the latitude/longitude of that row and the target latitude/longitude, and then asks for only rows where the distance value is less than 30 miles, orders the whole query by distance, and limits it to 20 results. To search by kilometers instead of miles, replace 3959 with 6371.

3959是地球半径的英里,6371是地球半径的千米: http://baike.baidu.com/view/758812.htm

01 SELECT
02   id, (
03     3959 * acos (
04       cos ( radians(78.3232) )
05       * cos( radians( lat ) )
06       * cos( radians( lng ) - radians(65.3234) )
07       + sin ( radians(78.3232) )
08       * sin( radians( lat ) )
09     )
10   ) AS distance
11 FROM markers
12 HAVING distance < 30
13 ORDER BY distance
14 LIMIT 0 , 20;

This is using the Google Maps API v3 with a MySQL backend which your already have.

https://developers.google.com/maps/articles/phpsqlsearch_v3#findnearsql

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
数据采集 小程序 Python
搞定短视频!批量下载快手视频(附源码)
相信大家都接触了短视频平台,比如某音、某手等平台,竟然大家都熟悉了,那么今天辰哥分享的技术是:在某手上搜索视频,并实现下载!
2145 0
|
存储 人工智能 安全
医学影像PACS系统的设计与实现,PACS源码
医学影像PACS系统是数字化医院的核心,实现影像的采集、存储、传输与辅助诊断。系统基于DICOM、HL7等标准,采用分布式架构与模块化设计,支持影像分层存储、高效调阅、AI集成及多系统联动,提升诊疗效率与数据管理能力。
2127 1
|
存储 SQL 缓存
数据库存储选型经验总结
工作中总是遇到数据存储相关的Bug工单,新需求开发设计中也多多少少会有数据模型设计和存储相关的问题
3390 0
数据库存储选型经验总结
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
11916 142
|
机器学习/深度学习 算法 Python
【机器学习】面试问答:决策树如何进行剪枝?剪枝的方法有哪些?
文章讨论了决策树的剪枝技术,包括预剪枝和后剪枝的概念、方法以及各自的优缺点。
727 2
|
数据采集 JSON JavaScript
django_vue3(vite+vue3)展示贵州省的疫情
django_vue3(vite+vue3)展示贵州省的疫情
269 0
|
C++
【洛谷 P1042】[NOIP2003 普及组] 乒乓球 题解(模拟+向量)
`NOIP2003`普及组编程题:乒乓球比赛模拟。给定一系列球赛记录(WL序列),程序需按11分和21分制分析比分。输入含多个字符串,含W(华华得分)、L(对手得分)和E(结束标记)。输出每局比分,分制间空行间隔。样例:`WWWWWW...` → `11:0\n11:0\n1:1`(11分制)和`21:0\n2:1`(21分制)。代码使用C++,逐字符读取,当分差≥2且得分≥x时输出比分。
602 0
|
机器学习/深度学习 数据采集 人工智能
大模型开发:你如何确保你的模型对于不同群体是公平的?
确保AI模型公平性的关键步骤包括:审查和处理数据以消除偏见,定义公平性度量,使用正向公平算法,进行敏感性分析,持续监控和审计模型,设立公平性目标,提供团队培训,以及遵守相关法律法规。通过这些综合措施,可以减少模型对不同群体的系统性差异,促进公正。
1080 2
|
Java Android开发
解决AGP升级到8.0后编译报错kaptGenerateStubsDebugKotlin
解决AGP升级到8.0后编译报错kaptGenerateStubsDebugKotlin
2138 0

热门文章

最新文章