WebGIS中GeoHash编码的研究和扩展

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

1.背景

1.1普通地理编码流程

将采集的POI入库后,数据库里保存有该POI的位置描述、X、Y等信息。当需要进行逆编码查询时,前端传入坐标的X、Y值,后台构建查询范围查询,并且对查询出来的值进行距离排序。

1.2普通地理编码的几点劣势

a.前端查询url中的X、Y值为真实值,可能会暴露相关真实信息。

b.前端查询的url因为X、Y值的长度而变得比较长。

c.后台中,需要同时对X列、Y列做查询判断。

d.因为传入的X、Y值总在变化,数据库中的查询很难进行缓存优化。

e.数据库中保存的是真实X、Y数据,增加了存储空间。

2 GeoHash算法简介

2.1算法背景

Geohash的初衷是如何用尽量短的URL来标志地图上的某个位置,而地图上的位置一般是用经纬度来表示,问题就转化为如何把经纬度转化为一个尽量短的URL。

2.2GeoHash算法的描述

具体来说GeoHash算法的主要思想是对某一数字通过二分法进行无限逼近。这里以经纬度区间(经度(-180,180),纬度(-90,90))为例子来进行讲解。

2.2.1 哈夫曼编码

假设纬度值为48,精确到1度即可,则其编码流程如下所示:

 

 

                       

以左向为0,右向为1,最后48精确到1度的编码为:11000010。

对经度同样可以做该编码逼近。

2.2.2编码融合

对经纬度分别做了编码后,需要将两个编码进行融合。融合规则为:将经度和纬度的编码合并,奇数位是纬度,偶数位是经度。

比如:纬度39.92324精确到0.001后的编码为1011 1000 1100 0111 1001。经度116.3906精确到0.001后的编码为1101 0010 1100 0100 0100。两者融合后的编码为:11100 11101 00100 01111 00000 01101 01011 00001。

2.2.3 编码字符串化

这里使用Base32算法对编码进行字符串 化,Base32的规则如下:

 

我们将39.92324, 116.3906(11100 11101 00100 01111 00000 01101 01011 00001)进行Base32的字符串化后获得字符串:wx4g0ec1。

3.基于GeoHash算法的扩展

3.1互联网GeoHash算法的局限

互联网GeoHash算法主要针对的是经纬度系统,所以其算法中的编码范围、编码精确度都相对固定。

范围为[-90,90],[-180,180]。

 

在纬度相等的情况下:

经度每隔0.00001度,距离相差约1米;

每隔0.0001度,距离相差约10米;

每隔0.001度,距离相差约100米;

每隔0.01度,距离相差约1000米;

每隔0.1度,距离相差约10000米。

 

在经度相等的情况下:

纬度每隔0.00001度,距离相差约1.1米;

每隔0.0001度,距离相差约11米;

每隔0.001度,距离相差约111米;

每隔0.01度,距离相差约1113米;

每隔0.1度,距离相差约11132米。

Geohash,如果geohash的位数是6位数的时候,大概为附近1千米。

但是假如需要编码的坐标为平面坐标时,以上算法必须进行相关修改才能使用。

3.2GeoHash算法扩展

3.2.1 根据所需精确度获取编码长度

这里以平面坐标系为例子。平面坐标的单位是M,如果想要编码的精确度精确到1M,则需要算出此时需要保留的编码长度应该是多少。具体算法与哈夫曼编码的思路基本相同,以下是代码截取:

 

这里,需要知道编码范围、编码精确位数。因为5位数的编码等于一个Base32字符串,所以最后返回的值除以5。

当然,这里是经纬度坐标系也可以,只要规定好范围以及编码精确位数即可。

3.2.2 编码算法优化

编码时,编码范围不再是固定的经纬度范围,而是根据传递进来的范围值来进行编码。具体代码如下:

 

4.性能测试

4.1数据准备

这里我准备了13万条数据(测试数据中大量重复数据):

 

 

数据为平面坐标系数据,对所有数据已经进行了GeoHash编码,为了方便测试,这里同样存入了X、Y坐标。

 

4.2 普通编码查询 VS GeoHash编码查询

测试坐标点为:505214.06,305104.09。对其进行精确到100M的GeoHash编码,编码值为:kx5。

4.2.1范围查询命中率

4.2.1.1普通查询命中率

查询中为了去掉重复项,所以稍显繁琐。

查询范围为(CoordinateX < 505314.06 and CoordinateX > 505114.06 and CoordinateY < 305204.09 and CoordinateY >305004.09)具体如下,共查询到:12项。

 

4.2.1.2 GeoHash查询命中率

因为编码已经精确到100M了,所以直接等于该编码即可,查询得到的结果为6项。

 

4.2.1.3 对比分析

对比两种查询,很明显GeoHash编码查询法查询到的数据要少一些。仔细分析可见:在传统查询中,距离在50M以内的前6项,均出现在了GeoHash查询中。但是其他6项则没有。

