Search code examples
javascriptgoogle-earth-engine

I want to solve the "system:time_start" error when trying to output GLDAS monthly precipitation to CSV using Google Earth Engine


I am using GoogleEarthEngine to look at precipitation data for the Mekong River basin. The GLDAS data are set every three hours per day. My goal is to extract the GLDAS data from 2000 to 2020 by adding up the data by month.

I want to extract the total monthly precipitation in GLDAS using the Google Earth Engine, but I cannot extract the CSV due to the error

Image.date: Image '120' has a 'system:time_start' property which is not a number: 2010-01-01T00:00:00

I think I can extract the CSV by converting "system:time_start", how should I change it?

var studyArea = ee.Geometry.Rectangle(102, 8.5, 107, 15);
Map.centerObject(mekong, 9);

// 解析対象年
var years = ee.List.sequence(2000, 2019);
var months = ee.List.sequence(1, 12);

var early = ('2010-01-01');
var late =  ('2011-01-01');

// MOD11A1の取り出し
var image = ee.ImageCollection('NASA/GLDAS/V021/NOAH/G025/T3H')
  .filterDate(early, late).filterBounds(mekong);
//print(image);

// mmに変換してmodLSTcに保存
var gldas_precipitation = image.select('Rainf_f_tavg');
var gldas_precipitation_mm = gldas_precipitation.map(function(img)
  {return img.multiply(10080.0).copyProperties(img, ['system:time_start'])});

// 変数gldas_precipitation_mm_monthの中に月単位のメジアンデータを保存  ////////////////////////////////////////////
var gldas_precipitation_mm_month = ee.ImageCollection.fromImages(
  years.map(function(y) {
    return months.map(function(m) {
      var monthly = gldas_precipitation_mm.filter(ee.Filter.calendarRange(y, y, 'year'))
        .filter(ee.Filter.calendarRange(m, m, 'month'))
        .sum()
        .rename('precipitation_mm_month');
    
    return monthly.set('year', y).set('system:time_start', ee.Date.fromYMD(y, 1, 1))
      .set('month', y).set('system:time_start', ee.Date.fromYMD(y, m, 1));
  });
}).flatten());

var gldas_precipitation_mm_month = gldas_precipitation_mm_month.filterBounds(mekong);

// TSLのポリゴン ///////////////////////////////////////////////////////////////////////////////////
var empty = ee.Image().byte();
// Paint all the polygon edges with the same number and width, display
var outline = empty.paint({
  featureCollection: mekong,
  color: 1,
  width: 2
});
Map.addLayer(outline, {palette: 'FF0000'}, 'TSL');

//output_csv_precipitation
//Create variables and extract data
var scale = gldas_precipitation_mm_month.mean().projection().nominalScale().multiply(0.05); print(scale);
var gldas = gldas_precipitation_mm_month.filter(ee.Filter.listContains('system:band_names', gldas_precipitation_mm.mean().bandNames().get(0)));
var ft = ee.FeatureCollection(ee.List([]));

//Function to extract values from image collection based on point file and export as a table 
var fill = function(img, ini) {
var inift = ee.FeatureCollection(ini);
var ft2 = img.reduceRegions(mekong, ee.Reducer.mean(), scale);
var date = img.date().format("YYYY/MM/dd");
var ft3 = ft2.map(function(f){return f.set('month', date)});
return inift.merge(ft3);
};

// Iterates over the ImageCollection
var profile = ee.FeatureCollection(gldas_precipitation_mm_month.iterate(fill, ft));
print(profile,'profile');

Solution

  • The value of the property system:time_start must be a number (even though it would make sense for it to be a Date, the system design didn't end up that way). You must change calls like

    .set('system:time_start', ee.Date.fromYMD(y, m, 1))
    

    to

    .set('system:time_start', ee.Date.fromYMD(y, m, 1).millis())
    

    While looking, I see other possible problems here:

        return monthly.set('year', y).set('system:time_start', ee.Date.fromYMD(y, 1, 1))
          .set('month', y).set('system:time_start', ee.Date.fromYMD(y, m, 1));
    

    This is setting the month property value to the y variable (not m), and it's setting system:time_start twice (so only the second value will be used). Probably this is not what you meant. I have not looked at what you're intending to do with the collection, so you'll have to figure that part out yourself.