3

The script below allows to extract monthly precipitation data for a single shapefile point. how can we modify it so that it can extract data for multiple points contained in a single shapefile.

The script: https://code.earthengine.google.com/ca1cf1a0b4b8ad6b7a4e3f076e893e91

var startYear = '2008';
var endYear = '2009';

var dataset = ee.ImageCollection('NASA/GPM_L3/IMERG_MONTHLY_V06')
    .filterDate(startYear, endYear)
    .select('precipitation');
    
print(dataset);

var getPrecipit = function(image) {

  // Reducing region and getting value
  var value_ppt = ee.Image(image)
    .reduceRegion(ee.Reducer.mean(), point)
    .get('precipitation');

  return ee.Number(value_ppt).multiply(24);  //mm/day

};

var count = dataset.size();

var ppt_list = dataset.toList(count).map(getPrecipit);

print("ppt_list (mm/day)", ppt_list);

var year_list = ee.List.sequence(ee.Number.parse(startYear), ee.Number.parse(endYear).subtract(1));

var leapYear_list = year_list.map( function leapYear(year) {
  
  return ee.Number(year).mod(4).eq(0).and(ee.Number(year).mod(100).neq(0)).or(ee.Number(year).mod(400).eq(0));
  
});

//print(leapYear_list);

var monthNumberDays = leapYear_list.map(function setYearsNumberDays (ele) {

  return ee.Algorithms
    .If(ee.Number(ele).eq(1), [31,29,31,30,31,30,31,31,30,31,30,31], 
                              [31,28,31,30,31,30,31,31,30,31,30,31]);
  
}).flatten();

//print("Month Number Days", monthNumberDays);

var monthlyValues = ppt_list.map(function (ele){
  
  var idx = ppt_list.indexOf(ele);
  
  return ee.Number(ele).multiply(monthNumberDays.get(idx));
  
});

//print(monthlyValues);

var allDates = ee.List(dataset.aggregate_array('system:time_start'));

var allDatesSimple = allDates.map(function(date){
  return ee.Date(date).format().slice(0,7);
  });

//print(allDatesSimple);

var paired = allDatesSimple.zip(monthlyValues);

print("ppt_list (mm/month)", paired);

var myFeatures = ee.FeatureCollection(paired.map(function(el){
  el = ee.List(el); // cast every element of the list
  return ee.Feature(null, {
    'date': ee.String(el.get(0)),
    'ppt_monthly':ee.Number(el.get(1))
  });
}));

//print(myFeatures);

// Export features, specifying corresponding names.
Export.table.toDrive(myFeatures,
"export_ppt", //my task
"GEE_Folder", //my export folder
"ppt_monthly",  //file name
"CSV");


1 Answer 1

3

When you upload a shapefile to GEE, you basically have a Feature Collection. So, I'm going to consider a Feature Collection with 3 arbitrary points in USA geography created in GEE. As you are using a monthly product then, you are going to obtain 12 values per year independently of number of points. So, if you are going to export as CSV, for instance, 10 years of precipitation (as in following code), you will have to consider for exporting 120 features. Each feature will have attached as property its respective date (year_month) and monthly precipitation per each point (matrix of 120x6; including id and null geometry fields).

For getting monthly precipitation values for each point, you need to map the Feature Collection with a function that includes getPrecipit and monthlyValues previous functions as follows.

var p1 = ee.Feature(ee.Geometry.Point([-97.44070668220519, 41.93324324360744]));
var p2 = ee.Feature(ee.Geometry.Point([-93.92508168220519, 40.612183748474436]));
var p3 = ee.Feature(ee.Geometry.Point([-97.08914418220519, 38.5807048157763]));

var col = ee.FeatureCollection([p1, p2, p3]);
var col_list = col.toList(col.size());

print(col);

Map.addLayer(col);

var startYear = '2008';
var endYear = '2018';

var dataset = ee.ImageCollection('NASA/GPM_L3/IMERG_MONTHLY_V06')
    .filterDate(startYear, endYear)
    .select('precipitation');
    
print(dataset);