我们可以推断为,虽然编码精度设置的为100M,但是最后一位的编码应该具体是精确到了100/2=50M 的范围。

所以,我们可以推断:GeoHash是能大致查询出要求范围的数据的,精确度比较高,但是查询所得数据量比真实的范围查询要少。

4.2.2 查询效率

4.2.2.1普通查询

清除查询缓存后,进行范围查询,需要0.281S。

 

在X、Y上分别建立索引后,需要0.172S。

 

4.2.2.2 GeoHash查询

不建立索引,需要耗时0.499S。

 

建立索引后,耗时0.156S。

 

第二次命中时,耗时:0.031S。

 

 

4.2.2.3查询性能对比分析

 

 

4.2.2.3.1查询时间

不考虑网络环境、查询时电脑本身CPU等性能偶然影响,单纯测试结果如下:


查询类型

(数据量13W)


无索引查询时间


有索引查询时间


二次命中时间


普通地理编码查询


0.281S


跟索引建立方式有关系,单纯在XY上建立索引,时间反而更久,需要:0.172S


0.094S


GeoHash编码查询


0.499S


0.156S


0.031S

 

可见GeoHash因为是字符串查询,其本身是比较耗时的。但是当做了索引后,其查询速度是快于普通查询的,而且其二次命中时查询速度比普通查询二次命中会更快。其原因比较简单:单列索引、单列命中显然是高于多列的。

4.2.3.2 资源消耗分析

普通查询的资源消耗信息:

 

 

GeoHash查询的资源消耗信息:

 

其中:

cardinality是指计划中这一步所处理的行数。

cost指cbo中这一步所耗费的资源,这个值是相对值,和cpu_cost、io_cost是有关系的。

cost是由其他几个因素共同决定的,这里暂时不进行深入的研究。一般情况下,在一张表只有一条记录的情况下,cpu_cost会有个初始值(常见的是2万多或3万多),随着记录的增加,cpu_cost也成比例的增加。对于io_cost来说,如果访问的记录在一个db_block中,值是不变的。

bytes指cbo中这一步所处理所有记录的字节数,是估算出来的一组值。

对比性能分析表可见:

GeoHash表中的cardinality和bytes是明显低于普通查询的,究其原因也还是因为其只需查询一列即可。

5.总结

GeoHash算法的几个特点:

a.GeoHash编码后,获得的位置信息为范围信息,而非真实的坐标精确值。

b.GeoHash编码后,将X、Y坐标融合成一个值,数据库存在中既可以减少存储空间,也便于优化查询。尤其是编码后,一定范围内的点均是同样编码,兴趣点查询的二次命中率会大大提高,进一步加快查询速度。

c.GeoHash的编码可以容易的表示出范围包含关系,这样非常便于进行范围查询。

d.查询时前端URL长度变短。

6.三个问题

6.1如何查询最近点

GeoHash查询出来的仅仅是某个范围内的数据,需要对返回的数据在进行距离运算,排序后最近的便是。其优化效率主要体现在范围查询上。

6.2查询效率能优化多少?

测试在1W条数据以下时不明显。

10W条附近时,开始有0.1S间的小差距。

类推,当数据量越大时,效果越明显。

6.3两个点离的越近,geohash的结果相同的位数越多,对么?

这一点是有些用户对geohash的误解,虽然geo确实尽可能的将位置相近的点hash到了一起,可是这并不是严格意义上的(实际上也并不可能,因为毕竟多一维坐标),例如在方格4的左下部分的点和大方格1的右下部分的点离的很近,可是它们的geohash值一定是相差的相当远,因为头一次的分块就相差太大了,很多时候我 们对geohash的值进行简单的排序比较,结果貌似真的能够找出相近的点,并且似乎还是按照距离的远近排列的,可是实际上会有一些点被漏掉了。
上述这个问题,可以通过搜索一个格子,周围八个格子的数据,统一获取后再进行过滤。这样就在编码层次解决了这个问题。
    既然不能做到将相近的点hash值也相近,那么geohash的意义何在呢?
    个人觉觉得geohash还是相当有用的一个算法,毕竟这个算法通过无穷的细分,能确保将每一个小块的geohash值确保在一定的范围之内,这样就为灵活的周边查找和范围查找提供了可能。

7.最后提一个有趣的问题——伦敦到纽约的距离怎么算

 

