利用天地图API实现批量获取地址对应的经纬度

本文详细介绍了如何在Python环境中配置VSCode,安装必要的第三方库,并利用天地图API进行地址经纬度的批量获取。步骤包括设置环境、创建应用、编写Python脚本处理数据和处理可能出现的PermissionError。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现目标:

利用天地图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值')

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

### 卫星地图数据资源下载及相关API #### 使用GitCode下载Google地图卫星图像 可以通过构建静态地图URL的方式,利用经纬度、缩放级别以及图片大小等参数来下载指定位置的卫星图像[^1]。这种方法适用于多种应用场景,例如地理研究中的植被覆盖分析、城市扩张监测,或是教育领域中的地球表面特征教学。 以下是基于Python的一个简单示例代码,展示如何通过Google Maps Static API获取卫星图像: ```python import requests def download_satellite_image(lat, lng, zoom=15, size="600x400", key="YOUR_API_KEY"): base_url = "https://maps.googleapis.com/maps/api/staticmap" params = { 'center': f"{lat},{lng}", 'zoom': zoom, 'size': size, 'maptype': 'satellite', 'key': key } response = requests.get(base_url, params=params) if response.status_code == 200: with open(f"satellite_{lat}_{lng}.png", "wb") as file: file.write(response.content) # 调用函数下载卫星图像 download_satellite_image(39.9042, 116.4074, zoom=18) # 北京市坐标为例 ``` 上述代码中,`YOUR_API_KEY`需替换为有效的Google Maps API密钥。 #### Google离线地图资源下载 如果需要更灵活地访问离线地图资源,可以参考开源项目 `open-source-toolkit/3c67c` 提供的功能[^2]。该项目允许用户直接在本地加载和查看已下载的Google地图资源,无需网络连接即可浏览卫星图像和其他地理信息。 #### C++多线程卫星影像Tile下载器 对于更高性能的需求,可以选择使用C++编写的地图下载器工具[^3]。它支持多线程并发处理,并能够从多个数据源(如ArcGIS、天地图、谷歌、高德、百度等)下载瓦片数据。此外,还具备将大量小图拼接成大图的能力,适合大规模地理数据分析任务。 #### Planet遥感数据平台 Planet公司提供了鸽群卫星拍摄的全球范围内的高清遥感影像服务[^4]。虽然其免费额度有限制(每月仅限于5000平方公里),但对于科研用途来说已经足够强大。开发者可通过官方文档了解具体API调用方法及其功能特性。 #### 百度地图API自动计量数据 在国内市场环境下,也可以考虑采用百度地图开放平台所提供的Web服务接口完成类似工作流程[^5]。下面是一个简单的例子说明怎样批量查询地址对应的位置信息: ```python from baidu_map_api import BaiduMapApi bm_api = BaiduMapApi('your_ak_here') address_list = ['清华大学', '北京大学'] result_df = bm_api.geocoding(address_list) print(result_df[['name', 'latitude', 'longitude']]) ``` 注意这里假设存在名为`baidu_map_api.py`封装好的类库文件以便简化操作过程。 ---
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值