part1: 主要为使用示例,以及主逻辑判断
逆地理编码-离线版-part1_mtj66的博客-CSDN博客
part2: 主要为工具类
逆地理编码-离线版-part2_mtj66的博客-CSDN博客
本文为逆地理编码离线版的第三部分,前面提供工具类,以及使用逻辑。
本文主要提供,数据加载,以及geo对象类,方便格式化数据。
geo_obj.py
# coding=utf-8
from enum import Enum, unique
# from geo import AdminUtils
import AdminUtils
CHINA_NAME = "中国"
CHINA_ID = "CN"
OVERSEA_NAME_VAL = "海外"
UNKNOWN_NAME_VAL = "未知"
UNKNOWN_ID_VAL = -1
UNKNOWN_LOCATION_VAL = None
@unique
class CoordinateSystem(Enum):
#
WGS84 = 0 # GPS
# 坐标系
GCJ02 = 1 # 国测局坐标系(火星坐标系)
BD09 = 2 # 百度坐标系
BJ54 = 3 # 北京54坐标系
XIAN80 = 4 # 西安80坐标系
CGCS2000 = 5 # 2000
# 国家大地坐标系
XYZ = 6 # 笛卡尔坐标系
MERCATOR = 7 # 墨卡托坐标系
@unique
class DistrictLevel(Enum):
# / ** 国家 ** /
Country = "country"
# / ** 省, 自治区 ** /
Province = "province"
# / ** 地级市 ** /
City = "city"
# / ** 区, 县, 县级市 ** /
District = "district"
# / ** 街道 ** /
Street = "street"
@unique
class AdminLevel(Enum):
# / ** 海外 ** /
Oversea = "oversea"
# / ** 国家 ** /
Country = "country"
# / ** 省, 自治区 ** /
Province = "province"
# / ** 地级市 ** /
City = "city"
# / ** 省辖市(属县级市)
# see: https: // baike.baidu.com / item / 省直辖县级行政单位 ** /
ProvincialCity = "provincialcity"
# / ** 区, 县, 县级市 ** /
District = "district"
# / ** 街道 ** /
Street = "street"
class S2LatLng(object):
def __init__(self, ):
super(S2LatLng, self).__init__()
class Location(object):
def __init__(self, lng: float, lat: float):
super().__init__()
self.lng = lng
self.lat = lat
def __str__(self):
return f"Location({self.lng},{self.lat})"
class Admin(object):
def __init__(self, country: str,
province: str,
city: str,
district: str,
town: str,
level: str,
countryCode: str,
provinceCode: int,
cityCode: int,
districtCode: int,
townCode: int,
center: Location = None):
super(Admin, self).__init__()
self.country = country
self.province = province
self.city = city
self.district = district
self.town = town
self.level = level
self.countryCode = countryCode
self.provinceCode = provinceCode
self.cityCode = cityCode
self.districtCode = districtCode
self.townCode = townCode
self.center = center
def __str__(self):
return f"Admin({self.country},{self.province},{self.city},{self.district},{self.town},{self.level}" \
+ f",{self.countryCode},{self.provinceCode},{self.cityCode},{self.districtCode},{self.townCode},{self.center})"
def hasCenter(self):
return self.center != Admin.UNKNOWN_LOCATION_VAL
def hasProvince(self):
return self.province != Admin.UNKNOWN_NAME_VAL
def hasCity(self):
return self.city != Admin.UNKNOWN_NAME_VAL
def hasDistrict(self):
return self.district != Admin.UNKNOWN_NAME_VAL
def hasCityId(self):
return self.cityCode != Admin.UNKNOWN_ID_VAL
def hasDistrictId(self):
return self.districtCode != Admin.UNKNOWN_ID_VAL
def hasTown(self):
return self.town != Admin.UNKNOWN_NAME_VAL
def shortProvince(self):
return AdminUtils.shortProvince(self.province)
def shortCity(self):
return AdminUtils.shortCity(self.city)
def toShort(self):
return self.Admin(self.country,
AdminUtils.shortProvince(self.province),
AdminUtils.shortCity(self.city),
AdminUtils.shortDistrict(self.district),
AdminUtils.shortStreet(self.town),
self.level, self.countryCode, self.provinceCode,
self.cityCode, self.districtCode, self.townCode, self.center)
def toNamestr(self):
return f"$country${self.province if (self.hasProvince()) else ''} " \
+ f"{self.city if (self.hasCity()) else ''}${self.district if (self.hasDistrict()) else ''}" \
+ f"$ {self.town if (self.hasTown()) else ''}"
@staticmethod
def createOversea():
return Admin(OVERSEA_NAME_VAL,
province=OVERSEA_NAME_VAL,
city=OVERSEA_NAME_VAL,
district=OVERSEA_NAME_VAL,
town=OVERSEA_NAME_VAL,
level=AdminLevel.Oversea,
countryCode="",
provinceCode=UNKNOWN_ID_VAL,
cityCode=UNKNOWN_ID_VAL,
districtCode=UNKNOWN_ID_VAL,
townCode=UNKNOWN_ID_VAL,
center=UNKNOWN_LOCATION_VAL
)
@staticmethod
def createCountry(country: str, countryID: str, center: Location):
return Admin(
country,
province=UNKNOWN_NAME_VAL,
city=UNKNOWN_NAME_VAL,
district=UNKNOWN_NAME_VAL,
town=UNKNOWN_NAME_VAL,
level=AdminLevel.Country,
countryCode=countryID,
provinceCode=UNKNOWN_ID_VAL,
cityCode=UNKNOWN_ID_VAL,
districtCode=UNKNOWN_ID_VAL,
townCode=UNKNOWN_ID_VAL,
center=center
)
@staticmethod
def createProvince(province: str, provinceId: int, center: Location):
return Admin(
country=CHINA_NAME,
province=province,
city=UNKNOWN_NAME_VAL,
district=UNKNOWN_NAME_VAL,
town=UNKNOWN_NAME_VAL,
level=AdminLevel.Province,
countryCode=CHINA_ID,
provinceCode=provinceId,
cityCode=UNKNOWN_ID_VAL,
districtCode=UNKNOWN_ID_VAL,
townCode=UNKNOWN_ID_VAL,
center=center
)
@staticmethod
def createCity(province: str, city: str, provinceId: int, cityId: int, center: Location):
return Admin(
country=CHINA_NAME,
province=province,
city=city,
district=UNKNOWN_NAME_VAL,
town=UNKNOWN_NAME_VAL,
level=AdminLevel.City,
countryCode=CHINA_ID,
provinceCode=provinceId,
cityCode=cityId,
districtCode=UNKNOWN_ID_VAL,
townCode=UNKNOWN_ID_VAL,
center=center
)
@staticmethod
def createProvincialCity(province: str, city: str, provinceId: int, cityId: int, center: Location):
return Admin(
country=CHINA_NAME,
province=province,
city=city,
district=city,
town=UNKNOWN_NAME_VAL,
level=AdminLevel.ProvincialCity,
countryCode=CHINA_ID,
provinceCode=provinceId,
cityCode=cityId,
districtCode=cityId,
townCode=UNKNOWN_ID_VAL,
center=center
)
@staticmethod
def createDistrict(province: str, city: str, district: str,
provinceId: int, cityId: int, districtId: int, center: Location):
return Admin(
country=CHINA_NAME,
province=province,
city=city,
district=district,
town=UNKNOWN_NAME_VAL,
level=AdminLevel.District,
countryCode=CHINA_ID,
provinceCode=provinceId,
cityCode=cityId,
districtCode=districtId,
townCode=UNKNOWN_ID_VAL,
center=center
)
@staticmethod
def createStreet(province: str, city: str, district: str, town: str,
provinceId: int, cityId: int, districtId: int, streetId: int, center: Location):
return Admin(
country=CHINA_NAME,
province=province,
city=city,
district=district,
town=town,
level=AdminLevel.Street,
countryCode=CHINA_ID,
provinceCode=provinceId,
cityCode=cityId,
districtCode=districtId,
townCode=streetId,
center=center
)
class AdminNode(object):
def __init__(self, id: int,
name: str,
shortName: str,
center: Location,
level: DistrictLevel,
parentId: int,
children: list):
super().__init__()
self.id = id
self.name = name
self.shortName = shortName
self.center = center
self.parentId = parentId
self.level = level
self.children = children
def __str__(self):
"""
:return: AdminNode(430000,湖南省,湖南,Location(112.9836,28.112743),province,100000,List(430700, 431000, 430400, 431300, 430500, 433100, 430300, 431100, 430900, 430800, 430200, 430600, 430100, 431200))
"""
return f"AdminNode({self.id},{self.name},{self.shortName},{self.center},{self.level},{self.children})"
class BusinessAreaData(object):
def __init__(self, name: str, center: Location, areaCode: int):
super().__init__()
self.name = name
self.center = center
self.areaCode = areaCode
class BusinessAreaGroup(object):
# list(BusinessAreaData)
def __init__(self, cityAdCode: int, areas):
super().__init__()
self.cityAdCode = cityAdCode
self.areas = areas
class BusinessArea(object):
def __init__(self,
name: str, areaCode: int, distance: int):
super().__init__()
self.name = name
self.areaCode = areaCode
self.distance = distance
class BusinessAreaInfo(object):
def __init__(self, admin: Admin, areas): # : list(BusinessArea)
super().__init__()
self.admin = admin
self.areas = areas
# case class BusinessAreaData(name: str, center: Location, areaCode: int) extends Serializable
#
# @SerialVersionUID(-5899680396800964972L)
# case class BusinessAreaGroup(cityAdCode: int, areas: Array[BusinessAreaData]) extends Serializable
#
# case class BusinessArea(name: str, areaCode: int, distance:int)
#
# case class BusinessAreaInfo(admin: Admin, areas: Seq[BusinessArea])
if __name__ == '__main__':
print(CoordinateSystem.GCJ02 ==CoordinateSystem.GCJ02)
data_loader.py
# -*- coding: utf-8 -*-
"""
@Time : 2022/6/30 13:49
@Author: Breeze
@File : test.py
"""
from geo_obj import *
import pickle
base_dir = "base_dir"
# 请联系WX SpringBreeze1104 付费获取geo数据
import os
boundaryAdminCell = {}
with open(os.path.join(base_dir, "boundaryAdminCell.txt")) as f:
for line in f.readlines():
idx, key, col1 = line.strip().split(",")
if idx != 'idx':
boundaryAdminCell[int(key)] = int(col1)
# '3689199061258207232' -1
boundaryIndex = {} # Map[Long, List[Long]]
if os.path.exists(os.path.join(base_dir, "boundaryIndex.pkl")):
with open(os.path.join(base_dir, "boundaryIndex.pkl"), 'rb') as f:
# boundaryIndex = pickle.loads(f.read())
boundaryIndex = pickle.load(f)
else:
with open(os.path.join(base_dir, "boundaryIndex.txt")) as f:
for line in f.readlines():
idx, key, col1 = line.strip().split(",")
if idx != 'idx':
key = int(key)
if boundaryIndex.get(key) is None:
boundaryIndex[key] = [int(e) for e in col1.split("|")]
else:
data = boundaryIndex[key]
data.extend([int(e) for e in col1.split("|")])
boundaryIndex[key] = data
with open(os.path.join(base_dir, "boundaryIndex.pkl"), 'wb') as f:
pickle.dump(boundaryIndex, f)
# Map[Long, List[(Long, Int, Int)]]
boundaryData = {}
if os.path.exists(os.path.join(base_dir, "boundaryData.pkl")):
with open(os.path.join(base_dir, "boundaryData.pkl"), 'rb') as f:
# boundaryAdminCell = pickle.loads(f.read())
boundaryData = pickle.load(f)
else:
with open(os.path.join(base_dir, "boundaryData.txt")) as f:
for line in f.readlines():
idx, key, col1, col2, col3 = line.strip().split(",")
if idx != 'idx':
data = boundaryData.get(int(key))
if data is not None:
data.append((int(col1), int(col2), int(col3)))
boundaryData[int(key)] = data
else:
boundaryData[int(key)] = [(int(col1), int(col2), int(col3))]
with open(os.path.join(base_dir, "boundaryData.pkl"), 'wb') as f:
pickle.dump(boundaryData, f)
# Map[Int, AdminNode]
adminData = {}
with open(os.path.join(base_dir, "adminData.txt"), encoding='utf-8') as f:
for line in f.readlines():
idx, key, name, shortName, center_lng, center_lat, level, parentId, children = line.strip().split(",")
if idx != 'idx':
children = [int(c) for c in children.split("|") if len(c)>0]
center = Location(float(center_lng), float(center_lat))
adminData[int(key)] = AdminNode(int(key), name, shortName, center, level, int(parentId), children)
# Map[Int, AdminNode]
streetData = {}
with open(os.path.join(base_dir, "streetData.txt"), encoding='utf-8') as f:
for line in f.readlines():
idx, id, name, shortName, center_lng, center_lat, level, parentId, children = line.strip().split(",")
if idx != 'idx':
children = [int(c) for c in children.split("|") if len(c)>0]
center = Location(float(center_lng), float(center_lat))
streetData[int(id)] = AdminNode(int(id), name, shortName, center, level, int(parentId), children)
cityBusinessArea = {} # Map[Int, Array[BusinessAreaData]]
with open(os.path.join(base_dir, "cityBusinessArea.txt"), encoding='utf-8') as f:
for line in f.readlines():
idx,city_code, bussiness, center_lng,center_lat,area_code = line.strip().split(",")
if idx != 'idx':
center = Location(float(center_lng), float(center_lat))
# name: str, center: Location, areaCode: int
businessAreaDatas = cityBusinessArea.get(int(city_code))
if businessAreaDatas is not None:
businessAreaDatas.append(BusinessAreaData(bussiness,center,area_code))
cityBusinessArea[int(city_code)] = businessAreaDatas
else:
cityBusinessArea[int(city_code)] = [BusinessAreaData(bussiness,center,area_code)]
cityLevelData = {}
with open(os.path.join(base_dir, "citylevels.txt"), encoding='utf-8') as f:
for line in f.readlines():
cityname,city_code,level = line.strip().split(",")
cityLevelData[cityname] = level
cityLevelData[city_code] = level
if __name__ == '__main__':
print('init end')