一,空间搜索相关:

基于地图的空间搜索使用经度(longitude)和纬度(latitude)作为基本的搜索条件进行地理信息的相关检索和查询。其实现方式一般包括以下一种实现方式:

在数据库表中将经度(longitude)和纬度(latitude)分别以两个不同的列进行存储,通过对经度(longitude)和纬度(latitude)两列建二元索引,提供对经度(longitude)和纬度(latitude)的检索。这种方式简单粗暴,可以满足对小规模的数据进行经纬度的检索。但是,在地图搜索相关的应用中,地理信息相关的记录的数据量会很多,二元索引的速度应该不会很理想,再者,基于地理信息的搜索行为相关的搜索基准点相对比较稀疏,数据库的缓存效果也不会太理想。

Geohash:通过这种编码方式,可以将经度(longitude)和纬度(latitude)值转换为一个基于base32编码的串,一方面可以实现对地理信息的一元索引;另外,地理上相近的点通过这种编码方式编码之后所得的串的前缀相同(当然会有特例,也就是一些边界条件,本文后面讲描述;前缀长度根据表示精度的不同而不同)。这样,要实现"搜索给定点附近的其他点"时,只需要将该参照点按照Geohash进行编码,按照精度要求从所得编码串中选取一定长度的字串作为前缀进行搜索,这样就可以很方便的实现该功能;

R-tree:还未具体学习,后续补充

其他支持:

二,Geohash

在介绍Geohash之前,先简单介绍一下经纬度概念。为了明确表示世界各地在地球上的位置,将地球看成一个基于经纬度线的坐标系。纬线就是平行于赤道平面的那些平面的周线,经线就是连接南北两极的大圆线的半圆弧。纬度分为北纬(正),南纬(负),赤道所在的纬度值为0。经度以本初子午线界(本初子午线经度为0),分为东经(正),西经(负)。故纬度范围可表示为[-90o, 0o),(0o, 90o],经度范围可表示为[-180o, 0o),(0o, 180o]。

我们可以将经度和纬度看成二维坐标系中的两个纬度,横轴表示经度,纵轴表示纬度,那么所表示的区域如下所示:

图 1

如上图所示,我们可以将整个区域逐步通过两条直线进行细分。例如:首先我们可以将原区域分成[(0, 0),(180, 0),(0, 90),(180, 90)],[(0, 0),(-180, 0),(0, 90),(-180, 90)],[(0, 0),(-180, 0),(0, -90),(-180, -90)],[(0, 0),(180, 0),(0, -90),(180, -90)]等四个区域,我们可以将这四个区域中的点分别按照该点所在的区域进行编码。具体的编码方式为先水平方向(经度)后竖直方向(纬度),以水平方向(经度)为例,它被竖直中轴线一分为二,那么右侧的编码为1,左侧的编码为0;同理,在竖直方向,上测的编码为1,下测的编码为0;依照这种规则,那么处于右上区域的点在第一次划分后的编码为11(如上图中A,E编码后的前两位),处于左上区域的点在第一次划分后的编码为01(如上图中B编码后的前两位),同理,第一次划分后C的编码为00,D的编码为10。

接下来对第一次划分后的四个区域重复上述过程,以第一次划分后的右上区域为例,可以将这个区域继续分为四个小区域,编码方式和第一次相同,根据这四个小区域在其所处的直接大区域中的方位进行编码,即这四个小区域中右侧的两个小区域水平编码为1(经度),左侧的两个小区域水平编码(经度)为0,上测的两个小区域的竖向编码为1,下测的两个小区域的竖向编码为0。所以,A第二次划分的编码为11,E第二次划分的编码为00。那么经过两次划分之后,A的编码为11 11,E的编码为11 00(即按照划分次序将每次的子编码进行拼接,如A第一次为11,第二次为11,故A两次划分之后编码为1111,同理E为1100)。明白了上述原理之后,我们可以根据上述原理将整个区域继续进行划分,就可以得到给定某一点更精确的编码值。

上述划分的过程是我个人对Geohash编码思想的一种直观的理解,对任意一对经度、纬度值(lon,lat),我们可以根据上述原理将其编码为0、1所组成的串,然后将所得串按照base32进行编码。

例如,对于经纬度值(116.3906,39.9232),我们可以将经纬度按照上述原理转换成如下0、1序列

图 2

图 3

所得序列为:

经度0、1编码后的序列为:1 1 0 1 0 0 1 0 1 1 0 0 0 1 0

