天地图获取经纬度

原文地址: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官网

天地图API

点击右上角控制台选择菜单栏-应用管理,点击创建新应用

 

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

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

实现步骤:

 1)建立一个文件夹(名为gis),其中共有四个文件(tianditu.py、convers.py、input.xlsx、output_td.xlsx)

2)tianditu.py(amp_api_key = '填入在前置条件中生成的key值')

  1.  
    # @desc: 利用天地图API下载地理编码
  2.  
     
  3.  
    import requests
  4.  
    import pandas as pd
  5.  
    import os
  6.  
    import time
  7.  
     
  8.  
    # 导入excel
  9.  
    amp_api_data = pd.read_excel(r'input.xlsx')
  10.  
    # 请求地址前缀
  11.  
    req_url_pref = "http://api.tianditu.gov.cn/geocoder?"
  12.  
    amp_api_key = '填入在前置条件中生成的key值'
  13.  
    result = pd.DataFrame() # 初始化
  14.  
    count = 0
  15.  
    print("---------------------------------------------------------------")
  16.  
    def get_poi_from_amap():
  17.  
    """
  18.  
    从天地图API下载地理编码
  19.  
    """
  20.  
    global result,count
  21.  
    response = requests.get(req_url_pref, params=rep_params)
  22.  
    data = response.json() # 返回字典数据dict
  23.  
    if data['status'] == '0':
  24.  
    lng = float(data["location"]["lon"])
  25.  
    lat = float(data["location"]["lat"])
  26.  
    busi_data = [
  27.  
    {
  28.  
    "input_name": amp_api_name,
  29.  
    "input_address": amp_api_address,
  30.  
    "gcj2000_lng": lng,
  31.  
    "gcj2000_lat": lat
  32.  
    }
  33.  
    ]
  34.  
     
  35.  
    else:
  36.  
    rep_params1 = {
  37.  
    "tk": amp_api_key,
  38.  
    "ds": {
  39.  
    "{'keyWord':"+'"'+ amp_api_name +'"'+"}",
  40.  
    }
  41.  
    }
  42.  
    response1 = requests.get(req_url_pref, params=rep_params1)
  43.  
    data = response1.json()
  44.  
    if data['status'] == '0':
  45.  
    lng = float(data["location"]["lon"])
  46.  
    lat = float(data["location"]["lat"])
  47.  
    busi_data = [
  48.  
    {
  49.  
    "input_name": amp_api_name,
  50.  
    "input_address": amp_api_address,
  51.  
    "gcj2000_lng": lng,
  52.  
    "gcj2000_lat": lat
  53.  
    }
  54.  
    ]
  55.  
    else:
  56.  
    busi_data = [
  57.  
    {
  58.  
    "input_name": amp_api_name,
  59.  
    "input_address": amp_api_address,
  60.  
    "gcj2000_lng": 'Unknow',
  61.  
    "gcj2000_lat": 'Unknow'
  62.  
    }
  63.  
    ]
  64.  
    count += 1
  65.  
    print(count,":",amp_api_name,"未能在地图中找到位置")
  66.  
     
  67.  
    df = pd.DataFrame(busi_data)
  68.  
    result = pd.concat([result, df], axis=0, ignore_index=True) # 将每次i结果union在一块(列方面追加)
  69.  
     
  70.  
     
  71.  
    # 遍历地址
  72.  
    for i in range(len(amp_api_data.values)):
  73.  
    amp_api_name = amp_api_data.values[i][0]
  74.  
    amp_api_address = amp_api_data.values[i][1]
  75.  
    rep_params = {
  76.  
    'ds':
  77.  
    "{'keyWord':"+'"'+ amp_api_address +'"'+"}",
  78.  
    'tk': amp_api_key
  79.  
    }
  80.  
    get_poi_from_amap()
  81.  
    print("进度:[",i+1,"/",len(amp_api_data),"]", sep='')
  82.  
    time.sleep(3)
  83.  
     
  84.  
    # 将脚本所在路径作为excel输出路径
  85.  
    output_path = os.getcwd() + os.sep + "output_td.xlsx"
  86.  
    # 将结果写入到output_path 所在的excel中
  87.  
    result.to_excel(output_path, index=False)
  88.  
    print("---------------经纬度获取完成(来源:天地图)-------------------")
  89.  
    print("有",count,"个地址未查询到对应的经纬度")
