Geo Distance Search with MySQL Presentation

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 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

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
9月前
|
存储 关系型数据库 数据库
探索PostgreSQL 14新特性--SEARCH和CYCLE
探索PostgreSQL 14新特性--SEARCH和CYCLE
51 0
|
5月前
|
算法 数据库 索引
Binary Search
二分查找(Binary Search)是一种在有序数组中查找目标值的算法。它的基本思想是将数组分成两半,判断目标值是否在左半部分或右半部分,然后递归地在相应的半部分中查找。这个过程不断重复,直到找到目标值或者确定目标值不存在为止。二分查找的时间复杂度为 O(logn),其中 n 是数组的长度。
37 0
PAT (Advanced Level) Practice - 1043 Is It a Binary Search Tree(25 分)
PAT (Advanced Level) Practice - 1043 Is It a Binary Search Tree(25 分)
103 0
|
算法 Python
Leetcode-Medium 98. Validate Binary Search Tree
Leetcode-Medium 98. Validate Binary Search Tree
108 0
|
SQL 关系型数据库 MySQL
Influx Sql系列教程四:series/point/tag/field
influxdb中的一条记录point,主要可以分为三类,必须存在的time(时间),string类型的tag,以及其他成员field;而series则是一个measurement中保存策略和tag集构成;
306 0
|
Java 定位技术
Google Earth Engine(GEE)——Error: Projection: The CRS of a map projection could not be parsed.(坐标转换错)
Google Earth Engine(GEE)——Error: Projection: The CRS of a map projection could not be parsed.(坐标转换错)
617 0
Google Earth Engine(GEE)——Error: Projection: The CRS of a map projection could not be parsed.(坐标转换错)
|
传感器 数据采集 ice
Google Earth Engine ——LANDSAT 7 Collection 1 Tier 1 and Real-Time data DN values数据集
Google Earth Engine ——LANDSAT 7 Collection 1 Tier 1 and Real-Time data DN values数据集
104 0
Google Earth Engine ——LANDSAT 7 Collection 1 Tier 1 and Real-Time data DN values数据集
SAP CRM Advanced search和Simple search里Max hit表现行为的差异
SAP CRM Advanced search和Simple search里Max hit表现行为的差异
108 0
SAP CRM Advanced search和Simple search里Max hit表现行为的差异
|
存储 缓存 UED
ElasticSearch Tune for search speed Translation
本译文原文取自https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-search-speed.html#_search_rounded_dates
1350 0

热门文章

最新文章