You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python脚本遍历地址表调用Google API地理编码并写入经纬度至对应行

看起来你卡在了遍历数据表并更新行的环节上——这其实是ArcPy游标使用的典型场景,我来帮你把代码补全并解释清楚:

完整可运行代码

import urllib.request
import urllib.parse
import json
import time
import arcpy

# 设置工作空间和数据表路径
arcpy.env.workspace = "D:/GIS/"
table_path = "addr.dbf"

# 替换为你的Google API密钥
GOOGLE_API_KEY = "YOUR_GOOGLE_API_KEY"

def geocode_address(address):
    """调用Google地理编码API,返回(纬度, 经度),失败则返回(None, None)"""
    if not address:
        print("空地址,跳过")
        return (None, None)
    
    base_url = "https://maps.googleapis.com/maps/api/geocode/json?"
    # 编码地址参数,避免特殊字符导致请求失败
    encoded_address = urllib.parse.quote(address)
    params = f"address={encoded_address}&key={GOOGLE_API_KEY}"
    full_url = base_url + params
    
    try:
        response = urllib.request.urlopen(full_url)
        data = json.load(response)
        
        if data['status'] == 'OK':
            location = data['results'][0]['geometry']['location']
            return (location['lat'], location['lng'])
        else:
            print(f"地址「{address}」编码失败,状态: {data['status']}")
            return (None, None)
    except Exception as e:
        print(f"请求地址「{address}」时出错: {str(e)}")
        return (None, None)

# 自动检查并创建经纬度存储字段(如果不存在)
field_names = [f.name.upper() for f in arcpy.ListFields(table_path)]
if 'LAT' not in field_names:
    arcpy.AddField_management(table_path, "LAT", "DOUBLE")
if 'LON' not in field_names:
    arcpy.AddField_management(table_path, "LON", "DOUBLE")

# 替换为你数据表中存储地址的字段名(比如"FULL_ADDR")
address_field = "ADDRESS"

# 使用UpdateCursor遍历每行并更新经纬度
with arcpy.da.UpdateCursor(table_path, [address_field, "LAT", "LON"]) as cursor:
    for row in cursor:
        current_address = row[0]
        # 调用地理编码函数获取坐标
        lat, lon = geocode_address(current_address)
        # 更新当前行的经纬度值
        row[1] = lat
        row[2] = lon
        # 提交更新到数据表
        cursor.updateRow(row)
        # 加入延迟,避免触发Google API请求频率限制
        time.sleep(0.2)

print("所有地址的经纬度更新完成!")

关键细节解释

  • 高效游标使用:用arcpy.da.UpdateCursor(数据访问模块的游标)替代旧版游标,它不仅速度更快,还支持直接修改行数据,配合with语句能自动管理资源,不用手动关闭游标。
  • 字段自动处理:先检查表中是否有LATLON字段,没有则自动创建,避免因缺少字段报错。
  • 地址编码处理:用urllib.parse.quote处理地址中的特殊字符(比如空格、中文、逗号),确保API请求的格式合法。
  • 错误捕获机制:加入try-except块捕获网络请求异常,同时处理API返回的错误状态(比如ZERO_RESULTSOVER_QUERY_LIMIT),方便你排查问题。
  • 请求频率控制:Google地理编码API免费版有每秒5次的请求限制,加入time.sleep(0.2)控制请求间隔,避免被临时封禁。

注意事项

  1. 一定要把YOUR_GOOGLE_API_KEY替换成你自己的有效密钥,并且确保已经在Google Cloud控制台启用了地理编码API
  2. address_field替换成你数据表中实际存储地址的字段名(比如"STREET_ADDR""FULL_ADDRESS")。如果你的地址分散在多个字段(比如街道、城市、邮编),可以拼接后传入函数:current_address = f"{row[0]}, {row[1]}, {row[2]}"
  3. 如果你的地址数量很大(比如超过1000条),建议考虑使用Google的批量地理编码服务,或者升级到付费版API,避免触发请求限制。

内容的提问来源于stack exchange,提问作者evand

火山引擎 最新活动