这个问题是前几天一个读博士的朋友问的我,思考这个问题挺有趣的。其中会涉及到长距离和短距离问题,推荐一篇类似博客:我们看到的地图一直都错得离谱(http://blog.sina.com.cn/s/blog_517eed9f0102w4rm.html);

 

 

                                                                           -----欢迎转载,但保留版权,请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

                                                                           如果您觉得本文确实帮助了您,可以微信扫一扫,进行小额的打赏和鼓励,谢谢 ^_^

                                      

时间: 2024-11-08 21:27:55

WebGIS中GeoHash编码的研究和扩展的相关文章

PHP也能干大事之PHP中的编码解码详解

PHP也能干大事之PHP中的编码解码详解        这篇文章主要介绍了PHP也能干大事之PHP中的编码解码详解,本文讲解了ASCII编解码.URL编解码.Base64编解码.HTML实体编解码.二进制.八进制.十进制.十六进制相互转换等内容,需要的朋友可以参考下 写在前面 PHP也能干大事是我总结的PHP语法特性及相关函数类库的经典用法,并不一定是真正能实现四两拨千斤的功效,但是掌握这些方法,可以在你的工作和学习上有一些帮助,希望大家能集思广益,将<PHP也能干大事>丰富得更精彩!转载请注

Java编码及网络传输中的编码问题

Java编码及网络传输中的编码问题 近来试着FTP搜索,遇到编码问题,研究了下. Java内部的String为Unicode编码,每个字符占两个字节. Java编解码方法如下: String str = "hi好啊me";   byte[] gbkBytes=str.getBytes("GBK");//将String的Unicode编码转为GBK编码,输出到字节中  String string=new String(gbkBytes,"GBK")

(八)WebGIS中栅格图层的设计

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.    前言 我们在上一章里了解到WebGIS中栅格图层的本质--地图图片.而从之前的第二章到第五章,我们详细的介绍了地图图片的获取原理和方法.所以在设计栅格图层前,我们已经知道了栅格图层中数据是如何获得的,剩下的便是怎样将这个过程用一种符合面向对象的设计原则来进行实现. 2.栅格数据获得的流程 这里我再次将栅格数据获得的流程描述一遍: 首先,得到屏幕范围内的地图

(十八)WebGIS中清空功能和地图定位功能的设计以及实现

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 当地图中增加了很多元素后,对不同的元素需要进行一定的控制,最简单的控制就是能对元素有选择的进行清空删除.在本节中,还将介绍WebGIS中另外一个常用功能,即地图定位功能.具体描述便是:当输入一个坐标点后,能够将地图缩放到该点处.下面我便就以上两个功能展开此章节的内容. 2.清空功能 2.1设计思路 根据功能点,我们可以将清空分为如下几个情形: a.清空某个或

(十六)WebGIS中偏移补偿量引发的问题之探讨

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 在上一章里讲解地图平移功能的实现时,我在最后提出了两个问题: A.在地图平移后,矢量图层的canvas的XY都发生了变化,此时根据地理坐标转换为屏幕坐标公式得出的屏幕坐标,在canvas上能将要素正确显示吗? B.矢量图层canvas的原点坐标XY有需要还原成初始的(0,0)的时候吗? 对这两个问题我给出的答案是:不能和需要. 在这一章里,我们将详细讲解得出

(十三)WebGIS中工具栏的设计之命令模式

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 从这一章节开始我们将正式进入WebGIS的工具栏中相关功能的设计和实现.我们以ArcMap中的工具栏中的基本工具为模板,将其中的放大.缩小.平移.全图.清除.定位.I查询.距离量测.面积量测在WebGIS中进行实现. 这里,我先跟大家说一个基本的概念.我们一般将工具分为Command和Tool.所谓command是指该工具被调用后,生效一次即终止.而Tool

(十五)WebGIS中平移功能的设计和实现

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 这一章我们将详细讲解WebGIS工具栏中另一个基础工具--平移工具(Pan).在介绍命令模式时,我们已经知道了此工具为Tool型的. 这个工具主要有如下两个功能: A.当切换到此工具上时,按下鼠标不放,移动鼠标时可以拖动地图. B.当切换到此工具上时,点击鼠标(鼠标不做平移),可以使地图平移,以点击处为中心. 2.设计 2.1 原理 我们已经知道,WebGI

(十一)WebGIS中要素(Feature)的设计

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.前言 在GIS中元素一般分为点元素,线元素,面元素以及symbol元素(特殊的点元素)等.与此对应,图层可以分为点图层,线图层,面图层以及标注图层等.从第9章到第10章,我给大家讲解了什么是矢量数据.矢量数据的来源.矢量数据的构造.以及矢量数据中的地理坐标与屏幕坐标之间的转换.在了解了这些概念和算法以及流程后,这一章我们将开始讲解设计出一个矢量图层前的最后一步,设

行为地图在WAP流程中简单的可用性研究

文章描述:行为地图(Behavioral Mapping)在可用性研究中的应用探索. 概念+实战 一.概念篇--传统行为地图(Behavioral Mapping)的概念及应用范围 一种从时间和空间角度,系统的观察研究行为的方法.而这种从时间和空间角度还可以有两个维度进行观察:以人群或个体为观察单位.以地点为观察单位. 以人群或个体为观察单位(好像有点像狗仔队),观察人群/个体的行为.语言.行动路线等,得到关于这个人或这一个体的习性.性格特征等.这种观察更多的是用在动物或者小孩身上,因为当你观察