var dataset_list = dataset.toList(dataset.size());

var year_list = ee.List.sequence(ee.Number.parse(startYear), ee.Number.parse(endYear).subtract(1));

var leapYear_list = year_list.map( function leapYear(year) {
  
  return ee.Number(year).mod(4).eq(0).and(ee.Number(year).mod(100).neq(0)).or(ee.Number(year).mod(400).eq(0));
  
});

//print(leapYear_list);

var monthNumberDays = leapYear_list.map(function setYearsNumberDays (ele) {

  return ee.Algorithms
    .If(ee.Number(ele).eq(1), [31,29,31,30,31,30,31,31,30,31,30,31], 
                              [31,28,31,30,31,30,31,31,30,31,30,31]);
  
}).flatten();

var allDates = ee.List(dataset.aggregate_array('system:time_start'));

var allDatesSimple = allDates.map(function(date){
  return ee.Date(date).format().slice(0,7);
  });

//print(allDatesSimple);

var getMonthlyValues = col_list.map(function (feat) {
  
  var getPrecipit = function(image) {

    // Reducing region and getting value
    var value_ppt = ee.Image(image)
      .reduceRegion(ee.Reducer.mean(), ee.Feature(feat).geometry())
      .get('precipitation');

    return ee.Number(value_ppt).multiply(24);  //mm/day

  };
  
  var ppt_list = dataset_list.map(getPrecipit);
  
  var monthlyValues = ppt_list.map(function (ele){
  
    var idx = ppt_list.indexOf(ele);
    
    return ee.Number(ele).multiply(monthNumberDays.get(idx));
    
  });
  
  return monthlyValues;
  
});

var list = ee.List.sequence(0, ee.Number(allDatesSimple.size()).subtract(1));

var myFeatures = ee.FeatureCollection(list.map(function(el){
  el = ee.List(el); // cast every element of the list
  return ee.Feature(null, {
    'date': allDatesSimple.get(el),
    'p1': ee.List(getMonthlyValues.get(0)).get(el),
    'p2': ee.List(getMonthlyValues.get(1)).get(el),
    'p3': ee.List(getMonthlyValues.get(2)).get(el),
    
  });
}));

print(myFeatures);

// Export features, specifying corresponding names.
Export.table.toDrive(myFeatures,
"export_ppt", //my task
"GEE_Folder", //my export folder
"ppt_monthly",  //file name
"CSV");

After running above code in GEE code Editor, I got following CSV file:

enter image description here

It has 121 records where the first one has the field names (p1, p2, p3 corresponds to each point).

Editing Note:

Following modification at the bottom of the script automatically generates the precipitation values for the Feature Collection of points. Complete code can be accessed here.

var list = ee.List.sequence(0, ee.Number(allDatesSimple.size()).subtract(1));

var features = ee.FeatureCollection(list
      .map(function (i) {
        return ee.Feature(null).set('date', allDatesSimple.get(i));
      })
    );

print(features);

var mapped = features.map(function (feature) {
  return ee.Feature(
    ee.List.sequence(0, col.size().subtract(1)).iterate(
      function (i, feature) {
        i = ee.Number(i);
        feature = ee.Feature(feature);
        var idx = feature.id();
        var key = ee.String('p').cat(i.format('%d'));
        var value = ee.List(getMonthlyValues.get(i)).get(ee.Number.parse(idx));
        return feature.set(key, value);
      },
      
      feature
    )
  );
});

print(mapped);

// Export features, specifying corresponding names.
Export.table.toDrive(mapped,
"export_ppt", //my task
"GEE_Folder", //my export folder
"ppt_monthly",  //file name
"CSV");
2
  • Thank you , the code works well. However, is there a possibility to automatically generate the precipitation values for all the points without listing them all like in lines 82 to 83 of the code ('p1': ee.List(getMonthlyValues.get(0)).get(el),....) since we may have dozens or hundreds of points?
    – Bouram
    Apr 3, 2023 at 10:31
  • Yes, it is possible. Please, see my Editing Note.
    – xunilk
    Apr 4, 2023 at 14:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.