python
 
运行

3)convers.py

  1.  
    """
  2.  
    * 经纬度偏移转换
  3.  
    """
  4.  
     
  5.  
    import math
  6.  
    PI = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280
  7.  
    x_PI = float(PI * float(3000.0) / float(180.0))
  8.  
    aa = float(6378245.0)
  9.  
    ee = 0.00669342162296594323
  10.  
     
  11.  
    def out_of_china(lng, lat):
  12.  
    # 纬度3.86~53.55,经度73.66~135.05
  13.  
    if 73.66 < lng < 135.05 and 3.86 < lat < 53.55:
  14.  
    return False
  15.  
     
  16.  
    def transform_lat(lng, lat):
  17.  
    ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))
  18.  
    ret += (20.0 * math.sin(6.0 * lng * PI) + 20.0 * math.sin(2.0 * lng * PI)) * 2.0 / 3.0
  19.  
    ret += (20.0 * math.sin(lat * PI) + 40.0 * math.sin(lat / 3.0 * PI)) * 2.0 / 3.0
  20.  
    ret += (160.0 * math.sin(lat / 12.0 * PI) + 320 * math.sin(lat * PI / 30.0)) * 2.0 / 3.0
  21.  
    return ret
  22.  
     
  23.  
     
  24.  
    def transform_lng(lng, lat):
  25.  
    ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))
  26.  
    ret += (20.0 * math.sin(6.0 * lng * PI) + 20.0 * math.sin(2.0 * lng * PI)) * 2.0 / 3.0
  27.  
    ret += (20.0 * math.sin(lng * PI) + 40.0 * math.sin(lng / 3.0 * PI)) * 2.0 / 3.0
  28.  
    ret += (150.0 * math.sin(lng / 12.0 * PI) + 300.0 * math.sin(lng / 30.0 * PI)) * 2.0 / 3.0
  29.  
    return ret
  30.  
     
  31.  
    def bd09_to_gcj02(bd_lon, bd_lat):
  32.  
    x = bd_lon - 0.0065
  33.  
    y = bd_lat - 0.006
  34.  
    z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * x_PI)
  35.  
    theta = math.atan2(y, x) - 0.000003 * math.cos(x * x_PI)
  36.  
    gg_lng = z * math.cos(theta)
  37.  
    gg_lat = z * math.sin(theta)
  38.  
    return [gg_lng, gg_lat]
  39.  
     
  40.  
    def gcj02_to_wgs84(lng, lat):
  41.  
    # 判断是否为国外坐标
  42.  
    if out_of_china(lng, lat):
  43.  
    return [lng, lat]
  44.  
    else:
  45.  
    dlat = transform_lat(lng - 105.0, lat - 35.0)
  46.  
    dlng = transform_lng(lng - 105.0, lat - 35.0)
  47.  
    radlat = lat / 180.0 * PI
  48.  
    magic = math.sin(radlat)
  49.  
    magic = 1 - ee * magic * magic
  50.  
    sqrtmagic = math.sqrt(magic)
  51.  
    dlat = (dlat * 180.0) / ((aa * (1 - ee)) / (magic * sqrtmagic) * PI)
  52.  
    dlng = (dlng * 180.0) / (aa / sqrtmagic * math.cos(radlat) * PI)
  53.  
    mglat = lat + dlat
  54.  
    mglng = lng + dlng
  55.  
    return [lng * 2 - mglng, lat * 2 - mglat]
  56.  
     
  57.  
    def bd09_to_wgs84(lng, lat):
  58.  
    point = bd09_to_gcj02(lng, lat)
  59.  
    wgs84point = gcj02_to_wgs84(point[0], point[1])
  60.  
    return [wgs84point[0], wgs84point[1]]
python
 
运行

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文件未关闭,查询到的内容无法写入

 
posted @ 2025-12-18 16:00  MaskerFan  阅读(12)  评论(0)    收藏  举报