什么是geohash?它的原理是什么?它帮助我们解决了哪些棘手问题?这篇文章将向你解释。
本文包含以下内容。大约需要10分钟来完成阅读:
我们在日常生活中遇到什么定位场景
简要回顾经纬度
地理哈希原理来分析
地理哈希
中存在的边界问题如何解决边界问题
两点间距离的计算
地理哈希在再版中的实现
我们在日常生活中遇到的位置场景下面两张图片应该相互熟悉。打开位置,找到我附近的车。那么,这是如何实现的呢?我脑海中的第一个实现是实时报告经度和纬度在数据库中,经度和纬度被标记为索引,并且通过搜索和比较经度和纬度的值来找到距离为1公里的车辆。但是,这种方法索引多、值大,并且需要遍历经度和纬度,这使得查询速度慢且效率低。< br>
那么,如何准确定位和快速搜索这些应用程序?答案是geohashgeohash通过算法将位置的经度和纬度转换为散列字符串。如果两个位置更近,则它们的哈希值的前缀是相同的然后通过数据库中的类似操作符“like wtw366%”,可以快速找到附近的汽车
例如,上海腾讯大厦的经度和纬度是:(31.1688749,121.3975184),那么转换成地理哈希是wtw366ngz5qt。我们想找一辆附近的车,我们可以使用:选择*从卡特彼勒地理哈希喜欢' wtw 366% ';< br>在大致了解了geohash是什么之后,让我们回顾一下纬度和经度是什么(高中生可能已经忘记了光(逃逸)),这对理解geohash有很大帮助。
我们将铺平道路,并得到以下计划
地球平面图将地球分为经度和纬度,以赤道和本初子午线为边界。赤道在0度,本初子午线也在0度。赤道是经度x的横坐标,本初子午线是纬度y的纵坐标。
经度和纬度地图经度(经度)`纬度)`液化天然气'和`纬度的简称,其中从本初子午线向东180度称为东经,用" e": (0,180)表示;西经180度是西经,用“w”表示:十字坐标法
我们通常读“纬度和经度”,实际上,一个位置的书写纬度和经度是“(纬度,经度)”
例如,上海腾讯大厦的定位是:(31.1688749,121.3975184)意思是:纬度=31.1688749,经度=121.3975184
上海腾讯大厦经纬度图的地理哈希原理分析了解了什么是经纬度之后,我们现在可以开始讨论地理哈希原理了。geohash通过以下步骤将经度和纬度子字符串转换为哈希字符串
指定位置的经度和纬度坐标值
根据十字坐标图和二分法将纬度和经度分成1和0的二进制数字串。
根据“偶数表示经度,奇数表示纬度”的算法将经度和纬度两个二进制数字串组合在一起组合
后,二进制数字串自始至终每隔5位数转换成十进制数,少于5位数的用0填充
十进制数字,对应于base32字符串算法的位置,被逐个匹配,并且获得最终的字符串结果。
根据调度划分被截获,得到最终的geohash值
让我们按照这个顺序计算和运算,并结合实例。
1。查找位置的纬度和经度我们可以使用各种地图和定位工具,如谷歌地图,通过定位或搜索位置来轻松查找纬度和经度。
腾讯大厦经纬度这样,我们发现上海腾讯大厦的经纬度为(31.1688749,121.3975184)
2。根据二进制算法,经纬度转换为01二进制上海腾讯大厦经纬度为(31.1688749,121.3975184)
,范围为-90到-90。90)被分成两个部分(-90,0)和(0,90)。如果目标纬度位于上一部分,则代码为0,否则代码为1
被编码为1,因为31.1688749属于(0,90)
然后将(0,90)分成(0,45),(45,90)两个区间,而31.1688749位于(0,45),因此代码为0
然后将(0,45)分成(0,22.5),(22.5,45)两部分,而31.1688749位于(22.5,45),因此代码为1< br>…。< br>….
等,上海腾讯大厦的纬度代码可以如下获得:
101011000101100011111101101经度用同样的算法细分为(-180,180),(-180,0),(0,180),代码为
110101100101001001110111010通过二进制算法,我们得到了腾讯大厦经纬度的二进制字符串如下:
string(30)" 101011000101000111101101101 "现在需要以偶数表示经度,以奇数表示纬度"你怎么理解这个?起初,我不知道如何操作。后来,经过一系列思考,我可以如下操作:
偶数纬度和奇数纬度。因为我无法用语言表达,所以我剪下了一张操作图。如图表上箭头操作顺序所示,将纬度向右移动一个位置,然后按顺序将其串连起来。
是在php代码中实现的,这似乎更容易理解:
//偶数表示经度,奇数表示纬度同样,我们也使用php算法来实现:
//base32映射geohash实际上代表一个矩形块区间,共分为最多12个字符串,即从1到12级。字符数量越多,块间隔越小,定位越准确
我们刚刚用12个级别计算了上海腾讯大厦的地理位置,基本计算位置是毫秒级,可以说非常准确。高于
的是与geohash字符串长度相对应的区间精度。我们可以看到,当geohash为12位时,意味着间隔为37毫米,这已经非常准确了。当geohash为6位时,表示为1.2k范围内的矩形位置
,因此,当两个geohash位置的前7位相同时,这意味着它们在附近1.2km的范围内
然后让我们使用腾讯大厦的geohash值分别截取经度的前7位、第6位和第5位数字,看看它在地图上是什么样子:
精确度< br>精确度< br>精确度在7,153米范围内。因此,根据上图,随着字符越来越少,精确度越来越小,矩形也越来越大在实际应用中,我们可以动态调整精度来实现更大或更小范围的搜索,这样不仅可以准确定位,还可以隐藏位置的位置信息
geohash的边界问题因为geohash代表一个块的信息,所以它被认为是在同一块中的两个位置中最接近的,然而,更接近的位置可能正好在另一个间隔中,从而导致失配问题有一个边界问题
让我们看看实际的例子我们想在腾达1.5公里内找到便利店。我们选择精确度为6的geohash公园里有两个a和b。b离我们更近,但是因为A和腾达在一个散列块中,所以发现A是最好的选择。这是边界问题如何解决
-13边界问题然后如何解决这个边界问题,并给出最新的最佳算法?答案是:计算该位置附近8个方向的geohash。最后,分别计算这些点与自身的距离(因为范围很小,点数也很少,计算量也很小),过滤掉不符合条件的点,就可以了。
8 geohash都是通过余弦定理和弧度计算方法来计算两点之间的距离,最后推导出的公式a是
$ s = acos(cos(rad lat 1)* cos(rad lat 2)* cos(rad ln G1-$ rad ln G2)+sin(rad lat 1)* sin(rad lat 2))* $ r;< br>目前主要由谷歌的公共距离计算公司使用,推导公式b为:
$ s = 2 * asin(sqrt(sin(($ rad lat 1-$ rad lat 2)/2),2)+cos(rad lat 1)* cos(rad lat 2)* power(sin(($ rad ln 1-$ rad ln G2)/2),2))* $ r;< br>其中:
$radLat1,$radLat1,$radLat2,$“Radlnt2是弧度
$R是地球半径
在PHP中实现:
函数获取距离(Lat1,$ lng1,$ lat2,$ LNG 2){redis中的经度和纬度由52位整数编码并放入zset中,其中zset的值元素是键,score是GeoHash的52位整数值当使用redis查询Geo时,其内部对应的操作实际上只是zset(skiplist)的操作坐标附近的其他元素可以通过对zset的分数进行排序来获得,元素的原始坐标
redis可以通过将分数减少到坐标值来获得。处理这些地理位置坐标点的思想是:二维平面坐标点->一维整数编码值-> Zset(score是编码值)-gt;Zrangebyrank(获取具有相似分数的元素),zrangebycore-->;坐标点的分数反解-->;附近点的地理坐标
redis中有6个命令支持地理定位算法。您可以访问redis官方网站查看其使用情况:https://Redis.io/commands # geo
geo add
geo pos
geo dist
geo adius
geo adius by member
geo hash
其他数据
geohash在线转换:http://geohash.co/
转换+地图定位:https://www.movable-type.co.uk/scripts/geohash.html
可以在我们的“腾讯科技”直湖栏目上盖章:
256