本文主要提供工具类代码:

AdminUtils.py

# -*- coding: utf-8 -*-import reNATIONS = "阿昌族,鄂温克族,傈僳族,水族,白族,高山族,珞巴族,塔吉克族,保安族,仡佬族,满族,塔塔尔族,布朗族,哈尼族,毛南族,土家族,布依族,哈萨克族,门巴族,土族,朝鲜族,汉族,蒙古族,佤族,达斡尔族,赫哲族,苗族,维吾尔族,傣族,回族,仫佬族,乌孜别克族,德昂族,基诺族,纳西族,锡伯族,东乡族,京族,怒族,瑶族,侗族,景颇族,普米族,彝族,独龙族,柯尔克孜族,羌族,裕固族,俄罗斯族,拉祜族,撒拉族,藏族,鄂伦春族,黎族,畲族,壮族".split(",")p1 = """(.+)(?:省|市)"""
p2 = """(.+)自治区"""
p3 = """(.+)特别行政区"""c0 = """^(.{2})$"""  # 2 长度为2的 "东区" "南区"
c1 = """(.+)(?:自治州|自治县)$"""  # 30 自治州  琼中黎族苗族自治县
c2 = """(.+)[市|盟|州]$"""  # 304 地级市, 盟; + 1恩施州
c3 = """(.+)地区$"""  # 8 地区
c4 = """(.+)(?:群岛|填海区)$"""  # 2 东沙群岛
c5 = """(.+[^地郊城堂])区$"""  # 20 港澳 不含"东区" "南区"2个字的
c6 = """(.+)(?:城区|郊县)$"""  # 6 九龙城区,上海城区,天津城区,北京城区,重庆城区,重庆郊县
c7 = """(.+[^郊])县$"""  # 12 台湾的xx县d0 = """^(.{2})$"""  # 2 长度为2的 "随县"
d1 = """(.+)[市]$"""  # 304 城区 “赤水市”
d2 = """(.+)自治县$"""  # 30 自治县
d3 = """(.+)自治州直辖$"""  # 30 自治州直辖 "海西蒙古族藏族自治州直辖"
d4 = """(.+)[区|县]$"""  # 8 区县
d5 = """(.+)(?:乡|镇|街道)$"""  # 8 乡镇|街道s0 = """^(.{2})$"""
s1 = """(.+)(?:特别行政管理区|街道办事处|旅游经济特区|民族乡|地区街道)$"""
s2 = """(.+)(?:镇|乡|村|街道|苏木|老街|管理区|区公所|苏木|办事处|社区|经济特区|行政管理区)$"""def replaceNations(ncity: str):for e in NATIONS:ncity = ncity.replace(e, '')return ncity# return zip([ncity] ++ NATIONS).reduce((x, y) => x.replaceAll(y, "").replaceAll(if(y.length > 2) y.replaceAll("族", "") else "", ""))def shortProvince(province: str):# (.+)特别行政区# (.+省|.+自治区)(.+市)res = re.match(p1, province, flags=0)if res:return res.group()res = re.match(p2, province, flags=0)if res:return res.group()res = re.match(p3, province, flags=0)if res:return res.group()# case p1(x) => x# case p2(x) => if(x== "内蒙古") x else replaceNations(x)# case p3(x) => x# case _ => provincereturn provincedef shortCityImp(city: str):""":param city::return: (city,-1)"""# 总数 383if re.match(c0, city, flags=0):return re.match(c0, city, flags=0).group(), 0elif re.match(c1, city, flags=0):return re.match(c1, city, flags=0).group(), 1elif re.match(c2, city, flags=0):return re.match(c2, city, flags=0).group(), 2elif re.match(c3, city, flags=0):return re.match(c3, city, flags=0).group(), 3elif re.match(c4, city, flags=0):return re.match(c4, city, flags=0).group(), 4elif re.match(c5, city, flags=0):return re.match(c5, city, flags=0).group(), 5elif re.match(c6, city, flags=0):return re.match(c6, city, flags=0).group(), 6elif re.match(c7, city, flags=0):return re.match(c7, city, flags=0).group(), 7# case c0(x) => (x, 0)# case c1(x) => (replaceNations(x), 2)# case c2(x) => if(x == "襄樊") ("襄阳",1) else (x, 1)# case c3(x) => (x,3)# case c4(x) => (x,4)# case c5(x) => (x,5)# case c6(x) => (x,6)# case c7(x) => (x,7)# case _ => (city, -1)return city, -1def shortDistrictImp(district: str):""":param district: :return: (String, Int) """# // 总数 2963 56个内蒙八旗和新疆兵团没有处理if re.match(d0, district, flags=0):return re.match(d0, district, flags=0).group()elif re.match(d1, district, flags=0):return re.match(d1, district, flags=0).group()elif re.match(d2, district, flags=0):return replaceNations(re.match(d2, district, flags=0).group()),2elif re.match(d3, district, flags=0):return replaceNations(re.match(d3, district, flags=0).group()),3elif re.match(d4, district, flags=0):return re.match(d4, district, flags=0).group()elif re.match(d5, district, flags=0):return re.match(d5, district, flags=0).group()# match {#  case d0(x) => (x, 0)#  case d1(x) => (x, 1)#  case d2(x) => (replaceNations(x), 2)#  case d3(x) => (replaceNations(x), 3)#  case d4(x) => (x,4)#  case d5(x) => (x,5)#  case _ => (district, -1)def replaceNationsNotEmpty(name: str):for e in NATIONS:name_ = name.replace(e, '').replace(e.replace('族', ''))if len(name_) >= 0:name = name_return namedef shortStreetImp(street: str):""":param street::return:"""# // 总数 42387# // 柘城县邵园乡人民政府, 保安镇, 鹅湖镇人民政府, 东风地区if re.match(s0, street, flags=0):return re.match(s0, street, flags=0).group(), 0elif re.match(s1, street, flags=0):return replaceNationsNotEmpty(re.match(s1, street, flags=0).group()), 1elif re.match(s2, street, flags=0):return replaceNationsNotEmpty(re.match(s2, street, flags=0).group()), 2# street match {#   case s0(x) => (x, 0)#   case s1(x) => (replaceNationsNotEmpty(x), 1)#   case s2(x) => (replaceNationsNotEmpty(x), 2)#   case _ => (street, -1)# }return street, -1if __name__ == '__main__':shortProvince("安徽省宿州市埇桥区")shortProvince("天津市")shortProvince("内蒙古自治区")shortProvince("香港特别行政区")