纬度0、1编码后的序列为:1 0 1 1 1 0 0 0 1 1 0 0 0 1 1

合并经度、纬度0、1编码后的序列得到,经纬度(116.3906,39.9232)的0、1编码序列:

图 4

注意:

在所得经纬度编码中,偶数位存放经度编码,奇数为存放纬度编码(编码位序号从0开始计数,所以第一位是偶数位)

接下来对所得的经纬度0、1编码后的序列进行base32编码,base32编码对应表如下:

图 5

所以上述序列经过base32编码后为:wx4g0e,即(116.3906,39.9232)geohash编码为wx4g0e(经度为6)

接下来,我们进一步理解Geohash编码。Geohash其实就是将整个地图或者某个分割所得的区域进行一次划分,由于采用的是base32编码方式,即Geohash中的每一个字母或者数字(如wx4g0e中的w)都是由5bits组成(2^5 = 32, base32),这5bits可以有32中不同的组合(0~31),这样我们可以将整个地图区域分为32个区域,通过00000 ~ 11111来标识这32个区域。第一次对地图划分后的情况如下图所示(每个区域中的编号对应于该区域所对应的编码):

图 6

也许有些读者对于上图中各区域的编号很难理解,我们不妨从Geohash的编码方式中找原因。因为Geohash的0、1串序列是经度0、1序列和纬度0、1序列中的数字交替进行排列的,如图4所示,在图4中,偶数位对应的序列为经度序列(0标识第一位),奇数位对应的序列为纬度序列,那么在进行第一次划分时,Geohash0、1序列中的前5个bits(11100),那么这5bits中有3bits是表示经度,2bits表示纬度,所以第一次划分时,是将经度划分成8个区段(2^3 = 8),将纬度划分为4个区段(2^2 = 4),这样就形成了32个区域。那么为什么第一次划分后每个区域对应的序号是上图中那样呢?那么下面这个图就可以详细说明。

图 7

同理,可以按照第一次划分所采用的方式对第一次划分所得的32个区域各自再次划分,如下图所示:

图 8

细心的读者会发现对第一次划分所得编号为S的区域再次进行划分后,所得的是8x4的32个区域,而不是如同第一次划分中的4x8的32个区域,这是为什么呢?这个也需要从Geohash的0、1序列来解释,因为Geohash的0、1序列的第一个5bits表示第一次划分,第二个5bits表示第二次划分,但是两者不同的是,在第一个5bit中有3bits(0,2,4)表示经度,2bits(1,3)表示纬度,而在第二个5bits中,有2bits(6,8)表示经度,3bits(5,7,9)表示纬度,所以应该是8x4的32个区域。每个区域对应的序号如下图所示:

图 9

三,GeoHash encode与decode源码(源代码引用自)

encode源码

1 functionencodeGeoHash(latitude, longitude) {2 var is_even=1;3 var i=0;4 var lat = []; var lon =[];5 var bit=0;6 var ch=0;7 var precision = 12;8 geohash = "";9

10 lat[0] = -90.0; lat[1] = 90.0;11 lon[0] = -180.0; lon[1] = 180.0;12

13 while (geohash.length mid) {17 ch |=BITS[bit];18 lon[0] =mid;19 } else

20 lon[1] =mid;21 } else{22 mid = (lat[0] + lat[1]) / 2;23 if (latitude >mid) {24 ch |=BITS[bit];25 lat[0] =mid;26 } else

27 lat[1] =mid;28 }29

30 is_even = !is_even;31

32 if (bit < 4)33 bit++;34 else{35 geohash +=BASE32[ch];36 bit = 0;37 ch = 0;38 }39 }40 returngeohash;41 }

decode源码

1 functiondecodeGeoHash(geohash) {2 var is_even = 1;3 var lat = []; var lon =[];4 lat[0] = -90.0; lat[1] = 90.0;5 lon[0] = -180.0; lon[1] = 180.0;6 lat_err = 90.0; lon_err = 180.0;7

8 for (i=0; i

15 refine_interval(lon, cd, mask);16 } else{17 lat_err /= 2;

18 refine_interval(lat, cd, mask);19 }20 is_even = !is_even;21 }22 }23 lat[2] = (lat[0] + lat[1])/2;

24 lon[2] = (lon[0] + lon[1])/2;

25

26 return{ latitude: lat, longitude: lon};27 }

