You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Earth Engine:如何将LandTrendr输出数组保存为表格?

问题描述

基于LandTrendr算法提取土地覆被变化时,提取拟合值数组后,控制台执行print(fitted)仅显示“Image (1 Band)”,无法查看具体数值,需要将数组输出保存为表格格式。原代码参考LandTrendr官方文档的5.1 LandTrendr Band部分编写,代码如下:

var points = ee.Geometry.Point([-121.946741626287, 39.7895992866194]);

// Define annual composite date range.
var startDay = 175; // start at 175th day of year
var nDays = 90;    // end 120 days later

// Define year range
var startYear = 1990;
var endYear   = 2020;

// Define band to use for segmentation
var bandName = 'B7';

// Define LandTrendr parameters
var ltParams = { 
  maxSegments:            6,
  spikeThreshold:         0.9,
  vertexCountOvershoot:   3,
  preventOneYearRecovery: true,
  recoveryThreshold:      0.25,
  pvalThreshold:          0.05,
  bestModelProportion:    0.75,
  minObservationsNeeded:  6
};


// Display the point.
Map.centerObject (points, 13);
Map.addLayer(points, {color: 'red'});
Map.setOptions('SAtellite');

// Define function to mask clouds and cloud shadows.
function cfmask(img) {
  var cloudShadowBitMask = 1 << 3;
  var cloudsBitMask = 1 << 5;
  var Mask = qa.bitweiseAnd (cloudShadowBitMask)
     .eq(0)
     .and(qa.bitwiseAnd(cloudsBitMask).eq(0))
  return img.updateMask(mask);
}

// Import Landsat 5 surface reflectance collection
var lsCol = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR');

// Define a list of years to make composits for.
var yearsList = ee.List.sequence(startYear, endYear, 1);

// Map over the year list to build an annual composite collection.
var annualCol = ee.ImageCollection.fromImages(
  yearsList.map(function(yr) {
    var startDate =  ee.Date.fromYMD(yr, 1, 1).advance(startDay, 'day');
    var middleDate = startDate.advance(nDays/2, 'day');
    var endDate = startDate.advance(nDays+1, 'day');
    var yearCol = lsCol
       .filterDate(startDate, endDate)
       .filterBounds(points)
       .select(bandName)
       .median();
    var nBands = yearCol.bandNames().size();
    return yearCol.set({
      'system:time_start': middleDate.millis(),
      'nBands': nBands
    });
    
  })
  );

// Deal with missing years (no images or all pixels masked).
var yearPresentCol = annualCol.filter(ee.Filter.neq('nBands', 0));
var yearAbsentCol = annualCol.filter(ee.Filter.eq('nBands', 0));

// Make a filter image for missing years - all pixels masked.
var dummyImg = ee.Image(0).selfMask().rename(bandName);

// Add dummy image band to image with bands (missing years).
yearAbsentCol = yearAbsentCol.map(function(img) {
  return img.addBands(dummyImg);
});

// merge the missing years collection to valid years collection.
var ltCol = yearPresentCol.merge(yearAbsentCol);

// Set the annual composite collection as the LandTrendr timeSeries parameter.
ltParams.timeSeries = ltCol;

var ltArrImg = ee.Algorithms.TemporalSegmentation.LandTrendr(ltParams);
print(ltArrImg);

// Map.addLayer(ltArrImg);

var segmentationInfo = ltArrImg.select(['LandTrendr'])

var LTarray = ltArrImg.select(['LandTrendr']); // subset the LandTrendr segmentation info
var year = LTarray.arraySlice(0, 0, 1); // slice out the year row
var fitted = LTarray.arraySlice(0, 2, 3); // slice out the fitted values row
print(fitted);
解决方案

问题核心

fitted是GEE中的数组图像(Array Image),控制台直接打印只会显示图像类型标识,不会解析并展开数组内的具体数值。需提取目标点位/区域的数值,转换为结构化格式后导出为表格。

步骤1:修正原代码错误

原代码的云掩膜函数存在变量未定义、拼写错误,先修正:

// 修正后的云掩膜函数
function cfmask(img) {
  var qa = img.select('pixel_qa'); // 补充定义qa变量
  var cloudShadowBitMask = 1 << 3;
  var cloudsBitMask = 1 << 5;
  var mask = qa.bitwiseAnd(cloudShadowBitMask) // 修正拼写bitweiseAnd为bitwiseAnd,统一变量大小写
    .eq(0)
    .and(qa.bitwiseAnd(cloudsBitMask).eq(0));
  return img.updateMask(mask);
}

步骤2:提取并结构化数值

将年份与拟合值数组合并后,提取目标点的数值并转换为表格结构:

// 合并年份与拟合值数组,展平为普通波段
var yearFitted = year.addBands(fitted).arrayFlatten([['year', 'fitted_value']]);