GeoUtils.py

import math
from s2sphere import LatLng, Anglefrom geo_obj import Location, CoordinateSystemx_PI = math.pi * 3000.0 / 180.0
EE = 0.00669342162296594323
A = 6378245.0  # BJZ54坐标系地球长半轴, m
EQUATOR_C = 20037508.3427892  # 赤道周长, m
EARTH_RADIUS = 6378137.0  # WGS84, CGCS2000坐标系地球长半轴, m
EARTH_POLAR_RADIUS = 6356725.0  # 极半径, mSQRT2 = 1.414213562def outOfChina(lng, lat):return lng < 72.004 or lng > 137.8347 or lat < 0.8293 or lat > 55.8271def transformLat(lng: float, lat: float):ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * math.sqrt(abs(lng))ret += (20.0 * math.sin(6.0 * lng * math.pi) + 20.0 * math.sin(2.0 * lng * math.pi)) * 2.0 / 3.0ret += (20.0 * math.sin(lat * math.pi) + 40.0 * math.sin(lat / 3.0 * math.pi)) * 2.0 / 3.0ret += (160.0 * math.sin(lat / 12.0 * math.pi) + 320 * math.sin(lat * math.pi / 30.0)) * 2.0 / 3.0return retdef transformLng(lng: float, lat: float):ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * math.sqrt(abs(lng))ret += (20.0 * math.sin(6.0 * lng * math.pi) + 20.0 * math.sin(2.0 * lng * math.pi)) * 2.0 / 3.0ret += (20.0 * math.sin(lng * math.pi) + 40.0 * math.sin(lng / 3.0 * math.pi)) * 2.0 / 3.0ret += (150.0 * math.sin(lng / 12.0 * math.pi) + 300.0 * math.sin(lng / 30.0 * math.pi)) * 2.0 / 3.0return retdef rad(d: float):return d * math.pi / 180.0def get_earth_dist(locA: LatLng, locB: LatLng, radius=6367000.0):""":param locA::param locB::param radius::return:"""lat1 = locA.lat().radians;lat2 = locB.lat().radians;lng1 = locA.lng().radians;lng2 = locB.lng().radians;dlat = math.sin(0.5 * (lat2 - lat1));dlng = math.sin(0.5 * (lng2 - lng1));x = dlat * dlat + dlng * dlng * math.cos(lat1) * math.cos(lat2);dis = (2.0 * math.atan2(math.sqrt(x), math.sqrt(max(0.0, 1.0 - x))))dist = dis * radiusreturn distdef get_earth_distance(locA: LatLng, locB: LatLng):""":param locA: .degrees or radians:param locB::return:"""try:# print(f'locA={locA},locB={locB}')lngA = float(str(locA).split(',')[1])latA = float(str(locA).split(',')[0].split(" ")[1])lngB = float(str(locB).split(',')[1])latB = float(str(locB).split(',')[0].split(" ")[1])f = rad((latA + latB) / 2)g = rad((latA - latB) / 2)l = rad((lngA - lngB) / 2)if g == 0 and l == 0:return 0sg = math.sin(g)sl = math.sin(l)sf = math.sin(f)s = .0c = .0w = .0r = .0d = .0h1 = .0h2 = .0dis = .0a = EARTH_RADIUSfl = 1 / 298.257sg = sg * sgsl = sl * slsf = sf * sfs = sg * (1 - sl) + (1 - sf) * slc = (1 - sg) * (1 - sl) + sf * slw = math.atan(math.sqrt(s / c))r = math.sqrt(s * c) / wd = 2 * w * ah1 = (3 * r - 1) / 2 / ch2 = (3 * r + 1) / 2 / sdis = d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg))except:print('get_earth_distance failed')return -1return float(f"{dis:.2f}")def distance(locA: Location, locB: Location):lngA = locA.lnglatA = locA.latlngB = locB.lnglatB = locB.latf = rad((latA + latB) / 2)g = rad((latA - latB) / 2)l = rad((lngA - lngB) / 2)if (g == 0 and l == 0):return 0sg = math.sin(g)sl = math.sin(l)sf = math.sin(f)s = .0c = .0w = .0r = .0d = .0h1 = .0h2 = .0dis = .0a = EARTH_RADIUSfl = 1 / 298.257sg = sg * sgsl = sl * slsf = sf * sfs = sg * (1 - sl) + (1 - sf) * slc = (1 - sg) * (1 - sl) + sf * slw = math.atan(math.sqrt(s / c))r = math.sqrt(s * c) / wd = 2 * w * ah1 = (3 * r - 1) / 2 / ch2 = (3 * r + 1) / 2 / sdis = d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg))return float(f"{dis:.2f}")def wgs84ToGCj02(lng: float, lat: float):""":param lng::param lat::return:"""mglat = .0mglng = .0if outOfChina(lng, lat):mglat = latmglng = lngelse:dLat = transformLat(lng - 105.0, lat - 35.0)dLon = transformLng(lng - 105.0, lat - 35.0)radLat = lat / 180.0 * math.pimagic = math.sin(radLat)magic = 1 - EE * magic * magicsqrtMagic = math.sqrt(magic)dLat = (dLat * 180.0) / ((A * (1 - EE)) / (magic * sqrtMagic) * math.pi)dLon = (dLon * 180.0) / (A / sqrtMagic * math.cos(radLat) * math.pi)mglat = lat + dLatmglng = lng + dLonreturn mglng, mglatdef toGCJ02(lng: float, lat: float, coordType: CoordinateSystem):"""判断坐标系转换:param lng::param lat::param coordType::return:"""if coordType.value == CoordinateSystem.WGS84.value:d = wgs84ToGCj02(lng, lat)return dif coordType.value == CoordinateSystem.BD09.value:d = bd09ToGCJ02(lng, lat)return dreturn lng, latdef gcj02ToWgs84(lng: float, lat: float):if outOfChina(lng, lat):return lng, latdlat = transformLat(lng - 105.0, lat - 35.0)dlng = transformLng(lng - 105.0, lat - 35.0)radlat = lat / 180.0 * math.pimagic = math.sin(radlat)magic = 1 - EE * magic * magicsqrtmagic = math.sqrt(magic)dlat = (dlat * 180.0) / ((A * (1 - EE)) / (magic * sqrtmagic) * math.pi)dlng = (dlng * 180.0) / (A / sqrtmagic * math.cos(radlat) * math.pi)mglat = lat + dlatmglng = lng + dlngreturn lng * 2 - mglng, lat * 2 - mglatdef toWGS84(lng: float, lat: float, coordType: CoordinateSystem):"""判断坐标系转换:type lat: object:param lng::param lat::param coordType::return:"""# print("CoordinateSystem.GCJ02 compare", coordType == CoordinateSystem.GCJ02,dir(coordType),dir(CoordinateSystem.GCJ02))if coordType.value == CoordinateSystem.GCJ02.value:return gcj02ToWgs84(lng, lat)elif coordType.value == CoordinateSystem.BD09.value:d02 = bd09ToGCJ02(lng, lat)return gcj02ToWgs84(d02[0], d02[0])else:return lng, latdef bd09ToGCJ02(lng: float, lat: float):if outOfChina(lng, lat):return lng, latx = lng - 0.0065y = lat - 0.006z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * x_PI)theta = math.atan2(y, x) - 0.000003 * math.cos(x * x_PI)gg_lng = z * math.cos(theta)gg_lat = z * math.sin(theta)return gg_lng, gg_lat

