測(cè)數(shù)據(jù)配置與驗(yàn)證)
1. 為什么要在 GEE 里接一層統(tǒng)一通道Google Earth Engine 上的 Sentinel-5 Precursor 數(shù)據(jù)是很多人做空氣質(zhì)量、碳排放、污染溯源分析時(shí)的第一站。TROPOMI 這臺(tái)多光譜傳感器從 2018 年 7 月開(kāi)始持續(xù)回傳數(shù)據(jù)能記錄臭氧、甲烷、甲醛、氣溶膠、一氧化碳、氮氧化物、二氧化硫這幾類大氣成分的濃度信息空間分辨率做到 0.01 弧度量級(jí)還附帶云特征。對(duì)做環(huán)境遙感的人來(lái)說(shuō)這套數(shù)據(jù)幾乎是繞不開(kāi)的。但真正動(dòng)手時(shí)會(huì)遇到一個(gè)很現(xiàn)實(shí)的問(wèn)題GEE 的 Python 端、命令行工具、以及你本地跑的分析腳本各自需要一套認(rèn)證和調(diào)用配置。如果你同時(shí)在用多個(gè)模型服務(wù)或數(shù)據(jù)通道Key 散落在不同文件里改一次要翻好幾個(gè)地方。我試過(guò)把配置集中到一個(gè)統(tǒng)一入口后面換環(huán)境、換機(jī)器、交接給同事都省事很多。這篇就圍繞「Sentinel-5P 七類氣體數(shù)據(jù)怎么在 GEE 里加載篩選」這件事給你一套可復(fù)制的 TaoToken 統(tǒng)一 Key/API 通道配置骨架再配上波段選擇、時(shí)間過(guò)濾和結(jié)果校驗(yàn)的完整動(dòng)作。適合已經(jīng)會(huì)一點(diǎn) GEE、但想把調(diào)用鏈路理順的人。2. TaoToken 前置Key 與通道準(zhǔn)備TaoToken 在這里扮演的角色是把你對(duì)模型/數(shù)據(jù)服務(wù)的調(diào)用統(tǒng)一到一個(gè)入口用一個(gè) Key 走通。你不需要在每個(gè)腳本里硬編碼不同的憑證。先到官網(wǎng) https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 了解整體能力然后進(jìn)控制臺(tái)創(chuàng)建 API Key。控制臺(tái)地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 管理頁(yè)在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。API 基礎(chǔ)地址統(tǒng)一用 https://taotoken.net/api 注意這個(gè)地址不帶 UTM 參數(shù)配置里直接寫(xiě)它。創(chuàng)建好 Key 之后建議先確認(rèn)兩件事一是這個(gè) Key 有沒(méi)有對(duì)應(yīng)你需要的模型或通道權(quán)限二是配額和速率限制是否夠你跑批量影像。如果你后面要做長(zhǎng)期的編碼或 Agent 任務(wù)可以看 Coding Plan 頁(yè)面 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 它更適合持續(xù)性的開(kāi)發(fā)場(chǎng)景。注意Key 只存在本地配置文件或環(huán)境變量里不要提交到 Git 倉(cāng)庫(kù)。GEE 腳本里也不要明文寫(xiě) Key。3. 可復(fù)制配置settings.json 與 config.toml下面給你兩套配置骨架按你用的工具鏈選一套即可。核心思路是把 base_url、api_key、默認(rèn)模型/通道、超時(shí)這些抽出來(lái)業(yè)務(wù)腳本只讀配置。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 } }讀取時(shí)用環(huán)境變量覆蓋 api_key避免明文import json, os with open(settings.json, r, encodingutf-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適合命令行工具 / 服務(wù)端[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_indexPython 讀取 TOML3.11 內(nèi)置 tomllibimport 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])兩套配置的字段含義一致你按項(xiàng)目習(xí)慣選。關(guān)鍵是 base_url 固定為 https://taotoken.net/api api_key 走環(huán)境變量注入。4. Sentinel-5P 七類數(shù)據(jù)的加載與篩選這一節(jié)是主體。Sentinel-5P 的數(shù)據(jù)集 ID 有 OFFI 和 NRTI 兩種延遲級(jí)別NRTI 是近實(shí)時(shí)OFFL 是離線精處理。做長(zhǎng)期分析優(yōu)先用 OFFL做快速響應(yīng)可以用 NRTI。下面把七類氣體的集合 ID 和常用波段列清楚。氣體/指標(biāo)集合 ID常用波段氣溶膠指數(shù)COPERNICUS/S5P/OFFL/L3_AER_AIabsorbing_aerosol_index云特征COPERNICUS/S5P/OFFL/L3_CLOUDcloud_fraction 等一氧化碳COPERNICUS/S5P/NRTI/L3_COCO_column_number_density甲醛COPERNICUS/S5P/NRTI/L3_HCHOtropospheric_HCHO_column_number_density二氧化氮COPERNICUS/S5P/NRTI/L3_NO2tropospheric_NO2_column_number_density臭氧COPERNICUS/S5P/NRTI/L3_O3O3_column_number_density二氧化硫COPERNICUS/S5P/NRTI/L3_SO2SO2_column_number_density甲烷COPERNICUS/S5P/OFFL/L3_CH4CH4_column_volume_mixing_ratio_dry_air4.1 氣溶膠加載、時(shí)間過(guò)濾、可視化先拿氣溶膠做完整示例這段可以直接貼進(jìn) 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);這段做了三件事選波段、按日期過(guò)濾、取均值后疊加到地圖。filterDate的結(jié)束日期是不包含的所以寫(xiě)2019-06-06實(shí)際只到 6 月 5 日這點(diǎn)容易踩坑。4.2 一氧化碳與甲烷換集合 ID 即可一氧化碳把集合換成COPERNICUS/S5P/NRTI/L3_CO波段換成CO_column_number_densityvar 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它的可用起始時(shí)間是 2019-02-08比其它幾類晚篩選時(shí)注意別把空區(qū)間傳進(jìn)去。4.3 臭氧、二氧化氮、二氧化硫、甲醛這四類都在 NRTI 下波段名分別是O3_column_number_density、tropospheric_NO2_column_number_density、SO2_column_number_density、tropospheric_HCHO_column_number_density。批量加載時(shí)可以寫(xiě)個(gè)循環(huán)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()會(huì)返回區(qū)間內(nèi)的影像數(shù)量這是最直接的校驗(yàn)動(dòng)作。如果返回 0先檢查日期區(qū)間和集合 ID 是否匹配。4.4 云過(guò)濾別忽略這一步Sentinel-5P 的云特征集合COPERNICUS/S5P/OFFL/L3_CLOUD里有cloud_fraction做濃度分析前建議先按云量過(guò)濾否則均值會(huì)被云污染。簡(jiǎn)單做法是給主集合加一個(gè)質(zhì)量掩膜或者單獨(dú)統(tǒng)計(jì)云量再?zèng)Q定是否剔除。5. 驗(yàn)證請(qǐng)求與成功結(jié)果配置和數(shù)據(jù)都就位后怎么確認(rèn)整條鏈路是通的分兩層驗(yàn)證。第一層驗(yàn)證 TaoToken 通道。用 curl 打一次基礎(chǔ)請(qǐng)求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 結(jié)構(gòu)說(shuō)明 Key 和 base_url 沒(méi)問(wèn)題。如果返回 401檢查 Key返回 404檢查路徑拼接。第二層驗(yàn)證 GEE 數(shù)據(jù)讀取。跑上面 4.3 的循環(huán)看每類氣體的影像數(shù)量是否大于 0。再取一景做波段統(tǒng)計(jì)img ee.ImageCollection(COPERNICUS/S5P/OFFL/L3_AER_AI) \ .select(absorbing_aerosol_index) \ .filterDate(2019-06-01, 2019-06-06) \ .mean() stats img.reduceRegion( reduceree.Reducer.minMax(), geometryee.Geometry.Point([-118.82, 36.1]), scale1000, maxPixels1e9 ) print(stats.getInfo())返回里能看到 min 和 max 兩個(gè)值說(shuō)明影像加載、波段選擇、區(qū)域統(tǒng)計(jì)都正常。這一步跑通你的氣體監(jiān)測(cè)讀取流程就算搭起來(lái)了。6. 本篇常見(jiàn)錯(cuò)排查報(bào)錯(cuò)一Collection.loadTable: Collection is empty多半是日期區(qū)間寫(xiě)反了或者結(jié)束日期等于起始日期。filterDate是左閉右開(kāi)結(jié)束日期要往后推一天。報(bào)錯(cuò)二Image.select: Band xxx not found波段名拼錯(cuò)或者集合 ID 和波段不匹配。比如把a(bǔ)bsorbing_aerosol_index用到 CO 集合上就會(huì)報(bào)這個(gè)。對(duì)照第 4 節(jié)的表格核對(duì)。報(bào)錯(cuò)三EEException: Not signed upGEE 項(xiàng)目沒(méi)注冊(cè)或沒(méi)初始化。先跑ee.Authenticate()再ee.Initialize(projectyour-project-id)。報(bào)錯(cuò)四TaoToken 返回 429觸發(fā)了速率限制。在配置里把max_retries調(diào)大或者降低并發(fā)。長(zhǎng)期高頻任務(wù)建議走 Coding Plan。報(bào)錯(cuò)五甲烷集合返回 0 景甲烷可用起始時(shí)間是 2019-02-08如果你篩的是 2018 年自然是空的。換到 2019 年之后。排障時(shí)優(yōu)先看 API Keys 頁(yè)面確認(rèn) Key 狀態(tài)接入細(xì)節(jié)看接入文檔 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。想直接驗(yàn)證模型通道是否正??梢杂媚P蛯?duì)話 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 快速試一次。7. 把通道固定下來(lái)后面只改業(yè)務(wù)整套流程跑通之后你會(huì)發(fā)現(xiàn)真正需要?jiǎng)拥闹挥袠I(yè)務(wù)部分換日期、換區(qū)域、換氣體類型。TaoToken 的 base_url 和 Key 固定在配置文件里GEE 的集合 ID 和波段名按第 4 節(jié)的表格查驗(yàn)證動(dòng)作就是看影像數(shù)量和波段統(tǒng)計(jì)。如果你后面要接 Claude Code 或做 Anthropic 相關(guān)的編碼任務(wù)可以走 https://taotoken.net/claude-code?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-codeutm_campaignrewrite 這個(gè)入口配置邏輯和上面一致只是通道不同。長(zhǎng)期做氣體監(jiān)測(cè)數(shù)據(jù)流水線的話把 settings.json 或 config.toml 納入版本管理Key 走環(huán)境變量換機(jī)器時(shí)復(fù)制配置就能繼續(xù)跑這是我實(shí)測(cè)下來(lái)最省心的做法。