`
天梯梦
  • 浏览: 13732408 次
  • 性别: Icon_minigender_2
  • 来自: 洛杉矶
社区版块
存档分类
最新评论

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

 
阅读更多

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

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

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

 

方案A: (MySQL Spatial)

 

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

CREATE TABLE address (
 
    address CHAR(80) NOT NULL,
 
    address_loc POINT NOT NULL,
 
    PRIMARY KEY(address)
 
);

 

空间索引:

ALTER TABLE address ADD SPATIAL INDEX(address_loc);

 

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

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

 

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

SELECT  *
    FROM    address
    WHERE   MBRContains
                    (
                    LineString
                            (
                            Point
                                    (
                                    30.620076 + 10 / ( 111.1 / COS(RADIANS(104.067221))),
                                    104.067221 + 10 / 111.1
                                    ),
                            Point
                                    (
                                    30.620076 - 10 / ( 111.1 / COS(RADIANS(104.067221))),
                                    104.067221 - 10 / 111.1
                                    ) 
                            ),
                    address_loc
                    )

 

 

方案B:

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

{
  "_id": ObjectId("518b1f1a83ba88ca60000001"),
  "account": "simplephp1@163.com",
  "gps": [
    104.067221,
    30.620076
  ]
}
 
{
  "_id": ObjectId("518b1dae83ba88d660000000"),
  "account": "simplephp6@163.com",
  "gps": [
    104.07958,
    30.653936
  ]
}

 

 

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

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

 

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

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

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

 

//删除索引

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

 

 

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

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

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

 

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

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

SELECT
  id, (
    3959 * acos (
      cos ( radians(78.3232) )
      * cos( radians( lat ) )
      * cos( radians( lng ) - radians(65.3234) )
      + sin ( radians(78.3232) )
      * sin( radians( lat ) )
    )
  ) AS distance
FROM markers
HAVING distance < 30
ORDER BY distance
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

转自:http://gis.stackexchange.com/a/31629

 

 

3 其他

Anyways, here’s the PHP formula for calculating the distance between two points (along with Mile vs. Kilometer conversion) rounded to two decimal places:

function getDistanceBetweenPointsNew($latitude1, $longitude1, $latitude2, $longitude2, $unit = 'Mi') {
      $theta = $longitude1 - $longitude2;
      $distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) + (cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta)));
      $distance = acos($distance);
      $distance = rad2deg($distance);
      $distance = $distance * 60 * 1.1515; switch($unit) {
           case 'Mi': break; case 'Km' : $distance = $distance * 1.609344;
      }
      return (round($distance,2));
 }

 

It’s also possible to use MySQL to do a calculation to find all records within a specific distance. In this example, I’m going to query MyTable to find all the records that are less than or equal to variable $distance (in Miles) to my location at $latitude and $longitude:

$qry = "SELECT *,(((acos(sin((".$latitude."*pi()/180)) * sin((`Latitude`*pi()/180))+cos((".$latitude."*pi()/180)) * cos((`Latitude`*pi()/180)) * cos(((".$longitude."- `Longitude`)*pi()/180))))*180/pi())*60*1.1515) as distance
 FROM `MyTable`
 WHERE distance >= ".$distance."

 

For Kilometers:

$qry = "SELECT *,(((acos(sin((".$latitude."*pi()/180)) * sin((`Latitude`*pi()/180))+cos((".$latitude."*pi()/180)) * cos((`Latitude`*pi()/180)) * cos(((".$longitude."- `Longitude`)*pi()/180))))*180/pi())*60*1.1515*1.609344) as distance
FROM `MyTable`
WHERE distance >= ".$distance."

 

转自:http://stackoverflow.com/a/8599305/4484798  & https://www.marketingtechblog.com/calculate-distance/

 

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

 

分享到:
评论
3 楼 1455975567 2018-08-17  
xuezhongyu01 写道
wocan23 写道
我想问下那个111.1是怎么得来的

我也看不懂,我猜测是不是跟st_distance函数一样,计算出来的结果是度,需要乘以111.1转换为米

米或者千米 = 地球半径 * PI /180;地球半径的单位是米,返回的就是米。
2 楼 xuezhongyu01 2018-06-04  
wocan23 写道
我想问下那个111.1是怎么得来的

我也看不懂,我猜测是不是跟st_distance函数一样,计算出来的结果是度,需要乘以111.1转换为米
1 楼 wocan23 2017-02-13  
我想问下那个111.1是怎么得来的

相关推荐

    mysql函数-根据经纬度坐标计算距离

    在MySQL数据库中,计算两个地理位置之间的距离通常涉及到地理坐标系统,即经纬度。经纬度坐标是地球表面位置的标准表示方式,其中经度表示东西方向,纬度表示南北方向。本篇文章将详细介绍如何利用MySQL的内置函数和...

    flutter + SpringBoot + MySql 实现高德地图定位获取位置信息插入数据库并计算出经纬度之间的距离

    flutter + SpringBoot + MySql 实现高德地图定位获取位置信息插入数据库并计算出经纬度之间的距离

    计算两经纬度之间的距离存储过程_mysql

    ### 计算两经纬度之间的距离存储过程_mysql 在MySQL中,经常需要处理与地理位置相关的数据,例如在地图应用、物流系统或者任何需要基于位置的服务(LBS)的应用程序中。其中一项常见的需求就是计算两个地理位置之间...

    全国城市商圈经纬度MYSQL版

    全国城市商圈经纬度MYSQL版,全国城市商圈经纬度MYSQL版,全国城市商圈经纬度MYSQL版,全国城市商圈经纬度MYSQL版,全国城市商圈经纬度MYSQL版,全国城市商圈经纬度MYSQL版,全国城市商圈经纬度MYSQL版,全国城市...

    MYSQL 关于两个经纬度之间的距离由近及远排序

    在MySQL数据库中,对经纬度数据进行距离排序是一项常见的需求,尤其在地理位置相关的应用中,如推荐系统、导航服务等。本篇文章将深入探讨如何在MySQL中实现这一功能,并优化查询性能。 首先,我们需要理解经纬度...

    mysql优化经纬度的计算

    需求:现在移动app的运用越来越广泛了,这里有个需求就是查找我附近的酒店 或者是团购这样类似的功能 前提:一般我们的酒店都是有经纬度的 也保存在数据库中,那么我们只要在数据库查找这些就可以了 也就是说 我们...

    mysql版省市经纬度

    中国所有省市的经纬度,,从GOOGLE获取的,可以用于基于电子地图的开发 insert into GEO_CN(P_INDEX, P_NAMES, LAT, LNG) values('110000', '北京市', '39.904214', '116.407413'); insert into GEO_CN(P_INDEX, P_...

    腾讯地图行政区域经纬度转Mysql国内地区数据库

    同时,`latitude` 和 `longitude` 字段使得我们可以利用Haversine公式或其他空间距离计算方法,快速估算两个地点之间的直线距离。 其次,`说明.txt` 文件可能是对数据转换过程的详细指南,包括如何导入SQL脚本到...

    商圈数据库,mysql直接导入就可以,含经纬度

    商圈数据库,mysql直接导入就可以,含经纬度,如北京-东城区-王府井-经纬度

    中国城市经纬度表 (mysql)

    全国所有城市经纬度数据库表 数据来源于百度地图 通过百度地图api调用,不保证数据完全准确

    全国 省 市 区 经纬度 mysql数据

    全国 省 市 区 经纬度 mysql数据

    PHP根据两点间的经纬度计算距离1

    在本文中,我们将深入探讨如何使用PHP来计算两个地点之间的距离,基于它们的经纬度坐标。这个功能在很多Web应用程序中都有用到,比如地图服务、物流跟踪或旅行规划等。我们将按照以下步骤来实现这一功能: 首先,...

    Java通过经纬度坐标获取两个点之间的直线距离的示例

    在实现经纬度坐标获取两个点之间的直线距离时,需要先获取每个人的经纬度坐标,并存储到数据库中。然后,通过SQL语句获取指定距离范围内的用户列表。最后,通过计算自己与用户之间的距离,获取距离范围内的用户列表...

    PHP根据两点间的经纬度计算距离

    PHP根据两点间的经纬度计算距离 一、 开发环境 1、环境搭建:Windows 7+Apache 2.4.18+MySQL 5.7.11+PHP 7.1.0。 2、文本编辑器:Sublime ...本案例主要使用PHP中的数学函数,通过两点间的经纬度来计算两点之间的距离。

    高德mysql信息表:区域名称、城市编码、邮政编码、经纬度、名称拼音

    在IT行业中,数据库管理和地理信息系统(GIS)是两个至关重要的领域。本文将深入探讨与给定标题和描述相关的知识点,包括“高德mysql信息表”、“高德API”、“地址编码”、“全国省市区”数据、“城市编码”、...

    全国县区拼音 经纬度 数据表(Mysql)

    全国县区拼音 经纬度 数据表 可以直接导入到MySQL中使用

    最新最全的全国省市区 四级数据库 mysql版本包含经纬度

    2014最全的全国省市区mysql数据库,与国家统计局数据同步,46462条,包含简称,地理位置经纬度,无限分类结构,包含港澳台。地区含有经纬度

    java实现附近的人功能.zip

    获取到用户的位置后,还需要将其转换为可计算的距离形式,例如使用Haversine公式来计算两个经纬度之间的距离。 2. **数据存储与结构**:用户的位置信息需要存储在数据库中,以便于后续的查询和计算。可以选择关系型...

    使用MySQL的geometry类型处理经纬度距离问题的方法

    在这个场景下,我们可以使用`geometry`类型来处理经纬度距离问题。以下是对这一主题的详细说明。 首先,我们需要创建一个包含经纬度信息的表。创建表`map`的SQL语句如下: ```sql CREATE TABLE `map` ( `id` int...

Global site tag (gtag.js) - Google Analytics