LineUtils.py

# // 计算两点之间的距离import mathdef lineDis(x1: float, y1: float, x2: float, y2: float):return math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))def pointToLineDis(x1: float , y1: float , x2: float , y2: float , x0: float , y0: float ): a = lineDis(x1, y1, x2, y2) #  线段的长度b = lineDis(x1, y1, x0, y0) #  点到起点的距离c = lineDis(x2, y2, x0, y0) #  点到终点的距离# 点在端点上if c <= 0.000001 or b <= 0.000001:return 0# 直线距离过短if a <= 0.000001:return b#  点在起点左侧,距离等于点到起点距离if c * c >= a * a + b * b:return b# 点在终点右侧,距离等于点到终点距离if b * b >= a * a + c * c:return c# 点在起点和终点中间,为垂线距离k = (y2 - y1) / (x2 - x1)z = y1 - k * x1p = (a + b + c) / 2#  半周长s = math.sqrt(p * (p - a) * (p - b) * (p - c))  # 海伦公式求面积return 2 * s / a  # 回点到线的距离(利用三角形面积公式求高)

S2Utils.py

import math
from s2sphere import Cap
from s2sphere import RegionCoverer
from s2sphere import *kEarthCircumferenceMeters = 1000 * 40075.017def earthMeters2Radians(meters: float)  :return (2 * math.pi) * (meters / 40075017)# // 预算,提升速度
def earthMeters2Radians_(radius):rad = earthMeters2Radians(radius * 1000)return radius * 1000, rad * rad * 2capHeightMap_ = map(lambda radius:earthMeters2Radians_(radius),[2, 4, 8, 16, 32, 64, 128, 256])
capHeightMap = {}
for e1,e2 in capHeightMap_:capHeightMap[e1] = e2
print(capHeightMap)def getLevel(inputs: int):""":param inputs::return:"""n = 0input = inputs# print(input, inputs)while input % 2 == 0:input = input / 2n += 1return 30 - n / 2def getCellId(s2LatLng: LatLng, radius: int, desLevel: int):capHeight = capHeightMap.get(radius) if capHeightMap.get(radius) else 0cap = Cap.from_axis_height(s2LatLng.to_point(), capHeight)coverer = RegionCoverer()coverer.min_level = desLevelcoverer.max_level = desLevel""">>> a = A()>>> getattr(a, 'bar')          # 获取属性 bar 值>>> setattr(a, 'bar', 5)       # 设置属性 bar 值"""#  圆形内的cell会自动做聚合,手动拆分res = []cellIds = coverer.get_covering(cap)for s2CellId in cellIds:cellLevel = getLevel(s2CellId.id())if (cellLevel == desLevel):res.append(s2CellId.id())else:res.extend([cellid.id() for cellid in childrenCellId(s2CellId, cellLevel, desLevel)])return resdef childrenCellId(s2CellId: CellId, curLevel: int, desLevel: int):list = []if (curLevel < desLevel) :inter= (s2CellId.childEnd.id - s2CellId.childBegin.id) / 4for i in range(0,5):id = s2CellId.childBegin.id + inter * icellId = CellId(id)list.append( childrenCellId(cellId, curLevel + 1, desLevel))else:list.append(s2CellId)return listif __name__ == '__main__':getLevel(100)

