"""功能模块""" import math from typing import TypedDict, Union import jmespath import pydash import requests # WechatMapClass.haversine(lat1=32. # 474664, lon1=119.893471, lat2=32. # 471578, lon2=119.917068) # WechatMapClass.addressToCoordinat # eConversion(address="江苏省泰州市海陵区济川东路与青年南路交叉口东220米泰州万达广场(2号入口)") # WechatMapClass.coordinateToAddressConversion(location="32.474664,119.893471") # WechatMapClass.coordinateToAddressConversion(location="32.471578,119.917068") class OriginPointOptional(TypedDict): 经度: Union[float, str] 纬度: Union[float, str] from pydantic import BaseModel class AdInfo(BaseModel): city: str adcode: int nation: str district: str province: str nation_code: int class Location(BaseModel): lat: float lng: float class Result(BaseModel): ip: str ad_info: AdInfo location: Location class IP解析地址模型Response(BaseModel): result: Result status: int message: str class wei地图工具: """注释""" key = "7SNBZ-FLN63-LRA3S-YJBAK-XSHQ3-TGF5E" # 腾讯地图的key # key = "LREBZ-PH5R7-2NIXW-H7JDB-CVHTK-4YFUJ" # 莫大帅注册地地图的腾讯地图的key @classmethod def 公式计算二点之间的距离(cls, orgin原点: OriginPointOptional, user原点: OriginPointOptional) -> float: """""" # 地球半径,单位为公里 R = 6371.0 # orgin原点: OriginPointOptional = {"纬度": 30.80377, "经度": 104.151812} # user原点: OriginPointOptional = {"纬度": 30.80377, "经度": 104.151812} # 将角度转换为弧度 orgin纬度 = math.radians(orgin原点.get("纬度")) orgin经度 = math.radians(orgin原点.get("经度")) user纬度 = math.radians(user原点.get("纬度")) user经度 = math.radians(user原点.get("纬度")) # 经纬度差值 经度差 = user经度 - orgin经度 纬度差 = user纬度 - orgin纬度 print(经度差, 纬度差) # Haversine公式 a = math.sin(纬度差 / 2) ** 2 + math.cos(orgin纬度) * math.cos(user纬度) * math.sin(经度差 / 2) ** 2 c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) # 计算两点间的距离 distance = R * c print(f"The distance between two points is {distance} km.") return distance @classmethod def 腾讯地图计算二点之间的距离(cls, toData终点: OriginPointOptional, fromData起点: OriginPointOptional): """""" fromStrDat = dict(sorted(fromData起点.items(), reverse=False)) fromStr = ",".join(fromStrDat.values()) toStrDat = dict(sorted(toData终点.items(), reverse=False)) toStr = ",".join(toStrDat.values()) print("排序后的值为", fromStr, toStr) data = {"key": cls.key, "from": fromStr, "to": toStr} url = f"https://apis.map.qq.com/ws/distance/v1/matrix?mode=driving" res_data = requests.post(url=url, data=data) print(res_data.json()) res_json = res_data.json() # type: dict d = { "status": 0, "message": "Success", "request_id": "9435209f1ee84219ae7826e65f577331", "result": { "rows": [{ "elements": [{ "distance": 3550, # 起点到终点的距离,单位:米 "duration": 651, # 表示从起点到终点的结合路况的时间,秒为单位注:步行/骑行方式(不计算耗时)以及起终点附近没有道路造成无法计算时,不返回本此节点 }], }], }, } distance = jmespath.search(data=res_data.json(), expression="result.rows[0].elements[0].distance") return distance @classmethod def 地址转换为坐标(cls, address: str): """""" url = f"https://apis.map.qq.com/ws/geocoder/v1/?address={address}" res = requests.get(url=url, params={"key": cls.key}, ) d = { "status": 0, "message": "Success", "request_id": "9b049a3ff13c4ac3bda3bb5a9fe0c0a8", "result": { "title": "泰州海陵万达广场", "location": { # 解析到的坐标(GCJ02坐标系) "lng": 119.917068, # 经度 "lat": 32.471578, # 纬度 }, "ad_info": { # 行政区划信息 object 是 "adcode": "321202", # string 是 行政区划代码,规则详见:行政区划代码说明 }, "address_components": { "province": "江苏省", "city": "泰州市", "district": "海陵区", "street": "济川东路", "street_number": "", }, "similarity": 0.99, "deviation": 1000, "reliability": 7, # 可信度参考:值范围 1 <低可信> - 10 <高可信> "level": 11, # 解析精度级别,分为11个级别,一般>=9即可采用(定位到点,精度较高) 也可根据实际业务需求自行调整,完整取值表见下文。 }, } @classmethod def 经纬度转换为地址(cls, location): """""" pass url = f"https://apis.map.qq.com/ws/geocoder/v1/?location={location}" res = requests.get(url=url, params={"key": cls.key}, ) return res.json() @classmethod def ip地址转为地址(cls, x_forwarded_for: str | bool, ): """""" url = "https://apis.map.qq.com/ws/location/v1/ip" response_data = requests.get(url=url, params={"key": cls.key, "ip": x_forwarded_for}, ) data = response_data.json() # type: dict print(data) resData = pydash.omit(data, "request_id") d = { "status": 0, "message": "Success", "request_id": "8805bff3303f42dd8a1cbcca3701cf63", "result": { "ip": "240e:3a3:b201:3f10:185c:efdb:c5b0:b95c", "location": { "lat": 32.49098, "lng": 119.91956, }, "ad_info": { "nation": "中国", "province": "江苏省", "city": "泰州市", "district": "海陵区", "adcode": 321202, "nation_code": 156, }, }, } # nation = jmespath.search(data=data, expression="result.ad_info.nation", ) # 国家 # province = jmespath.search(data=data, expression="result.ad_info.province", ) # 省份 # city = jmespath.search(data=data, expression="result.ad_info.city", ) # district = jmespath.search(data=data, expression="result.ad_info.district", ) # 区 # adcode = jmespath.search(data=data, expression="result.ad_info.adcode", ) # 区号 # ip = jmespath.search(data=data, expression="result.ip", ) # lat = jmespath.search(data=data, expression="result.location.lat", ) # lng = jmespath.search(data=data, expression="result.location.lng", ) return resData if __name__ == "__main__": # wei地图工具.腾讯地图计算二点之间的距离(toData终点={"纬度": "30.80377", "经度": "104.151812"}, fromData起点={"纬度": "30.80377", "经度": "104.151812"}) print(wei地图工具.ip地址转为地址(x_forwarded_for="119.84.150.100", ))