1. 认识GlobFire v2火灾数据集
我第一次接触GlobFire v2数据集是在分析澳大利亚山火的时候。这个基于MCD64A1的全球火灾数据集,就像给地球装了一个"火灾记录仪",能让我们清楚地看到过去20年全球火灾的"活动轨迹"。
GlobFire v2最厉害的地方在于,它不仅记录了火灾发生的位置,还精确标注了每个火灾斑块的边界和面积。这就好比不仅知道哪里发生了火灾,还能准确测量出每个火灾现场的"伤疤"有多大。数据集覆盖2000-2021年,包含了全球范围内的火灾事件,每个事件都有唯一的ID标识,就像给每场火灾都办了"身份证"。
在GEE平台上,这个数据集的路径是ee.FeatureCollection("JRC/GWIS/GlobFire/v2/FinalPerimeters")。我特别喜欢它的几个字段设计:
area:火灾面积(平方米)FinalDate/InitialDate:火灾起止时间Id:唯一标识符
这些字段组合起来,就像给每场火灾建立了一个完整的"档案",让我们可以从时间、空间、规模三个维度进行交叉分析。比如去年分析亚马逊雨林火灾时,我就是通过这些字段快速筛选出了过去十年间8-10月(旱季)发生的所有火灾事件。
2. 数据准备与环境配置
在GEE上使用GlobFire v2之前,有几个准备工作要做。首先确保你有一个Google Earth Engine账号(如果没有可以去官网申请,通常24小时内就能通过)。登录后,建议先创建一个新脚本,我习惯命名为GlobFire_Analysis。
// 初始化地图 var map = ui.Map(); map.setControlVisibility(false); // 隐藏默认控件 map.setOptions('satellite'); // 使用卫星底图接下来是加载数据集。这里有个小技巧:GlobFire v2实际上有两个版本:
FinalPerimeters:最终确定的火灾边界DailyPerimeters:每日更新的火灾边界
我一般先用FinalPerimeters做宏观分析,需要研究具体火灾发展过程时才会用DailyPerimeters。加载代码很简单:
var globfire = ee.FeatureCollection("JRC/GWIS/GlobFire/v2/FinalPerimeters"); print(globfire.first()); // 查看第一条记录的结构记得添加一个方便查看的底图。我推荐使用ESA的全球土地覆盖数据作为背景:
var landcover = ee.Image("ESA/WorldCover/v100/2020"); Map.addLayer(landcover, {min:0,max:100}, 'Land Cover');3. 时空分析方法详解
3.1 时间维度分析
分析火灾的年际变化特别有意思。我写过一个函数,可以统计每年火灾总面积:
// 按年份统计火灾总面积 var yearlyStats = function(startYear, endYear) { var stats = []; for (var y = startYear; y <= endYear; y++) { var startDate = ee.Date.fromYMD(y, 1, 1); var endDate = ee.Date.fromYMD(y, 12, 31); var yearlyFires = globfire.filterDate(startDate, endDate); var totalArea = yearlyFires.reduceColumns({ reducer: ee.Reducer.sum(), selectors: ['area'] }).get('sum'); stats.push({ year: y, area: totalArea }); } return ee.FeatureCollection(stats); }; var stats = yearlyStats(2000, 2020); print(stats);这个函数会输出一个表格,包含每年的火灾总面积。我建议把结果导出到Google Drive,然后用Excel或Python做进一步的可视化分析。
3.2 空间热点识别
识别火灾热点区域就像在玩"大家来找茬"。我常用的方法是空间聚类分析:
// 计算火灾密度 var fireDensity = globfire .filterDate('2010-01-01', '2020-12-31') .reduceToImage(['area'], ee.Reducer.sum()) .divide(ee.Image.constant(1e10)); // 转换为每万平方公里 var fireHotspots = fireDensity.gt(0.5); // 定义热点阈值 Map.addLayer(fireDensity, {min:0, max:1, palette:['white','red']}, 'Fire Density'); Map.addLayer(fireHotspots.selfMask(), {palette:['red']}, 'Hotspots');这个方法可以快速锁定像澳大利亚东南部、美国加州、地中海沿岸这些常年"上火"的地区。调整阈值参数(上面代码中的0.5)可以控制热点识别的灵敏度。
4. 高级可视化技巧
4.1 动态时间轴展示
GEE最酷的功能之一就是时间轴动画。我经常用这个功能给合作方演示火灾的季节性变化:
// 创建月际动画 var monthlyFires = globfire.filterDate('2020-01-01', '2020-12-31'); var months = ee.List.sequence(1, 12); var monthlyImages = months.map(function(m) { var start = ee.Date.fromYMD(2020, m, 1); var end = start.advance(1, 'month'); return ee.Image().paint( monthlyFires.filterDate(start, end), 0, 1 // 值设为1便于统计 ).set('month', m); }); var collection = ee.ImageCollection(monthlyImages); print(ui.Chart.image.seriesByRegion({ imageCollection: collection, regions: ee.FeatureCollection([ee.Geometry.Rectangle([-180,-90,180,90])]), reducer: ee.Reducer.sum(), scale: 50000, xProperty: 'month' }));这段代码会生成一个折线图,显示2020年每月全球火灾数量的变化趋势。配合GEE的时间轴控件,还能动态播放火灾的空间分布变化。
4.2 三维火灾图谱
虽然GEE本身是二维的,但我们可以用一些小技巧实现伪3D效果:
// 创建3D效果可视化 var elevation = ee.Image('USGS/SRTMGL1_003'); var fireHeight = fireDensity.multiply(5000); // 将火灾密度转换为高度 var visParams = { opacity: 0.7, palette: ['blue', 'green', 'yellow', 'red'], min: 0, max: 1 }; Map.addLayer(fireHeight, visParams, '3D Fire Map'); Map.addLayer(elevation, {min:0, max:3000}, 'Elevation');这样火灾频发的区域会"凸起",就像在地形图上叠加了一层火灾"热度图"。调整multiply的参数可以控制凸起的高度。
5. 实际应用案例分析
去年我用这套方法分析过东南亚的农业焚烧问题。当地农民有烧荒的传统,但很难量化影响。通过GlobFire v2数据,我们发现了几个有趣的现象:
- 烧荒活动有明显的周期性,每年3-4月和9-10月是两个高峰
- 虽然单次焚烧面积不大,但累计影响惊人 - 某些地区年焚烧面积超过国土面积的15%
- 焚烧热点与棕榈油种植园分布高度重合
分析代码是这样的:
// 东南亚农业焚烧分析 var seAsia = ee.Geometry.Rectangle([92, -11, 141, 28]); // 东南亚范围 var agriFires = globfire .filterBounds(seAsia) .filter(ee.Filter.rangeContains('area', 10000, 500000)); // 筛选典型农火规模 var monthlyCount = agriFires .aggregate_histogram('InitialDate.month') .sort('key'); print('Monthly distribution:', monthlyCount); // 热点分析 var kernel = ee.Kernel.circle(50000, 'meters'); var density = agriFires .reduceToImage(['area'], ee.Reducer.count()) .convolve(kernel); Map.addLayer(density, {min:0, max:50, palette:['white','yellow','red']}, 'Agricultural Fire Density');这个案例展示了如何将GlobFire v2数据与实际环境问题结合。类似的思路也适用于分析野火与气候变化的关系、评估火灾对生物多样性的影响等课题。
6. 常见问题与解决方案
在使用GlobFire v2的过程中,我踩过不少坑。这里分享几个典型问题的解决方法:
问题1:数据加载慢
- 解决方案:先按时间或空间范围筛选,不要直接加载整个数据集
// 不好的做法 var allFires = ee.FeatureCollection("JRC/GWIS/GlobFire/v2/FinalPerimeters"); // 推荐做法 var filteredFires = ee.FeatureCollection("JRC/GWIS/GlobFire/v2/FinalPerimeters") .filterDate('2020-01-01', '2020-12-31') .filterBounds(yourRegion);问题2:可视化效果不理想
- 解决方案:调整色阶和透明度
// 默认可视化可能不明显 Map.addLayer(fires, {}, 'Fires'); // 优化后的可视化 Map.addLayer(fires, { palette: ['yellow', 'red'], opacity: 0.6, width: 2 }, 'Optimized Fires');问题3:统计分析内存不足
- 解决方案:使用reducer时添加scale参数
// 可能导致内存不足 var totalArea = fires.aggregate_sum('area'); // 推荐做法 var totalArea = fires.reduceColumns({ reducer: ee.Reducer.sum(), selectors: ['area'], weight: null }).get('sum');还有一个实用技巧是使用batch模式运行耗时较长的分析任务,避免浏览器会话超时。在代码编辑器右上角有个"Task"按钮,可以把任务提交到后台运行。
7. 与其他数据集的联合分析
GlobFire v2真正的威力在于与其他数据的交叉分析。我经常结合以下几类数据:
- 气候数据:分析火灾与温度、降水的关系
var climate = ee.ImageCollection("ECMWF/ERA5/MONTHLY"); var temp = climate.select('mean_2m_air_temperature');- 植被数据:研究火灾前后的植被变化
var ndvi = ee.ImageCollection("MODIS/006/MOD13A2").select('NDVI');- 人类活动数据:评估人类活动对火灾的影响
var population = ee.ImageCollection("WorldPop/GP/100m/pop");一个典型的联合分析案例是这样的:
// 火灾与气候关系分析 var climateZones = ee.Image("USDOS/LSIB_SIMPLE/2017"); var joinedData = globfire.map(function(fire) { var point = fire.geometry().centroid(); var climate = climateZones.reduceRegion({ reducer: ee.Reducer.mode(), geometry: point, scale: 5000 }); return fire.set(climate); }); var stats = joinedData.aggregate_histogram('climate'); print('Fire distribution by climate zone:', stats);这种交叉分析往往能发现很多有意思的规律。比如我们发现热带草原气候区的火灾频率是热带雨林气候区的3-4倍,但单次火灾面积反而更小。
8. 自动化分析与定期监测
对于需要长期跟踪的项目,我建议设置自动化分析流程。GEE的Export功能可以把结果定期保存到Google Drive或Cloud Storage:
// 年度报告自动生成 var annualReport = function(year) { var yearlyFires = globfire.filterDate( ee.Date.fromYMD(year, 1, 1), ee.Date.fromYMD(year, 12, 31) ); // 按大洲统计 var continents = ee.FeatureCollection("USDOS/LSIB_SIMPLE/2017"); var stats = yearlyFires.reduceToImage(['area'], ee.Reducer.sum()) .reduceRegions({ collection: continents, reducer: ee.Reducer.sum(), scale: 5000 }); // 导出到Google Drive Export.table.toDrive({ collection: stats, description: 'FireStats_' + year, fileNamePrefix: 'fire_stats_' + year, fileFormat: 'CSV' }); }; // 执行2010-2020年的分析 for (var y = 2010; y <= 2020; y++) { annualReport(y); }这个脚本会在你的Google Drive生成11个CSV文件,每个文件包含对应年份各大陆的火灾统计数据。配合Google Sheets的自动化脚本,可以进一步实现自动化的报告生成和可视化更新。
在实际项目中,我还经常设置异常警报。比如当某个区域的火灾面积突然比去年同期增加50%以上时,自动发送邮件提醒:
// 异常检测(伪代码) var current = globfire.filterDate(currentPeriod).sum('area'); var baseline = globfire.filterDate(baselinePeriod).sum('area'); var anomaly = current.divide(baseline).gt(1.5); if (anomaly) { // 调用邮件发送API }