逆地理编码-离线版-part2相关推荐

  1. android studio高德地图的显示于定位(附带逆地理编码围栏)

    首先注册高德成为开发者(打开高德地图,点击底部的开发者平台),创建应用,按照要求填写相应信息 网站:http://lbs.amap.com/api/android-sdk/guide/create-p ...

  2. python调用百度地图画轨迹图_[python]百度地图API,正/逆地理编码,路线规划接口的调用,实现输出出行的距离和......

    [Python] 纯文本查看 复制代码''' 文件名:L17.py 作者:小饭团 创建时间:2019年1月11日15:17:03 文件描述:调用Web服务API接口,百度地图路线规划 正/逆地理编码 ...

  3. php 百度逆地理编码,百度逆地址解析

    http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding city 否 "北京市" &qu ...

  4. 调用高德逆地理接口_地理编码与逆地理编码

    本章主要介绍如何将地址描述信息和地理坐标做相互转化,主要包括以内容:正向地理编码 逆向地理编码 地理编码服务 地理编码包含正向地理编码和逆向地理编码两种:正向地理编码: 将地址描述信息转换成地理坐标( ...

  5. 技巧 | 在R语言中使用高德地图的API进行地理/逆地理编码(地址与经纬度的相互转换)...

    高德地图和百度地图都提供了坐标拾取系统,通过坐标查询或坐标反查操作可以查询一个地址对应的经纬度或经纬度对应的地址名称.但是,手动查询的方式效率很低,也不能进行批量查询. 本篇就来介绍在R语言中调用高德 ...

  6. Unity GPS定位之逆地理编码(获取经纬度并转换成地理位置)

    unity定位 前言 最近在做一款手游,然后策划给的需求就是定位到当前用户所在的城市,然后花了一个上午给做了出来,思路大概就是通过手机定位获取到当前位置的经度和纬度,然后通过各个地图(我这里用的是百度 ...

  7. python百度地图api经纬度_详解用Python调用百度地图正/逆地理编码API

    一.背景 (正)地理编码指的是:将地理位置名称转换成经纬度: 逆地理编码指的是:将经纬度转换成地理位置信息,如地名.所在的省份或城市等 百度地图提供了相应的API,可以方便调用.相应的说明文档如下: ...

  8. 高德地图地理编码和逆地理编码,以及逆地理编码的时候如何去掉省、市、镇

    地理编码和逆地理编码 首先说说,何为地理编码, 地理编码就是 给你一个地名,得到对应的经纬度(纬经度,高德地图实际是纬经度) 知道地理编码,那么逆地理编码就不难理解了. 逆地理编码就是给出经纬度,得到 ...

  9. php 百度逆地理编码,百度地图开放平台 Web服务API --Geocoding API (地理编码和逆地理编码)...

    百度地图开放平台地理编码服务和逆地理编码服务的api文档地址:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geoco ...

最新文章

  1. PLSQL的DBMS_GETLINE
  2. vue 生产word_nodejs(officegen)+vue(axios)在客户端导出word文档
  3. [算法系列之二十六]字符串匹配之KMP算法
  4. python 3.7.732位安装步骤_Python3.7安装pyaudio教程解析
  5. python算法系列资料集(三)
  6. “use strict” 严格模式使用(前端基础系列)
  7. Mysql 常用show命令
  8. Firebug控制台详解(转)
  9. 拓端tecdat|R语言结构方程模型 SEM 多元回归和模型诊断分析学生测试成绩数据与可视化
  10. 《从零开始做抖音》 程然
  11. Win10截图和草图无法使用怎么办
  12. unl导入导出数据库
  13. 计算机高级搜索文章内容,外文信息计算机检索
  14. 树莓派烧写OpenWrt系统后外接4G模块实现4G路由即MiFi
  15. QQ2010协议技术详细分析QQ登陆过程
  16. 系统集成项目管理工程师(软考中级)—— 第八章 新一代信息技术 笔记分享
  17. 如何在图片中添加文字
  18. FPGA流水灯和跑马灯
  19. 图片全屏查看js插件
  20. 下三角矩阵的压缩存储

热门文章

  1. 西安80转2000坐标参数_!!!西安80坐标与地方坐标系的转换方法技巧
  2. 论中国足球教练排名,“神奇教练”米卢说第二,没人敢称第一
  3. 服务器无法远程访问的原因有哪些
  4. 2021-2027全球与中国3,5-二氯-4-甲基吡啶市场现状及未来发展趋势
  5. js渲染10万数据列表,不阻塞UI
  6. 你还在这样做:浏览器“记住用户名密码”?
  7. riboPOOL—适合任意物种(真核生物、原核生物、高丰度mRNA)的核糖体RNA/rRNA去除方案(探针法)siTOOLs Biotech中国总代理蓝景科信
  8. 微信公众平台定制开发
  9. win7 android usb驱动,在win7系统下安装手机usb驱动软件的教程
  10. 卷积网络中的通道、特征图、过滤器和卷积核