逆地理编码-离线版-part1

Posted mtj66

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逆地理编码-离线版-part1相关的知识,希望对你有一定的参考价值。

在数据处理过程中经常遇到经纬度需要解析成地址的问题,即逆地理编码。

如果为了获取高精度的数据,可以采用百度or高德的逆地理编码接口,但是个人请求量受限,企业版限额会高一些。

那有没有不限额的逆地理编码方案呢?

本文提供一种离线方案,实现经纬转地址信息的方案,精度为乡镇街道粒度,响应速度单核4ms/每条,能满足一般的逆地理编码需求。

本文分模块提供如下代码。

程序主入口为 getGeoInfo,具体参考如下代码。

from s2sphere import CellId

from s2sphere import LatLng

import GeoUtils
import S2Utils, LineUtils
from geo_obj import *
# pip --trusted-host pypi.tuna.tsinghua.edu.cn install s2sphere
from data_loader import boundaryAdminCell, boundaryIndex, boundaryData, adminData, streetData, cityBusinessArea, \\
cityLevelData

min_level = 12


def init(needBoundary=True, needArea=False, needStreet=True, needCityLevel=False):
"""
按需初始化数据, 离线数据处理可以不加载该方法
:param needBoundary: 是否需要加载边界数据,用于经纬度转换省市区县
:param needArea: 是否需要加载商圈数据
:param needStreet: 是否需要加载街道数据
:param needCityLevel: 是否需要加载城市级别数据
:return:
"""

adminData
if needBoundary:
boundaryData
boundaryIndex
boundaryAdminCell

if needStreet:
streetData
if needArea:
cityBusinessArea
if needCityLevel:
cityLevelData


def determineAdminCode(lonIn: float, latIn: float, coordSys: CoordinateSystem = CoordinateSystem.GCJ02):
gcj02LonLat = GeoUtils.toGCJ02(lonIn, latIn, coordSys)
lon = gcj02LonLat[0]
lat = gcj02LonLat[1]
# print(lon, lat)
# lon = 112.989382
# lat = 28.147062

s2LatLng = LatLng.from_degrees(lat, lon)
id1 = CellId.from_lat_lng(s2LatLng).parent(min_level).id()

id2 = CellId.from_lat_lng(s2LatLng).parent(min_level - 2).id()
if GeoUtils.outOfChina(lon, lat):
return -1
elif boundaryAdminCell.get(id1) is not None:
return boundaryAdminCell.get(id1)
elif boundaryAdminCell.get(id2) is not None:
return boundaryAdminCell.get(id2)
else:
keys = []
maxLevel = 2000 # 必须大于2000m,否则会出现格子半径过小选择错误问题
# 最远距离 为新疆哈密市80公里
while len(keys) == 0 and maxLevel < 200000:
newKeys = S2Utils.getCellId(s2LatLng, maxLevel, min_level)
# newKeys = []
for key in newKeys:
if boundaryIndex.get(key) is not None:
# print("flatmap", key, maxLevel, boundaryIndex.get(key))
keys.extend(boundaryIndex.get(key))

maxLevel = maxLevel * 2

def fun_(key, s2LatLng):
# 修改成 getutils distance
# return (key, CellId(key).to_lat_lng().get_distance(s2LatLng))
# return key, GeoUtils.get_earth_distance(CellId(key).to_lat_lng(), s2LatLng)
latlng = CellId(key).to_lat_lng()
dis = GeoUtils.get_earth_dist(latlng, s2LatLng)
return key, dis

# print(newKeys, newKeys)
if len(keys) > 0:
# lines1 = map(lambda key: fun_(key, s2LatLng),newKeys)
lines1 = []
for key in keys:
lines1.append(fun_(key, s2LatLng))
lines1.sort(key=lambda x: x[1])
# take 5
lines1_tak5 = lines1[0:5]
# print("lines1_tak5 ", lines1_tak5)
res1 = []
# flatmap
for startPoint in lines1_tak5:
if boundaryData.get(startPoint[0]) is not None:
values = boundaryData.get(startPoint[0])
for value in values:
res1.extend(
[(startPoint[0], value[0], value[1], True), (startPoint[0], value[0], value[2], False)])
lines1 = []
for line in res1:
start = CellId(line[0]).to_lat_lng()
end = CellId(line[1]).to_lat_lng()
dis = LineUtils.pointToLineDis(start.lng().degrees, start.lat().degrees, end.lng().degrees,
end.lat().degrees, lon, lat)
lines1.append((((start.lng().degrees, start.lat().degrees), (end.lng().degrees, 使用定位,逆地理编码,经纬度《=转=》地址信息逆地理编码,地址《=转=》经纬度,贼方便!!!!

基于矢量数据的逆地理编码功能实现

FT实现逆地理编码&报错处理

高德地图:地理/逆地理编码

高德地图的API怎么用URL实现地理编码/逆地理编码?

CDH5.7Hadoop集群搭建(离线版)