开发LBS应用之 根据一点的经纬度实现附近点的查询 - geohash

叁歲伎倆 2022-08-07 09:55 178阅读 0赞



开发LBS应用之 根据一点的经纬度实现附近点的查询 - geohash

时间 2014-07-31 15:13:13 segmentfault-博客 原文 http://blog.segmentfault.com/cloudmario/1190000000624088

geohash

这年头和LBS相关的应用越来越火. 从最早的foursquare的热闹程度就可见一般, 现在就更不用说微信、陌陌了 (什么, 没听过… 哥们, 你out 了). 和LBS有关的应用一般都包括一些共同的操作, 最常见的一个, 就是找附近的东东(餐馆, 商店, 妞….). 所以, 这里就抛出了一个问题, 怎样才能在大量经纬度数据中检索出附近的点呢?

geohash能做到:

  • https://github.com/CloudSide/geohash
  • https://github.com/lyokato/objc-geohash
  • 例如: 假设我的数据库里存储着1亿条包含经纬度的用户数据,用iPhone/android手机定位得到 新浪总部(理想国际大厦)的经纬度: 39.98123848, 116.30683690 然后去数据库查找附近的妞 m6vY73.gif

    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 )

  • 范围如图:

j6VnayV.png

  • 用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多万行测试数据):

索引:

YnEFfaM.png

数据:

uiQvU3m.png

  • 看一下查询是否够高效?:

    EXPLAIN SELECT * FROM xy WHERE geohash LIKE ‘wx4eqw%’;

jMbeqm.png

恩, HOHO!!

其他资料:

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

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

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

发表评论

表情:
评论列表 (有 0 条评论,178人围观)

还没有评论,来说两句吧...

相关阅读