
本文介绍如何使用嵌套循环或列表推导式生成两个数值范围的所有唯一坐标对,并将其高效应用于 http 请求循环中,实现批量下载图片资源(如 nearmap 瓦片),同时包含错误处理、文件命名规范与安全实践建议。
本文介绍如何使用嵌套循环或列表推导式生成两个数值范围的所有唯一坐标对,并将其高效应用于 http 请求循环中,实现批量下载图片资源(如 nearmap 瓦片),同时包含错误处理、文件命名规范与安全实践建议。
在地理空间数据批量获取场景中(例如下载栅格瓦片),常需遍历二维坐标网格(如 x, y 瓦片索引)。核心挑战在于:如何将两个独立范围(如 range(634797, 634876) 和 range(776458, 776512))组合为所有可能的 (x, y) 坐标对,并逐对代入请求逻辑?
最简洁、Pythonic 的方式是使用列表推导式生成笛卡尔积,而非手动嵌套 for 循环追加元组:
range1 = range(634797, 634876)
range2 = range(776458, 776512)
# ✅ 推荐:一行生成所有 (x, y) 对
combinations = [(x, y) for x in range1 for y in range2]
print(f"共生成 {len(combinations)} 个唯一坐标对")
生成坐标对后,直接在 for 循环中解包元组(for myVal1, myVal2 in combinations:),即可自然绑定变量,无缝接入原有请求逻辑。
以下是完整、健壮的批量下载实现:
import requests
import os
# 配置参数(建议提取为常量)
SURVEY_ID = "6e33c960-4310-11ee-90f9-b3c1b4806389"
ZOOM_LEVEL = "21"
API_KEY = "YOUR_API_KEY_HERE" # ⚠️ 生产环境请使用环境变量或密钥管理服务
OUTPUT_DIR = "/arcgis/home/nearmap"
# 创建输出目录(避免 FileNotFoundError)
os.makedirs(OUTPUT_DIR, exist_ok=True)
# 定义坐标范围
x_range = range(634797, 634876) # 横向索引
y_range = range(776458, 776512) # 纵向索引
# 生成所有 (x, y) 组合(笛卡尔积)
tile_pairs = [(x, y) for x in x_range for y in y_range]
print(f"准备下载 {len(tile_pairs)} 个瓦片...")
# 批量请求与保存
for x, y in tile_pairs:
url = f"https://api.nearmap.com/tiles/v3/surveys/{SURVEY_ID}/North/{ZOOM_LEVEL}/{x}/{y}.jpg?apikey={API_KEY}"
headers = {"accept": "image/*"}
try:
response = requests.get(url, headers=headers, timeout=30)
if response.status_code == 200:
file_path = os.path.join(OUTPUT_DIR, f"{x}_{y}.jpg")
with open(file_path, 'wb') as f:
f.write(response.content)
print(f"✓ 成功下载: {file_path}")
else:
print(f"✗ 请求失败 [{response.status_code}]: {x}, {y}")
except requests.exceptions.RequestException as e:
print(f"⚠️ 网络异常 {x}, {y}: {e}")
except OSError as e:
print(f"⚠️ 文件写入失败 {x}, {y}: {e}")
关键优化与注意事项:
-
安全性:切勿硬编码 API 密钥。生产环境应通过
os.getenv("NEARMAP_API_KEY")读取环境变量。 -
鲁棒性:添加
try/except捕获网络超时、连接中断等异常;使用timeout=30防止长期阻塞。 -
可维护性:将 URL 路径片段(如
SURVEY_ID,ZOOM_LEVEL)定义为常量,便于复用与修改。 -
文件系统安全:使用
os.path.join()构建路径,兼容不同操作系统;os.makedirs(..., exist_ok=True)确保目录存在。 -
命名规范:用下划线
_分隔x_y(而非拼接str(x)+str(y)),避免坐标混淆(如12_3vs1_23)。 -
性能提示:若瓦片数量极大(>10k),可考虑添加
time.sleep(0.1)限流,或改用concurrent.futures.ThreadPoolExecutor并行下载(需注意 API 速率限制)。
通过此模式,你可轻松扩展至多维参数组合(如 x, y, z, layer),只需调整列表推导式结构即可。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











