Geohash介绍
Geohash是一种地址编码,能把二维的经纬度编码成字符串,某一区域范围内的经纬度是一致的,其中有编码长度控制区域的范围 精度参考
使用场景
实时LBS应用
LBS应用中,搜索某某(地点) 附近 的什么(地点),重点在于附近,如果没有Geohash
算法,你可能需要做。
- 圈定经度在某范围
- 圈定纬度在某范围
- 一般还会加上时间来做匹配
在数据量不多的时候这个方案确实可行,可是一旦数据量上去之后,这个方式别说实时应用甚至连离线场景都不合适。另外基本上应用基于LBS后,数据都是海量的。
所以通过对经纬度做Geohash
成为字符串后,然后对该字符串以及时间在数据库中添加索引,再加上业内最常用的分库分表,即使海量基于LBS方面的数据实时查询也成为可行。
地理位置信息回溯
某打车公司,偶尔需要配合公安破案以及xx方面诉求的数据回溯,要调出某一时间段某一地区所有司机的信息
,由于司机是实时上报坐标,数据量异常之大(日均几百G的,约500亿记录)
如果利用常规的圈定经度,纬度,时间范围的方式来查询根本不可行,所以利用Geohash在Hadoop中去查询的方式使得从大量数据中回溯特定数据方案可行。
当然这种诉求还有更佳的解决方案来做,由于并非高频需求,目前只是简单入Hive
然后离线跑数据
简单使用
下边简单介绍在python
和php
中使用Geohash
,以及遇到的问题
python
推荐使用Google
上边的这个包,Download下来之后,解压到任意位置
1 2 3 4 5 6 7 8 9 10 11 12 13
| 16:02 liujb@localhost /Users/liujb/Dropbox/Didi/python-geohash % ll total 104 -rw-r--r--@ 1 liujb staff 25B Jan 15 15:14 MANIFEST.in -rw-r--r--@ 1 liujb staff 3.7K Jan 15 15:14 README -rw-r--r--@ 1 liujb staff 14K Jan 15 15:14 geohash.py -rw-r--r--@ 1 liujb staff 11K Jan 15 15:15 geohash.pyc -rw-r--r--@ 1 liujb staff 3.3K Jan 15 15:14 jpgrid.py -rw-r--r--@ 1 liujb staff 2.1K Jan 15 15:14 jpiarea.py -rw-r--r--@ 1 liujb staff 2.6K Jan 15 15:14 quadtree.py -rw-r--r--@ 1 liujb staff 525B Jan 15 15:14 setup.py drwxr-xr-x@ 6 liujb staff 204B Jan 15 15:14 src drwxr-xr-x@ 7 liujb staff 238B Jan 15 15:14 test
|
然后在该目录
大专栏 Geohash介绍i>输入python
,进入python
环境,
- 输入
import geohash
,导入geohash包
print geohash.encode(30.725014, 104.257957)
- 得到
wm6nu3q64mxr
整个过程如下
1 2 3 4 5 6 7 8 9 10 11
| % python Python 2.7.11 (default, Dec 12 2015, 20:37:07) [GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import geohash >>> print geohash.encode(30.725014, 104.257957) wm6nu3q64mxr >>> print geohash.encode(30.725014, 104.257957, 5) wm6nu >>> print geohash.encode(30.735014, 104.267957) wm6nuejs7mzg
|
看得出 30.725014, 104.257957
和 30.735014, 104.267957
的hash值分别是wm6nu3q64mxr
, wm6nuejs7mzg
两个字符串的前5位相同,两个地点相隔大约2公里左右
注意遇到的坑
1 2 3 4 5 6 7 8 9 10 11
| >>> print geohash.encode(104.257957, 30.725014, 5) File "<stdin>", line 1 print geohash.encode(104.257957, 30.725014, 5) ^ SyntaxError: invalid syntax >>> print geohash.encode(104.257957, 30.725014, 5) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "geohash.py", line 79, in encode raise Exception("invalid latitude.") Exception: invalid latitude.
|
这是因为经纬度弄反了,所以geohash.encode()
第一个参数是纬度,第二个参数是经度,第三个参数是编码长度。这个坑是因为一开始使用的是vinsci这个包,该包经纬度弄反了不会报错,也是会出来一个编码。当时并没有注意到该环节,导致匹配了很多很远的经纬度数据
php
参考此处
本文参考