利用GeoHash实现逆地理编码(经纬度坐标转换行政区划)

您所在的位置:网站首页 获取经纬度及位置行政地址信息的软件是 利用GeoHash实现逆地理编码(经纬度坐标转换行政区划)

利用GeoHash实现逆地理编码(经纬度坐标转换行政区划)

2024-07-13 02:05| 来源: 网络整理| 查看: 265

目录 前言理解GeoHashGeoHash精度GeoHash特征GeoHash规律 逆地理编码实现逆地理编码的基本思路1.全国范围内6位精度GeoHash计算2.获取全国范围内区/县/三级市级别行政区划地址围栏点3.计算6位精度GeoHash块与区/县/三级市级别行政区划关联关系4.将GeoHash结果值与行政区划关联关系数据存储5.跟据坐标点的GeoHash值查询行政区划信息 结尾

前言

GeoHash是很多基于LBS(Location Based Services)服务不可绕过的解决方案之一,网上关于GeoHash的介绍和算法很多,资源也算比较丰富。这篇文章主要是介绍如何利用GeoHash或者进行逆地理编码(经纬度坐标转换行政区划)的实现。

以中文地址【江苏省南京市玄武区梅园新村街道总统府】为例,省级【江苏省】,市级【南京市】,区县级【玄武区】,街道乡镇级【梅园新村街道】,详细地址【总统府】。由于没有地图服务没有提供街道乡镇级的行政区划polygon数据(行政区划边界的坐标点集合),所以本文利用geoHash进行的逆地理编码的方式,只能到区县级。第四级和详细地址信息,变更相对会比较频繁,需要人工接入,维护成本比较大。 理解GeoHash

GeoHash是按照固定的算法,将经纬度信息转换为Base32码表中的一串字符。具体的算法网上资源较多,不进行详细介绍。逻辑并不是非常复杂,大概逻辑如下:

按照经度范围[-180°,180°],纬度范围[-90°,90°]对目标经纬度进行计算;二分经度和纬度范围区间,分别判断经度和纬度,在右侧集合则为1,在左侧集合则为0;循环进行此计算。将所得经纬度1和0结果,经度在偶数位(从0位计算),纬度在奇数位进行拼接,5位二进制结果为一组,转换为十进制数后,再转换为对应Base32码表中数字,即得到对应GeoHash值。

推荐一个github上GeoHash的实现: GeoHash算法实现

GeoHash精度

GeoHash使用5位计算结果(左右区间)作为一个精度,例如wtw6kf共有6个Base32编码表的字母或数字,代表这个geoHash值的精度为6。

GeoHash特征 以一个坐标点118.797405,32.044227为例,该坐标点实际上是无数个精度更高(小数点后精确位到6位以后)的坐标点集合;将其放大理解,可以看作为一个二维矩形,此二维矩形的4角的坐标值分别应为: 坐标位置经度纬度西南点118.79740532.044227西北点118.79740532.044227999999…东北点118.797405999999…32.044227999999…东南点118.797405999999…32.044227 通过对坐标点的理解, GeoHash的值可以理解为,是无数个经纬度坐标的集合。通过多个经纬度坐标在不同精度的GeoHash计算后,都可以得到一个相同GeoHash的值的规律;可得知,GeoHash的覆盖面积会比经纬度单点的覆盖面积大,只有当GeoHash计算精度越大时,其覆盖面积越小,越近似于经纬度单点的覆盖面积。同类的思路,在我们高等数学中,使用微分计算不规则曲线图形面积时的方法,最终也是极限接近结果。以坐标点118.797405,32.044227(实际地理位置为:江苏省南京市总统府)的6位精度geoHash值wtsqr3为例,其二维矩形4角的坐标值分别为: 坐标位置经度纬度西南点118.79516601562532.0416259765625西北点118.79516601562532.047119140625东北点118.8061523437532.047119140625东南点118.8061523437532.0416259765625

在地图上表现为: 在这里插入图片描述 在线绘制地址围栏

可见该GeoHash块的覆盖面积已经将地理位置江苏省南京市总统府完全覆盖,并且也会覆盖更多其他地区。

GeoHash规律

通过GeoHash的运算规则和全球经纬度范围,可以推导出不同精度的GeoHash块父子级规律:即精度为n的GeoHash会有32个精度为n+1的GeoHash块。例如当GeoHash值精度为1,全世界地图都会被32个GeoHash值覆盖。例如精度为1的GeoHash值w,其会覆盖我国大部分国土。 在这里插入图片描述 在线标选GeoHash块

当GeoHash精度为2时,其展示效果如下: 在这里插入图片描述 当GeoHash精度为3时,其展示效果如下: 在这里插入图片描述 所以如果要遍历GeoHash时,不需要进行经纬度的再次运算,可以根据GeoHash奇偶数的规律,进行GeoHash值的生成。其中奇数位的规律如下表所示: 在这里插入图片描述 偶数位的规律如下表所示: 在这里插入图片描述

逆地理编码

