天地图获取经纬度
原文地址:https://blog.csdn.net/hongyinvjianke/article/details/136674474
实现目标:
利用天地图API实现批量获取地址对应的经纬度
前置条件:
1.python的环境搭建
python官网:https://www.python.org/downloads/

点击Python 3.11.8

下载Windows installer (64-bit)
下载好后直接点击运行安装
注意事项:
1)选择自定义安装
2)勾选add python to path
3)勾选install pip
2.VScode安装
3.第三方库下载
在vscode终端中输入
pip install requests
pip install pandas
pip install openpyxl
4.进入天地图地图API官网
点击右上角控制台
选择菜单栏-应用管理,点击创建新应用

提交后,列表中生成key在后面代码中会用到

可以在菜单栏-服务调用配额说明中,查看到地理编码的调用量每天有7000次,注意该使用限度

实现步骤:
1)建立一个文件夹(名为gis),其中共有四个文件(tianditu.py、convers.py、input.xlsx、output_td.xlsx)
2)tianditu.py(amp_api_key = '填入在前置条件中生成的key值')
-
# @desc: 利用天地图API下载地理编码
-
-
import requests
-
import pandas as pd
-
import os
-
import time
-
-
# 导入excel
-
amp_api_data = pd.read_excel(r'input.xlsx')
-
# 请求地址前缀
-
req_url_pref = "http://api.tianditu.gov.cn/geocoder?"
-
amp_api_key = '填入在前置条件中生成的key值'
-
result = pd.DataFrame() # 初始化
-
count = 0
-
print("---------------------------------------------------------------")
-
def get_poi_from_amap():
-
"""
-
从天地图API下载地理编码
-
"""
-
global result,count
-
response = requests.get(req_url_pref, params=rep_params)
-
data = response.json() # 返回字典数据dict
-
if data['status'] == '0':
-
lng = float(data["location"]["lon"])
-
lat = float(data["location"]["lat"])
-
busi_data = [
-
{
-
"input_name": amp_api_name,
-
"input_address": amp_api_address,
-
"gcj2000_lng": lng,
-
"gcj2000_lat": lat
-
}
-
]
-
-
else:
-
rep_params1 = {
-
"tk": amp_api_key,
-
"ds": {
-
"{'keyWord':"+'"'+ amp_api_name +'"'+"}",
-
}
-
}
-
response1 = requests.get(req_url_pref, params=rep_params1)
-
data = response1.json()
-
if data['status'] == '0':
-
lng = float(data["location"]["lon"])
-
lat = float(data["location"]["lat"])
-
busi_data = [
-
{
-
"input_name": amp_api_name,
-
"input_address": amp_api_address,
-
"gcj2000_lng": lng,
-
"gcj2000_lat": lat
-
}
-
]
-
else:
-
busi_data = [
-
{
-
"input_name": amp_api_name,
-
"input_address": amp_api_address,
-
"gcj2000_lng": 'Unknow',
-
"gcj2000_lat": 'Unknow'
-
}
-
]
-
count += 1
-
print(count,":",amp_api_name,"未能在地图中找到位置")
-
-
df = pd.DataFrame(busi_data)
-
result = pd.concat([result, df], axis=0, ignore_index=True) # 将每次i结果union在一块(列方面追加)
-
-
-
# 遍历地址
-
for i in range(len(amp_api_data.values)):
-
amp_api_name = amp_api_data.values[i][0]
-
amp_api_address = amp_api_data.values[i][1]
-
rep_params = {
-
'ds':
-
"{'keyWord':"+'"'+ amp_api_address +'"'+"}",
-
'tk': amp_api_key
-
}
-
get_poi_from_amap()
-
print("进度:[",i+1,"/",len(amp_api_data),"]", sep='')
-
time.sleep(3)
-
-
# 将脚本所在路径作为excel输出路径
-
output_path = os.getcwd() + os.sep + "output_td.xlsx"
-
# 将结果写入到output_path 所在的excel中
-
result.to_excel(output_path, index=False)
-
print("---------------经纬度获取完成(来源:天地图)-------------------")
-
print("有",count,"个地址未查询到对应的经纬度")
3)convers.py
-
"""
-
* 经纬度偏移转换
-
"""
-
-
import math
-
PI = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280
-
x_PI = float(PI * float(3000.0) / float(180.0))
-
aa = float(6378245.0)
-
ee = 0.00669342162296594323
-
-
def out_of_china(lng, lat):
-
# 纬度3.86~53.55,经度73.66~135.05
-
if 73.66 < lng < 135.05 and 3.86 < lat < 53.55:
-
return False
-
-
def transform_lat(lng, lat):
-
ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
-
ret += (20.0 * math.sin(6.0 * lng * PI) + 20.0 * math.sin(2.0 * lng * PI)) * 2.0 / 3.0
-
ret += (20.0 * math.sin(lat * PI) + 40.0 * math.sin(lat / 3.0 * PI)) * 2.0 / 3.0
-
ret += (160.0 * math.sin(lat / 12.0 * PI) + 320 * math.sin(lat * PI / 30.0)) * 2.0 / 3.0
-
return ret
-
-
-
def transform_lng(lng, lat):
-
ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
-
ret += (20.0 * math.sin(6.0 * lng * PI) + 20.0 * math.sin(2.0 * lng * PI)) * 2.0 / 3.0
-
ret += (20.0 * math.sin(lng * PI) + 40.0 * math.sin(lng / 3.0 * PI)) * 2.0 / 3.0
-
ret += (150.0 * math.sin(lng / 12.0 * PI) + 300.0 * math.sin(lng / 30.0 * PI)) * 2.0 / 3.0
-
return ret
-
-
def bd09_to_gcj02(bd_lon, bd_lat):
-
x = bd_lon - 0.0065
-
y = bd_lat - 0.006
-
z = 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]
-
-
def gcj02_to_wgs84(lng, lat):
-
# 判断是否为国外坐标
-
if out_of_china(lng, lat):
-
return [lng, lat]
-
else:
-
dlat = transform_lat(lng - 105.0, lat - 35.0)
-
dlng = transform_lng(lng - 105.0, lat - 35.0)
-
radlat = lat / 180.0 * PI
-
magic = math.sin(radlat)
-
magic = 1 - ee * magic * magic
-
sqrtmagic = math.sqrt(magic)
-
dlat = (dlat * 180.0) / ((aa * (1 - ee)) / (magic * sqrtmagic) * PI)
-
dlng = (dlng * 180.0) / (aa / sqrtmagic * math.cos(radlat) * PI)
-
mglat = lat + dlat
-
mglng = lng + dlng
-
return [lng * 2 - mglng, lat * 2 - mglat]
-
-
def bd09_to_wgs84(lng, lat):
-
point = bd09_to_gcj02(lng, lat)
-
wgs84point = gcj02_to_wgs84(point[0], point[1])
-
return [wgs84point[0], wgs84point[1]]
4)input.xlsx(填入待查询的地址)
name:地点名称
address:地址
5)output_td.xlsx(py文件运行后会将查询到的经纬度写到该文件内)
input_name:输入的地点名称
input_address:输入的地址
output_name:查询结果的地点名称
output_address:查询结果的地址
gcj2000_lng:查询结果的经度(较为准确)
gcj2000_lat:查询结果的纬度(较为准确)

6)所有文件准备好后,右击运行tianditu.py

7)可以在终端看到查询进度

问题汇总:
1)PermissionError: [Errno 13] Permission denied: 'E:\\gis\\output_td.xlsx'
说明output_td.xlsx文件未关闭,查询到的内容无法写入

浙公网安备 33010602011771号