// 提取目标点的数值
var pointData = yearFitted.sampleRegions({
  collection: ee.FeatureCollection(points),
  scale: 30, // 匹配Landsat 30米分辨率
  geometries: true
});

// 打印结构化表格数据到控制台
print('年份-拟合值表格', pointData);

步骤3:导出为CSV表格

通过GEE的导出功能将数据保存到Google Drive,生成可编辑的表格:

// 导出到Google Drive
Export.table.toDrive({
  collection: pointData,
  description: 'LandTrendr_Fitted_Values',
  folder: 'GEE_Outputs', // 自定义Drive文件夹名称
  fileFormat: 'CSV'
});

完整修正代码

整合所有修正与新增逻辑后的完整代码:

var points = ee.Geometry.Point([-121.946741626287, 39.7895992866194]);

// Define annual composite date range.
var startDay = 175; // start at 175th day of year
var nDays = 90;    // end 120 days later

// Define year range
var startYear = 1990;
var endYear   = 2020;

// Define band to use for segmentation
var bandName = 'B7';

// Define LandTrendr parameters
var ltParams = { 
  maxSegments:            6,
  spikeThreshold:         0.9,
  vertexCountOvershoot:   3,
  preventOneYearRecovery: true,
  recoveryThreshold:      0.25,
  pvalThreshold:          0.05,
  bestModelProportion:    0.75,
  minObservationsNeeded:  6
};

// Display the point.
Map.centerObject(points, 13);
Map.addLayer(points, {color: 'red'});
Map.setOptions('SATELLITE'); // 修正拼写SAtellite为大写SATELLITE

// 修正后的云掩膜函数
function cfmask(img) {
  var qa = img.select('pixel_qa');
  var cloudShadowBitMask = 1 << 3;
  var cloudsBitMask = 1 << 5;
  var mask = qa.bitwiseAnd(cloudShadowBitMask)
    .eq(0)
    .and(qa.bitwiseAnd(cloudsBitMask).eq(0));
  return img.updateMask(mask);
}

// Import Landsat 5 surface reflectance collection
var lsCol = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR')
  .map(cfmask); // 应用云掩膜

// Define a list of years to make composits for.
var yearsList = ee.List.sequence(startYear, endYear, 1);

// Map over the year list to build an annual composite collection.
var annualCol = ee.ImageCollection.fromImages(
  yearsList.map(function(yr) {
    var startDate =  ee.Date.fromYMD(yr, 1, 1).advance(startDay, 'day');
    var middleDate = startDate.advance(nDays/2, 'day');
    var endDate = startDate.advance(nDays+1, 'day');
    var yearCol = lsCol
       .filterDate(startDate, endDate)
       .filterBounds(points)
       .select(bandName)
       .median();
    var nBands = yearCol.bandNames().size();
    return yearCol.set({
      'system:time_start': middleDate.millis(),
      'nBands': nBands
    });
    
  })
);

// Deal with missing years (no images or all pixels masked).
var yearPresentCol = annualCol.filter(ee.Filter.neq('nBands', 0));
var yearAbsentCol = annualCol.filter(ee.Filter.eq('nBands', 0));

// Make a filter image for missing years - all pixels masked.
var dummyImg = ee.Image(0).selfMask().rename(bandName);

// Add dummy image band to image with bands (missing years).
yearAbsentCol = yearAbsentCol.map(function(img) {
  return img.addBands(dummyImg);
});

// merge the missing years collection to valid years collection.
var ltCol = yearPresentCol.merge(yearAbsentCol);

// Set the annual composite collection as the LandTrendr timeSeries parameter.
ltParams.timeSeries = ltCol;

var ltArrImg = ee.Algorithms.TemporalSegmentation.LandTrendr(ltParams);
print('LandTrendr结果图像', ltArrImg);

var LTarray = ltArrImg.select(['LandTrendr']); // subset the LandTrendr segmentation info
var year = LTarray.arraySlice(0, 0, 1); // slice out the year row
var fitted = LTarray.arraySlice(0, 2, 3); // slice out the fitted values row

// ----------------新增代码:提取并导出表格----------------
// 合并年份与拟合值数组,展平为普通波段
var yearFitted = year.addBands(fitted).arrayFlatten([['year', 'fitted_value']]);

// 提取目标点的数值
var pointData = yearFitted.sampleRegions({
  collection: ee.FeatureCollection(points),
  scale: 30,
  geometries: true
});

// 打印结构化数据到控制台
print('年份-拟合值表格数据', pointData);

// 导出到Google Drive为CSV表格
Export.table.toDrive({
  collection: pointData,
  description: 'LandTrendr_Fitted_Values',
  folder: 'GEE_Results',
  fileFormat: 'CSV'
});

内容的提问来源于stack exchange,提问作者babak asadolah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 17:02:08