天天看点

跟据经纬度实现附近搜索Java实现

http://www.open-open.com/lib/view/open1421650750328.html

mysql空间数据库、矩形算法、geohash

geo算法

参考文档:

http://blog.csdn.net/wangxiafghj/article/details/9014363geohash  算法原理及实现方式

http://blog.charlee.li/geohash-intro/  geohash:用字符串实现附近地点搜索

http://blog.sina.com.cn/s/blog_7c05385f0101eofb.html    查找附近点--Geohash方案讨论

http://www.wubiao.info/372        查找附近的xxx 球面距离以及Geohash方案探讨

http://en.wikipedia.org/wiki/Haversine_formula       Haversine formula球面距离公式

http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe   球面距离公式代码实现

http://developer.baidu.com/map/jsdemo.htm#a6_1   球面距离公式验证  

http://www.wubiao.info/470     Mysql or Mongodb LBS快速实现方案

geohash有以下几个特点:

首先,geohash用一个字符串表示经度和纬度两个坐标。某些情况下无法在两列上同时应用索引 (例如MySQL 4之前的版本,Google App Engine的数据层等),利用geohash,只需在一列上应用索引即可。

其次,geohash表示的并不是一个点,而是一个矩形区域。比如编码wx4g0ec19,它表示的是一个矩形区域。 使用者可以发布地址编码,既能表明自己位于北海公园附近,又不至于暴露自己的精确坐标,有助于隐私保护。

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

一直在琢磨LBS,期待可以发现更好的方案。现在纠结了。

简单列举一下已经了解到的方案:

1.sphinx geo索引

2.mongodb geo索引

3.mysql sql查询

4.mysql+geohash

5.redis+geohash

然后列举一下需求:

1.实时性要高,有频繁的更新和读取

2.可按距离排序支持分页

3.支持多条件筛选(一个经纬度数据还包含其他属性,比如社交系统的性别、年龄)

方案简单介绍:

1.sphinx geo索引

支持按照距离排序,并支持分页。但是尝试mva+geo失败,还在找原因。

无法满足高实时性需求。(可能是不了解实时增量索引配置有误)

资源占用小,速度快

2.mongodb geo索引

支持按照距离排序,并支持分页。支持多条件筛选。

可满足实时性需求。

资源占用大,数据量达到百万级请流量在10w左右查询速度明显下降。

3.mysql+geohash/ mysql sql查询

不支持按照距离排序(代价太大)。支持分页。支持多条件筛选。

可满足实时性需求。

资源占用中等,查询速度不及mongodb。

且geohash按照区块将球面转化平面并切割。暂时没有找到跨区块查询方法(不太了解)。

4.redis+geohash

geohash缺点不再赘述

不支持距离排序。支持分页查询。不支持多条件筛选。

可满足实时性需求。

资源占用最小。查询速度很快。

------update

补充一下测试机配置:

1TB SATA硬盘。8GB RAM。I3 2350 双核四线程

https://blog.csdn.net/Mary881225/article/details/70173864

继续阅读