decode解码 geohash_GeoHash相关推荐

  1. decode解码 geohash_Geohash算法原理及实现

    最近需要实现一个功能,查找车辆附近的加油站,如果车和加油站距离在200米以内,则查找成功. 加油站数量肯定不小,能否缩小查找范围,否则以遍历形式,效率肯定高不了. Geohash算法就是将经纬度编码, ...

  2. decode解码 geohash_Geohash 原理及 Python 实现

    本文代码见 github.内容参考维基百科 Geohash Geohash 是一种地理编码系统,可以把经纬度坐标转换为短字符串,原理是用 Z-order curve 填充平面.在给定的精度下,相同的字 ...

  3. org.bouncycastle.util.encoders.Base64.decode 解码去换行问题

    org.bouncycastle.util.encoders.Base64.decode解码去换行问题 byte[] b1 = Base64.decode("MIIDFjCCAn+gAwIB ...

  4. python中------decode解码出现的0xca问题解决方法

    python中------decode解码出现的0xca问题解决方法 参考文章: (1)python中------decode解码出现的0xca问题解决方法 (2)https://www.cnblog ...

  5. decode解码报错UnicodeDecodeError: 'gb2312' codec can't decode byte 0x8f in position 6018: illegal multib

    python抓取网页后用decode解码,报错信息如下: Traceback (most recent call last):File "<pyshell#7>", l ...

  6. 站长在线Python精讲:Python中字符串编码转换encode编码和decode解码详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<Python中字符串编码转换:encode编码和decode解码详解>.本知识点主要内容有:常用编码简介.使用encode( ...

  7. P2转P3时出现‘utf-8‘ codec can‘t decode byte 0xb3 in position 0: invalid start byte(\x、decode解码)

    直接上干货 实例: abc = b'\x85\xa6\xff\x01\x00\x00\x00\x01!\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ ...

  8. decode解码 geohash_python geohash算法逆地址编码原理初探

    1.geohash有什么用途呢? 这几天刚好有个测试任务是关于设备信息位置处理的,里面提及到geohash:抱着测试的警觉性,打算研读一下这个geohash到底是什么?Geohash 是一种地理编码系 ...

  9. 编码解码问题.decode(encoding='gbk', errors='ignore')

    编码解码问题 在一次请求一个网页的过程中,遇到一个问题,代码如下: 这是解决了问题之后的代码 import urllib.requestheaders={'User-Agent':'Mozilla/5 ...

最新文章

  1. Selenium3.X 与 Javascript (Nodejs)
  2. CVPR 2021 论文/代码分类汇总!持续更新中!
  3. 青少年迷恋上短视频 如何防沉迷?
  4. sql server 利用 For Xml Path('') 多行数据拼接成一个字符串
  5. intelj idea安装和配置
  6. Git学习收获(一)
  7. 【分享】一次单体架构改造成微服务架构的拆分实践
  8. 侮辱性极强!6年编发无数反诈骗新闻,90后小编竟被骗了5万...
  9. uefi引导gpt安装win10_uefi安装win10系统原版镜像教程
  10. EMC辐射骚扰整改案例分析
  11. python selenium 跳转网页_selenium关于页面跳转
  12. 华为计算机黑屏怎么办,华为笔记本升级后黑屏怎么回事
  13. 杭州河坊街特色手机饰品——招财猫!
  14. 自然语言处理(NLP)的一般处理流程!
  15. 回顾大一|我们要做的是提前准备,而不是提前焦虑
  16. matlab能输入铁心参数,变压器铁心剩磁预测研究
  17. A375皮肤黑色素瘤细胞膜修饰纳米囊泡|saos2骨肉瘤细胞膜复合纳米脂质体
  18. 毕业设计-基于大数据的电影推荐系统-python
  19. iOS 屏蔽系统更新描述文件更新!快把烦人的系统更新提示关掉!
  20. Qt+百度API实现人脸对比寻找明星脸

热门文章

  1. Hadoop集群搭建与经验总结
  2. 粉丝活动:《uni-app跨平台开发与应用从入门到实践》一本(包邮)
  3. cmd之xcopy命令实例
  4. 深度学习--CLIP算法(文本搜图片,图片搜图片)
  5. Kdump机制介绍以及分享
  6. 【报告分享】活跃长者驱动的健康市场-CCAF(附下载)
  7. Python图片抓取实操
  8. ad设置塞孔_PCB线路板导电孔塞孔工艺的实现
  9. 中国商用单相燃气智能表市场趋势报告、技术动态创新及市场预测
  10. You have 18 unapplied migration(s).Watching for file changes with StatReloader