LBS地理位置距离计算方法之geohash算法

随着移动终端的普及,不少应用都基于LBS功能,附近的某某(餐馆、银行、妹纸等等)。
基础数据中,通常保存了目标位置的经纬度;利用用户提供的经纬度,进行对比,从而得到是否在附近。这里须要在设置出一个字段,是关于编码的字段,一会看下文哈……php


地理位置距离实现目标:
查找附近多少千米内的人或者商家mysql

好比:微信、陌陌、美团、基于O2O的一些APP这些应用或者移动网页都须要用到地理位置计算android

目前来讲:移动地理位置距离计算比较好的算法是geohash,特此整理分享。git

 

geohash有如下几个特色:github

第一:geohash用一个字符串表示经度和纬度两个坐标。算法

某些状况下没法在两列上同时应用索引 (例如MySQL 4以前的版本,Google App Engine的数据层等),利用geohash,只需在一列上应用索引便可。sql

(这里插一句:咱们的mysql为字段建立的索引,其实原理就是利用二分法算法来作路径查询简化,快速查找出想要的字段位置)数据库

第二:geohash表示的并非一个点,而是一个矩形区域。好比编码wx4g0ec19,它表示的是一个矩形区域。 微信

使用者能够发布地址编码,既能代表本身位于北海公园附近,又不至于暴露本身的精确坐标,有助于隐私保护。ide

第三:编码的前缀能够表示更大的区域。


例如wx4g0ec1,它的前缀wx4g0e表示包含编码wx4g0ec1在内的更大范围。 这个特性能够用于附近地点搜索。首先根据用户当前坐标计算geohash(例如wx4g0ec1)而后取其前缀进行查询 (SELECT * FROM place WHERE geohash LIKE 'wx4g0e%'),便可查询附近的全部地点。

Geohash比直接用经纬度的高效不少。

 

Geohash的原理

Geohash的最简单的解释就是:将一个经纬度信息,转换成一个能够排序,能够比较的字符串编码

 

geohash能作到:

require_once('geohash.class.php');
$geohash = new Geohash;
//获得这点的hash值
$hash = $geohash->encode(39.98123848, 116.30683690);
//取前缀,前缀约长范围越小
$prefix = substr($hash, 0, 6);
//取出相邻八个区域
$neighbors = $geohash->neighbors($prefix);
array_push($neighbors, $prefix);

print_r($neighbors);
  • 获得9个geohash值
//获得9个geohash值

Array
(
  [top] => wx4eqx
  [bottom] => wx4eqt
  [right] => wx4eqy
  [left] => wx4eqq
  [topleft] => wx4eqr
  [topright] => wx4eqz
  [bottomright] => wx4eqv
  [bottomleft] => wx4eqm
  [0] => wx4eqw
)

  

  • 范围如图:
  • 用sql语句查询
  • SELECT * FROM xy WHERE geohash LIKE 'wx4eqw%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqx%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqt%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqy%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqq%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqr%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqz%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqv%';
    SELECT * FROM xy WHERE geohash LIKE 'wx4eqm%';
    
  • 看一下是否用上索引 (一共有50多万行测试数据):
  • 索引:




其余资料:

- geohash演示: http://openlocation.org/geohash/geohash-js/

- wiki: http://en.wikipedia.org/wiki/Geohash

- 原理: https://github.com/CloudSide/geohash/wiki

 

 

移动端地理算法探讨 交流QQ: 187395037 

相关文章
相关标签/搜索