逆地理编码指的是将经纬度坐标转换为具体的标准的行政区划信息,以高德逆地理编码接口为例,坐标点118.797405,32.044227响应的结果如下:

{ "status": "1", "regeocode": { "addressComponent": { "city": "南京市", "province": "江苏省", "adcode": "320102", "district": "玄武区", "towncode": "320102002000", "streetNumber": { "number": "292号", "location": "118.797317,32.044008", "direction": "南", "distance": "25.7166", "street": "长江路" }, "country": "中国", "township": "梅园新村街道", "citycode": "025" }, "formatted_address": "江苏省南京市玄武区梅园新村街道总统府" }, "info": "OK", "infocode": "10000" }

高德逆地理编码接口在线测试

此篇博文只介绍可以模拟到行政区划的省/直辖市、二级市、区/县/三级市的方式。如果想要详细地址(这个需要GPS终端进行实际定位,再转换火星坐标系进行记录)或者乡/镇/街道级别的地址信息,人工维护成本比较大,以笔者不算太长的地图服务接触时间来看,我们国家因城市化速度较快等原因,第四级的行政区划变更速度比较频繁。

实现逆地理编码的基本思路 1.全国范围内6位精度GeoHash计算 如果按照GeoHash的算法,需要使用全国的示例点进行计算得到结果,这个计算量和工作量非常巨大,基本上可以考虑放弃。按照上述的GeoHash规律,我们可以轻易的通过GeoHash奇偶数表获取全国所有的6位精度GeoHash值。首先确定全国2位精度GeoHash块(甚至3位)有多少,此数据可以直接通过画图来获取粗略结果,如下图所示: 在这里插入图片描述可见全国(不包含中国南海三沙市)的2位精度GeoHash块约为29块,那么,计算得出的6位精度和7位精度GeoHash值数量分别应为:

6位精度数量:29 * 25 * 25* 25* 25 = 30408704 7位精度数量:29 * 25 * 25* 25* 25 * 25= 973078528

6位精度的Geohash值可以麻烦大部分数据需求,7位精度Geohash值主要市为了解决区/县/三级市行政区划边界点与6位精度GeoHash块重合现象,7位精度的GeoHash值并不需要完全计算。 2.获取全国范围内区/县/三级市级别行政区划地址围栏点 首先感谢高德,行政区划地址围栏坐标点的数据需要从高德开放平台获取(高德开放平台地址围栏点比腾讯地图提供的要精准),申请一个高德的Key,批量拉去数据即可。注意编写脚本时建议写入文本文件或者直接写入数据库,数据量比较大。高德在线测试获取行政区划围栏点 拉取数据时,注意区/县/三级市级别行政区划名称有可能会重复,建议使用adcode字段进行区分。拉取得围栏点在地图中示例(江苏省南京市玄武区)如下,比较可靠: 在这里插入图片描述 3.计算6位精度GeoHash块与区/县/三级市级别行政区划关联关系 使用java7原生API可以判断GeoHash块(二维矩形)与区/县/三级市级别行政区划是否包含或相交,主要使用如下2个类: import java.awt.Polygon; import java.awt.geom.Area;

判断是否包含: 在这里插入图片描述

判断是否相交: 在这里插入图片描述

如果包含,则记录该区县级别行政区划信息与对应精度的GeoHash值的关联关系;如果不包含也不相交,则不保留关系;如果相交,则遍历当前精度的GeoHash值下一精度GeoHash值,重复2 3步骤,直到包含关系,并存储GeoHash值和对应行政区划信息。 注意: 由于数据量和计算量大,在编写脚本遍历时,尽量减少O(n)n的大小,例如GeoHash值tz仅在新疆范围内,遍历tz开头的6位精度GeoHash值时,可以仅将新疆地区行政区划参与计算。建议脚本中计算完毕部分数据就写入本地或者数据库,脚本写的粗糙的话,跑计算时很有可能会OOM。 4.将GeoHash结果值与行政区划关联关系数据存储 使用散列表存储所有的GeoHash值与行政区划关联关系。根据GeoHash的规律,参考坐标118.797405,32.044227各精度GeoHash值: 精度GeoHash值1w2wt3wts4wtsq5wtsqr6wtsqr37wtsqr338wtsqr33x

为了减少单个散列表中数据量过大问题,可以按照2位精度或者3位精度GeoHash值区分存储,具体策略可以根据具体场景自行调整。

5.跟据坐标点的GeoHash值查询行政区划信息 将目标坐标点进行7位精度GeoHash值计算根据GeoHash值获取对应散列表数据,查询获取结果。 结尾

以上查询过程很简单,复杂度O(1)即可拿到对应行政区划数据,不过1-4步骤的数据初始化过程需要人工介入次数较多;在部分边界点处理上,出现7位精度GeoHash仍然是相交而不是包含时,可以选择人工处理或上升到8位精度,按照大部分业务需求不建议上升至9位精度以上计算;如果采用人工处理,可以根据GeoHash覆盖点大小直接确定行政区划归属。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3