GEE云端高效提取ERA5气象数据至矢量要素实战指南

📅 2026/7/31 10:57:39
GEE云端高效提取ERA5气象数据至矢量要素实战指南
1. 项目缘起为什么要在GEE里折腾ERA5数据如果你和我一样经常需要处理大范围、长时间序列的气象数据比如研究区域气候变化、做水文模型驱动、或者分析农业气象条件那你肯定对ERA5不陌生。作为欧洲中期天气预报中心ECMWF的第五代全球大气再分析数据集ERA5提供了从1979年至今、小时级的高精度气象变量温度、降水、风速、辐射……要啥有啥数据质量没得说。但问题来了ERA5数据量太大了。直接从Copernicus Climate Data StoreCDS下载全球或区域的数据动辄几十个GB对网络和本地存储都是考验。更头疼的是我们往往只需要特定地点比如气象站点、城市中心点或者特定区域比如一个流域、一个行政区划的数据。为了几个点的数据去下载整个全球格网就像为了喝一杯牛奶去买下一头牛效率太低。这时候Google Earth Engine (GEE) 的优势就凸显出来了。GEE云端存储了海量的地理空间数据集其中就包括ERA5-Land陆地再分析和ERA5大气再分析。我们不需要下载原始数据只需要在GEE的云端计算环境中编写几行JavaScript或Python代码就能像“点菜”一样精确地从庞大的数据集中提取出我们需要的点或面要素上的时间序列然后直接导出为SHP或CSV这种轻量级、易处理的格式。整个过程在云端完成本地只接收最终的结果文件省时省力省流量。我最近的一个项目需要获取中国300多个城市过去20年的逐月平均气温和降水量。如果传统方法光是数据下载和预处理就得折腾好几天。而在GEE里从写代码到下载完CSV文件总共用了不到一小时。这就是为什么我认为掌握在GEE中提取ERA5数据至矢量要素并导出的技能是现代地理、生态、环境等领域研究者和工程师的必备效率工具。2. 核心工具与数据基础GEE平台与ERA5数据集辨析在动手之前我们必须把“厨房”和“食材”搞清楚。这一步没理清后面代码跑起来全是坑。2.1 Google Earth Engine (GEE)你的云端地理计算引擎GEE不是一个简单的数据下载器而是一个强大的地理空间数据处理云平台。它的核心价值在于数据湖集成了PB级的多源遥感与地理数据集Landsat, Sentinel, MODIS, 气象数据等并保持更新。计算引擎提供JavaScript和Python API让你可以用代码对全球尺度的数据进行处理、分析所有计算在Google的服务器上完成。结果导出可以将处理后的结果图像、统计值、表格导出到Google Drive、Google Cloud Storage或直接下载。对于我们的任务GEE扮演的角色是数据存取接口 空间查询与统计计算器 格式转换与导出工具。注意使用GEE需要申请账号学术用途通常免费并可能需等待审核。在代码编辑器中初次运行某些函数时也可能需要授权访问你的Google Drive用于存放导出结果。2.2 ERA5与ERA5-Land选对“食材”是关键在GEE的代码编辑器中搜索“ERA5”你会找到好几个数据集。最容易混淆的是ECMWF/ERA5_LAND/HOURLY和ECMWF/ERA5/DAILY。它们有什么区别该用哪个特性ERA5 (大气再分析)ERA5-Land (陆地再分析)空间分辨率约31公里 (0.25度)约9公里 (0.1度)时间范围1979年至今1950年至今 (GEE中通常从1981开始)时间频率小时级小时级覆盖范围全球大气全球陆地表面不包括开阔海洋核心变量大气各层温度、气压、风、湿度、降水量等更注重地表2米气温、2米露点温度、地表温度、10米风、地表太阳辐射、降水总量等GEE中常用数据集IDECMWF/ERA5/DAILY(日聚合数据)ECMWF/ERA5/MONTHLY(月聚合数据)ECMWF/ERA5_LAND/HOURLYECMWF/ERA5_LAND/MONTHLY适用场景需要高层大气变量如500hPa位势高度、海洋上空数据的研究。绝大多数陆地生态、水文、农业研究。需要更高空间分辨率的地表气象要素。如何选择如果你的研究区域在陆地上且关注近地表气象要素如气温、降水、辐射优先选择ERA5-Land。它的更高分辨率能更好地捕捉地形和地表覆盖的影响结果更精细。如果你需要研究大气环流或者区域包含大片海洋则选择ERA5。对于日尺度或月尺度的分析直接使用DAILY或MONTHLY聚合产品会更方便计算效率也更高。HOURLY数据则用于更精细的日内变化分析。以提取日降水量为例在ERA5-Land中小时数据集的变量名是total_precipitation_hourly。你需要知道这个值的单位是米。1米降水量等于1000毫米。所以如果你想要毫米为单位的日降水量代码中可能需要乘以1000并根据数据集是小时还是日聚合数据进行累加。这是第一个容易踩的坑单位换算。3. 从理论到代码提取气象数据至点/面要素的核心逻辑理解了数据和平台我们来看核心操作。无论提取到点还是面其逻辑流程是相通的可以概括为以下几步定义时空范围告诉GEE你要哪一段时间、什么区域的数据。加载数据根据上一步的选择加载对应的ERA5数据集影像集合ImageCollection。定义目标要素创建或导入你的点Point或面Polygon要素集合FeatureCollection。空间关联与信息提取将气象数据与你的要素进行空间关联并执行提取操作。格式化与导出将提取的结果整理成表格并导出为CSV或SHP。下面我用一个最经典的场景——提取多个气象站点过去5年的日均2米气温——来手把手拆解代码。假设我们有三个站点的经纬度坐标。3.1 准备阶段定义范围与加载数据// 1. 定义时间范围 var startDate ee.Date(2019-01-01); var endDate ee.Date(2024-01-01); // 2. 定义区域可以是全局也可以画个几何区域限制计算范围提升效率 var region ee.Geometry.Rectangle([70, 15, 140, 55]); // 示例中国大致范围 // 3. 加载ERA5-Land日数据 var era5LandDaily ee.ImageCollection(ECMWF/ERA5_LAND/DAILY) .filterDate(startDate, endDate) .filterBounds(region) // 可选用于初步筛选 .select(temperature_2m); // 选择我们需要的变量2米气温单位是开尔文(K)这里有几个关键点ee.Date用于构造GEE中的日期对象。filterDate和filterBounds是筛选影像集合最常用的方法能大幅减少后续处理的数据量。select(temperature_2m)很重要。ERA5数据集包含很多波段变量只选择需要的可以节省内存和计算时间。你需要去GEE的数据集页面查看具体的变量名。3.2 创建目标点要素集合假设我们有北京、上海、广州三个站点的信息我们可以手动创建// 4. 创建点要素集合 (FeatureCollection) var stations ee.FeatureCollection([ ee.Feature(ee.Geometry.Point([116.4074, 39.9042]), {name: Beijing}), ee.Feature(ee.Geometry.Point([121.4737, 31.2304]), {name: Shanghai}), ee.Feature(ee.Geometry.Point([113.2644, 23.1291]), {name: Guangzhou}) ]); // 也可以从已有的Google Fusion Table、Assets中的SHP文件导入更适用于大量站点。 // var stations ee.FeatureCollection(projects/your-project/assets/your_stations_shp);每个ee.Feature包含一个几何图形ee.Geometry.Point和属性{name: ...}。属性可以任意添加比如站点ID、海拔等这些属性会保留到最终输出的表格中。3.3 核心提取将时间序列数据“缩减”到点上这是最关键的一步。我们需要对era5LandDaily这个包含多张日影像的集合在每一个station点上进行时间序列的提取。GEE提供了ee.ImageCollection.reduceRegions函数但它对大量点和长时间序列处理时容易超时或出错。更稳健、更常用的方法是使用ee.ImageCollection.map结合ee.FeatureCollection.map进行循环提取。// 5. 定义一个函数用于从单张影像上提取所有点的值 var extractPointData function(image) { // 对单张影像在每个点上采样sample值。 // scale: 采样尺度单位米。对于ERA5-Land9km设为9000或10000比较合适。 // geometries: 设为true会在结果中保留点的几何信息坐标导出SHP时需要。 var date image.date().format(YYYY-MM-dd); // 获取影像日期并格式化 var valuesAtPoints image.reduceRegions({ collection: stations, reducer: ee.Reducer.first(), // 提取该点上第一个也是唯一像素的值 scale: 10000, geometries: true // 如果最终要导出SHP这里必须为true }); // 为提取到的每个要素点添加一个日期属性 return valuesAtPoints.map(function(feature) { return feature.set(date, date); }); }; // 6. 将上述函数映射到整个影像集合得到一个新的要素集合每个点每天一条记录 var timeSeriesFeatures era5LandDaily.map(extractPointData).flatten(); print(timeSeriesFeatures.first()); // 打印第一条记录看看结构代码逻辑解读reduceRegions是核心的空间缩减操作。reducer: ee.Reducer.first()表示提取该点位置像素的值。对于点要素这就是简单的采样。scale: 10000这个参数至关重要。它指定了采样或计算的空间尺度。必须设置为与你的数据分辨率相匹配或更粗的尺度。对于约9km的ERA5-Land设置10000米10公里是安全的。设置得过细如100米不仅没必要还会导致GEE在后台进行不必要的重采样增加计算负担甚至报错。.map().flatten()这是一个经典模式。map将extractPointData函数应用到影像集合的每一张影像上每次返回一个包含所有站点当天数据的FeatureCollection。flatten()则将这些每日的集合“压平”合并成一个大的FeatureCollection其中每条记录是一个站点在一天的数据。运行print(timeSeriesFeatures.first())你会在控制台看到类似这样的输出表明数据结构正确Feature (5 properties) type: Feature geometry: Point (116.407, 39.904) properties: Object (4 properties) name: Beijing temperature_2m: 270.123456789 date: 2019-01-01 system:index: ...3.4 面要素的提取从“点采样”到“区域统计”提取到面比如一个县、一个流域的逻辑与点类似但reducer的选择不同。我们不再需要单个像素值而是需要能代表整个区域的一个统计值如平均值、最大值、最小值、总和等。假设我们有一个面要素集合counties包含多个县的边界。// 假设 counties 是一个面要素集合 var counties ee.FeatureCollection(path/to/your/counties/assets); // 修改提取函数中的 reducer var extractPolygonData function(image) { var date image.date().format(YYYY-MM-dd); // 使用 ee.Reducer.mean() 来计算区域内的平均值 var valuesAtPolygons image.reduceRegions({ collection: counties, reducer: ee.Reducer.mean(), // 关键变化使用均值 reducer scale: 10000, geometries: true // 导出SHP时需要 }); return valuesAtPolygons.map(function(feature) { // 可以同时添加多个统计量比如 var mean feature.get(temperature_2m_mean); // reducer.mean() 生成的属性名会带后缀 // 如果需要可以在这里重命名属性 return feature.set(date, date).set(temp_mean, mean); }); }; var timeSeriesForPolygons era5LandDaily.map(extractPolygonData).flatten();关键区别与注意事项Reducer的选择ee.Reducer.mean(),ee.Reducer.sum(),ee.Reducer.minMax()等。对于降水你可能关心总和 (sum)对于温度关心均值 (mean)。属性名使用ee.Reducer.mean()后生成的属性名会默认在原变量名后加上_mean后缀例如temperature_2m_mean。你需要知道这个规则去访问它。尺度效应scale参数对面统计影响更大。统计计算会在指定的尺度网格上进行。确保尺度不小于数据分辨率否则统计结果可能不准确。通常设置为数据分辨率的1-2倍是一个好的起点并进行敏感性测试。4. 结果导出生成CSV与SHP文件的实战细节数据提取到FeatureCollection后还在GEE的服务器内存里。我们需要将其导出到本地。4.1 导出为CSV文件CSV是最通用、最轻量的表格格式适合时间序列分析。// 假设 timeSeriesFeatures 是我们从点提取得到的时间序列集合 Export.table.toDrive({ collection: timeSeriesFeatures, description: ERA5_Temperature_TimeSeries_Points, // 任务名称 folder: GEE_Exports, // 可选Google Drive中的文件夹名 fileNamePrefix: station_temperature_2019_2023, fileFormat: CSV, selectors: [name, date, temperature_2m, longitude, latitude] // 选择要导出的属性列 });参数详解description: 导出任务在GEE任务管理器中的名称方便识别。folder: 文件将保存在你Google Drive的该文件夹下。如果不指定则在Drive根目录。fileNamePrefix: 导出文件的前缀。selectors:这是一个极其重要且容易出错的参数。它指定了导出CSV中包含哪些列。如果不指定GEE会导出所有属性包括很多系统自动生成的、无用的属性如system:index,.geo等导致CSV文件混乱。务必手动列出你需要的字段。对于点数据我通常会把longitude和latitude也导出来方便后续核对。你可以通过print(timeSeriesFeatures.first())查看具体的属性名。点击运行后你需要在GEE代码编辑器右上角的“Tasks”选项卡中找到刚生成的任务点击“RUN”来启动导出。文件会异步生成并上传到你的Google Drive。4.2 导出为SHP文件SHP是地理信息系统GIS中的标准矢量格式包含空间几何信息。当你需要将提取的数据连同地理位置一起在ArcGIS、QGIS等软件中查看或进一步分析时就需要SHP。Export.table.toDrive({ collection: timeSeriesFeatures, description: ERA5_Temperature_TimeSeries_Points_SHP, folder: GEE_Exports, fileNamePrefix: station_temperature_shp, fileFormat: SHP // 关键变化指定格式为SHP });SHP导出的特殊性文件包导出的是一个ZIP压缩包里面包含.shp,.shx,.dbf,.prj等SHP格式所需的多个文件。几何信息由于我们在reduceRegions时设置了geometries: true几何信息点坐标会被保留并导出。属性表CSV中的列在SHP中对应属性表的字段。注意SHP属性字段名有10字符长度限制过长的字段名会被截断。多部件要素GEE导出的SHP有时会将所有点合并成一个“多部件”要素这可能在GIS软件中无法单独选中每个点。一个解决办法是在导出前对集合中的每个要素单独设置几何信息但更简单的做法是导出为CSV含坐标和SHP两种格式CSV用于数据分析SHP用于可视化。5. 避坑指南与性能优化来自实战的经验之谈照着上面的步骤做基本能成功。但要想做得快、做得稳避免中途失败以下几点经验至关重要。5.1 错误排查当导出任务失败时“User memory limit exceeded” (用户内存超限)这是最常见错误。原因是处理的数据量太大时间跨度长、区域大、变量多、要素多。解决方案1分而治之。将长时间序列分成多个时间段分别运行导出任务。例如一次导出5年数据而不是20年。解决方案2空间筛选。在加载数据时使用filterBounds严格限定在你要素集所在的最小外接矩形区域减少不必要的影像加载。解决方案3提前聚合。如果你最终需要月数据就不要导出日数据再本地聚合。直接在GEE中使用.filter(ee.Filter.calendarRange(1, 12, month))结合mean()reducer进行月度聚合然后导出月均值数据量减少30倍。解决方案4采样尺度优化。确保scale参数设置合理不要过小。“Collection query aborted after accumulating over 5000 elements”GEE对客户端集合ee.List,ee.FeatureCollection在打印或预览时的元素数量有限制。解决方案不要试图print()或Map.addLayer()一个非常大的要素集合。直接进行导出操作即可。导出过程是服务器端的不受此限制。导出任务一直处于“READY”状态不开始检查是否在“Tasks”面板中手动点击了“RUN”。检查Google Drive是否有足够空间。任务可能正在排队稍等片刻。5.2 性能优化技巧变量预选务必使用.select()在最早阶段就只加载你需要的变量。加载[temperature_2m, total_precipitation]和加载所有变量计算效率天差地别。使用聚合产品如果分析精度允许直接使用ERA5/DAILY或ERA5/MONTHLY而不是从小时数据开始聚合。云端已经帮你算好了。简化几何如果你导入的SHP面要素边界非常复杂顶点数极多先用GIS软件简化一下或者用GEE的.simplify()方法处理能显著提升reduceRegions的速度。避免客户端循环在GEE中应尽量避免使用for循环客户端循环而多用map()、filter()、reduce()等服务器端函数。上面代码中的map就是服务器端操作。5.3 数据后处理须知单位检查下载CSV后第一件事是检查数值范围是否合理。ERA5的温度单位通常是开尔文(K)要转换为摄氏度(°C)需要减去273.15。降水单位是米转换为毫米需要乘以1000。缺失值处理GEE提取时如果点/面落在影像的无效区域如海洋对于ERA5-Land可能会得到null值。在导出前可以用.filter(ee.Filter.notNull([temperature_2m]))过滤掉这些无效记录或者在本地用Pandas、Excel进行处理。时间格式导出的日期字符串可能可以直接被分析软件识别也可能需要转换一下格式。最后分享一个我常用的代码结构模板它包含了错误处理和进度提示更加健壮// 定义所有参数 var startDate ee.Date(2019-01-01); var endDate ee.Date(2024-01-01); var scale 10000; var variables [temperature_2m, total_precipitation]; // 1. 加载数据 var dataset ee.ImageCollection(ECMWF/ERA5_LAND/DAILY) .filterDate(startDate, endDate) .select(variables); // 2. 加载要素 var points ee.FeatureCollection(your_points_asset_id); // 3. 提取函数 var extractData function(image) { var date image.date().format(YYYY-MM-dd); var reduced image.reduceRegions({ collection: points, reducer: ee.Reducer.first(), scale: scale }); // 添加日期并可选地重命名变量 return reduced.map(function(f) { return f.set(date, date) .set(temp, f.get(variables[0])) // 重命名 .set(precip, f.get(variables[1])); }); }; // 4. 映射并压平 var timeSeries dataset.map(extractData).flatten(); // 5. 过滤可能的空值按需 timeSeries timeSeries.filter(ee.Filter.notNull([temp])); // 6. 导出 Export.table.toDrive({ collection: timeSeries, description: My_ERA5_Export, fileFormat: CSV, selectors: [site_id, date, temp, precip, longitude, latitude] // 明确指定字段 }); print(导出任务已配置请在Tasks面板中运行。); print(预计数据量, timeSeries.size(), 条记录);掌握这套方法你就能在GEE这个强大的云端平台上游刃有余地驾驭ERA5气象数据将宏观的数据海洋精确提炼成你研究所需的微观数据溪流。无论是几百个站点还是成千上万个栅格单元GEE都能帮你高效、优雅地完成。