1. 为什么要在 GEE 里接一层统一通道
Google Earth Engine 上的 Sentinel-5 Precursor 数据,是很多人做空气质量、碳排放、污染溯源分析时的第一站。TROPOMI 这台多光谱传感器从 2018 年 7 月开始持续回传数据,能记录臭氧、甲烷、甲醛、气溶胶、一氧化碳、氮氧化物、二氧化硫这几类大气成分的浓度信息,空间分辨率做到 0.01 弧度量级,还附带云特征。对做环境遥感的人来说,这套数据几乎是绕不开的。
但真正动手时会遇到一个很现实的问题:GEE 的 Python 端、命令行工具、以及你本地跑的分析脚本,各自需要一套认证和调用配置。如果你同时在用多个模型服务或数据通道,Key 散落在不同文件里,改一次要翻好几个地方。我试过把配置集中到一个统一入口,后面换环境、换机器、交接给同事,都省事很多。
这篇就围绕「Sentinel-5P 七类气体数据怎么在 GEE 里加载筛选」这件事,给你一套可复制的 TaoToken 统一 Key/API 通道配置骨架,再配上波段选择、时间过滤和结果校验的完整动作。适合已经会一点 GEE、但想把调用链路理顺的人。
2. TaoToken 前置:Key 与通道准备
TaoToken 在这里扮演的角色,是把你对模型/数据服务的调用统一到一个入口,用一个 Key 走通。你不需要在每个脚本里硬编码不同的凭证。
先到官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 了解整体能力,然后进控制台创建 API Key。控制台地址是 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite ,Key 管理页在 https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite 。API 基础地址统一用 https://taotoken.net/api ,注意这个地址不带 UTM 参数,配置里直接写它。
创建好 Key 之后,建议先确认两件事:一是这个 Key 有没有对应你需要的模型或通道权限;二是配额和速率限制是否够你跑批量影像。如果你后面要做长期的编码或 Agent 任务,可以看 Coding Plan 页面 https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite ,它更适合持续性的开发场景。
注意:Key 只存在本地配置文件或环境变量里,不要提交到 Git 仓库。GEE 脚本里也不要明文写 Key。
3. 可复制配置:settings.json 与 config.toml
下面给你两套配置骨架,按你用的工具链选一套即可。核心思路是把 base_url、api_key、默认模型/通道、超时这些抽出来,业务脚本只读配置。
3.1 settings.json(适合 Python / Node 脚本)
{ "taotoken": { "base_url": "https://taotoken.net/api", "api_key": "sk-your-key-here", "timeout_seconds": 60, "max_retries": 3, "default_channel": "general" }, "gee": { "project": "your-gee-project-id", "default_collection": "COPERNICUS/S5P/OFFL/L3_AER_AI", "default_band": "absorbing_aerosol_index" } }读取时用环境变量覆盖 api_key,避免明文:
import json, os with open("settings.json", "r", encoding="utf-8") as f: cfg = json.load(f) cfg["taotoken"]["api_key"] = os.environ.get("TAOTOKEN_API_KEY", cfg["taotoken"]["api_key"]) print(cfg["taotoken"]["base_url"])3.2 config.toml(适合命令行工具 / 服务端)
[taotoken] base_url = "https://taotoken.net/api" api_key = "sk-your-key-here" timeout_seconds = 60 max_retries = 3 default_channel = "general" [gee] project = "your-gee-project-id" default_collection = "COPERNICUS/S5P/OFFL/L3_AER_AI" default_band = "absorbing_aerosol_index"Python 读取 TOML(3.11+ 内置 tomllib):
import tomllib, os with open("config.toml", "rb") as f: cfg = tomllib.load(f) cfg["taotoken"]["api_key"] = os.environ.get("TAOTOKEN_API_KEY", cfg["taotoken"]["api_key"]) print(cfg["gee"]["default_collection"])两套配置的字段含义一致,你按项目习惯选。关键是 base_url 固定为 https://taotoken.net/api ,api_key 走环境变量注入。
4. Sentinel-5P 七类数据的加载与筛选
这一节是主体。Sentinel-5P 的数据集 ID 有 OFFI 和 NRTI 两种延迟级别,NRTI 是近实时,OFFL 是离线精处理。做长期分析优先用 OFFL,做快速响应可以用 NRTI。下面把七类气体的集合 ID 和常用波段列清楚。
| 气体/指标 | 集合 ID | 常用波段 |
|---|---|---|
| 气溶胶指数 | COPERNICUS/S5P/OFFL/L3_AER_AI | absorbing_aerosol_index |
| 云特征 | COPERNICUS/S5P/OFFL/L3_CLOUD | cloud_fraction 等 |
| 一氧化碳 | COPERNICUS/S5P/NRTI/L3_CO | CO_column_number_density |
| 甲醛 | COPERNICUS/S5P/NRTI/L3_HCHO | tropospheric_HCHO_column_number_density |
| 二氧化氮 | COPERNICUS/S5P/NRTI/L3_NO2 | tropospheric_NO2_column_number_density |
| 臭氧 | COPERNICUS/S5P/NRTI/L3_O3 | O3_column_number_density |
| 二氧化硫 | COPERNICUS/S5P/NRTI/L3_SO2 | SO2_column_number_density |
| 甲烷 | COPERNICUS/S5P/OFFL/L3_CH4 | CH4_column_volume_mixing_ratio_dry_air |
4.1 气溶胶:加载、时间过滤、可视化
先拿气溶胶做完整示例,这段可以直接贴进 GEE Code Editor 或 Python 端。
var collection = ee.ImageCollection('COPERNICUS/S5P/OFFL/L3_AER_AI') .select('absorbing_aerosol_index') .filterDate('2019-06-01', '2019-06-06'); var band_viz = { min: -1, max: 2.0, palette: ['black', 'blue', 'purple', 'cyan', 'green', 'yellow', 'red'] }; Map.addLayer(collection.mean(), band_viz, 'S5P Aerosol'); Map.setCenter(-118.82, 36.1, 5);这段做了三件事:选波段、按日期过滤、取均值后叠加到地图。filterDate的结束日期是不包含的,所以写2019-06-06实际只到 6 月 5 日,这点容易踩坑。
4.2 一氧化碳与甲烷:换集合 ID 即可
一氧化碳把集合换成COPERNICUS/S5P/NRTI/L3_CO,波段换成CO_column_number_density:
var co = ee.ImageCollection('COPERNICUS/S5P/NRTI/L3_CO') .select('CO_column_number_density') .filterDate('2020-01-01', '2020-02-01'); var co_viz = { min: 0, max: 0.05, palette: ['black', 'blue', 'green', 'yellow', 'red'] }; Map.addLayer(co.mean(), co_viz, 'S5P CO');甲烷用COPERNICUS/S5P/OFFL/L3_CH4,波段CH4_column_volume_mixing_ratio_dry_air,它的可用起始时间是 2019-02-08,比其它几类晚,筛选时注意别把空区间传进去。
4.3 臭氧、二氧化氮、二氧化硫、甲醛
这四类都在 NRTI 下,波段名分别是O3_column_number_density、tropospheric_NO2_column_number_density、SO2_column_number_density、tropospheric_HCHO_column_number_density。批量加载时可以写个循环:
import ee ee.Initialize() gases = { "O3": ("COPERNICUS/S5P/NRTI/L3_O3", "O3_column_number_density"), "NO2": ("COPERNICUS/S5P/NRTI/L3_NO2", "tropospheric_NO2_column_number_density"), "SO2": ("COPERNICUS/S5P/NRTI/L3_SO2", "SO2_column_number_density"), "HCHO": ("COPERNICUS/S5P/NRTI/L3_HCHO", "tropospheric_HCHO_column_number_density"), } for name, (cid, band) in gases.items(): col = (ee.ImageCollection(cid) .select(band) .filterDate("2021-06-01", "2021-06-10")) print(name, col.size().getInfo())col.size().getInfo()会返回区间内的影像数量,这是最直接的校验动作。如果返回 0,先检查日期区间和集合 ID 是否匹配。
4.4 云过滤:别忽略这一步
Sentinel-5P 的云特征集合COPERNICUS/S5P/OFFL/L3_CLOUD里有cloud_fraction,做浓度分析前建议先按云量过滤,否则均值会被云污染。简单做法是给主集合加一个质量掩膜,或者单独统计云量再决定是否剔除。
5. 验证请求与成功结果
配置和数据都就位后,怎么确认整条链路是通的?分两层验证。
第一层,验证 TaoToken 通道。用 curl 打一次基础请求:
curl -X POST "https://taotoken.net/api/v1/chat/completions" \ -H "Authorization: Bearer $TAOTOKEN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"your-model","messages":[{"role":"user","content":"ping"}]}'返回里有正常的 JSON 结构,说明 Key 和 base_url 没问题。如果返回 401,检查 Key;返回 404,检查路径拼接。
第二层,验证 GEE 数据读取。跑上面 4.3 的循环,看每类气体的影像数量是否大于 0。再取一景做波段统计:
img = ee.ImageCollection("COPERNICUS/S5P/OFFL/L3_AER_AI") \ .select("absorbing_aerosol_index") \ .filterDate("2019-06-01", "2019-06-06") \ .mean() stats = img.reduceRegion( reducer=ee.Reducer.minMax(), geometry=ee.Geometry.Point([-118.82, 36.1]), scale=1000, maxPixels=1e9 ) print(stats.getInfo())返回里能看到 min 和 max 两个值,说明影像加载、波段选择、区域统计都正常。这一步跑通,你的气体监测读取流程就算搭起来了。
6. 本篇常见错排查
报错一:Collection.loadTable: Collection is empty多半是日期区间写反了,或者结束日期等于起始日期。filterDate是左闭右开,结束日期要往后推一天。
报错二:Image.select: Band 'xxx' not found波段名拼错,或者集合 ID 和波段不匹配。比如把absorbing_aerosol_index用到 CO 集合上就会报这个。对照第 4 节的表格核对。
报错三:EEException: Not signed upGEE 项目没注册或没初始化。先跑ee.Authenticate()再ee.Initialize(project='your-project-id')。
报错四:TaoToken 返回 429触发了速率限制。在配置里把max_retries调大,或者降低并发。长期高频任务建议走 Coding Plan。
报错五:甲烷集合返回 0 景甲烷可用起始时间是 2019-02-08,如果你筛的是 2018 年,自然是空的。换到 2019 年之后。
排障时优先看 API Keys 页面确认 Key 状态,接入细节看接入文档 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite 。想直接验证模型通道是否正常,可以用模型对话 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=model-chat&utm_campaign=rewrite 快速试一次。
7. 把通道固定下来,后面只改业务
整套流程跑通之后,你会发现真正需要动的只有业务部分:换日期、换区域、换气体类型。TaoToken 的 base_url 和 Key 固定在配置文件里,GEE 的集合 ID 和波段名按第 4 节的表格查,验证动作就是看影像数量和波段统计。
如果你后面要接 Claude Code 或做 Anthropic 相关的编码任务,可以走 https://taotoken.net/claude-code?utm_source=taotoken_aicg_blog_end&utm_content=claude-code&utm_campaign=rewrite 这个入口,配置逻辑和上面一致,只是通道不同。长期做气体监测数据流水线的话,把 settings.json 或 config.toml 纳入版本管理(Key 走环境变量),换机器时复制配置就能继续跑,这是我实测下来最省心的做法。