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实现查找附近的人 (两经纬度之间的距离)
相关推荐
mysql函数-根据经纬度坐标计算距离
flutter + SpringBoot + MySql 实现高德地图定位获取位置信息插入数据库并计算出经纬度之间的距离
计算两经纬度之间的距离存储过程_mysql
Spring boot基于Redis Hash数据结构实现附近的人Demo,框架由Spring-boot实现,压缩包含源码以及部署jar包。代码清晰,有注释,考虑性能优化
需求:现在移动app的运用越来越广泛了,这里有个需求就是查找我附近的酒店 或者是团购这样类似的功能 前提:一般我们的酒店都是有经纬度的 也保存在数据库中,那么我们只要在数据库查找这些就可以了 也就是说 我们...
全国所有城市经纬度数据库表 数据来源于百度地图 通过百度地图api调用,不保证数据完全准确
本篇文章是对MYSQL中关于两个经纬度之间的距离由近及远排序的方法进行了详细的分析介绍,需要的朋友参考下
商圈数据库,mysql直接导入就可以,含经纬度,如北京-东城区-王府井-经纬度
PHP根据两点间的经纬度计算距离 一、 开发环境 1、环境搭建:Windows 7+Apache 2.4.18+MySQL 5.7.11+PHP 7.1.0。 2、文本编辑器:Sublime ...本案例主要使用PHP中的数学函数,通过两点间的经纬度来计算两点之间的距离。
中国行政区域五级划分mysql版(包含港澳台、经纬度、邮编、中文拼音等),省市县镇村,
MySQL存储文件,全国区域表带经纬度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_...
高德api 高德地址编码表 mysql版全国省、市、区行政区域mysql信息表,包含:区域名称、城市编码、邮政编码、经纬度、名称拼音,sql文件,mysql导入可用;
中国城市行政区坐标经纬度 中国省市区县位置坐标mysql数据库 全国哪个行政区的坐标都有!
腾讯地图行政区划转Mysql数据库表,新加地区拼音行政区域经纬度和经纬度字段,方便计算距离,经纬度只记录到三级。
全国县区拼音 经纬度 数据表 可以直接导入到MySQL中使用
本人历经千辛万苦整理的全国城市商圈经纬度MYSQL版,亲验下载直接可用。 部分数据如下: INSERT INTO `circles` VALUES ('1', '北京市', '北京市', '东城区', '王府井', '116.412987', '39.908416'); INSERT INTO `...
2014最全的全国省市区mysql数据库,与国家统计局数据同步,46462条,包含简称,地理位置经纬度,无限分类结构,包含港澳台。地区含有经纬度
中国省市区城市列表mysql数据表,可直接导入数据库、可转JSON数据,带行政区划码和经纬度