0

I'm struggling at finding a way to extract daily average temperatures and total precipitations for different points (an imported table as FeatureCollection), throughout a selected period of time (few years). At the moment, I am trying 2 options:

  1. https://code.earthengine.google.com/dce98ed8676655aa41b8ad5f820f6eae
  2. https://code.earthengine.google.com/de3052ead7a94c8a1b498da8b45f67e1

In the first one i get what i want but I need to change the structure of the outcome, since there are as many columns as the number of days analysed. What I want to obtain is a table with columns for the date, the sector ("settore"), the avrg temperature and the total precipitation. Which is what i get in the secondo code, more or less, except that for each day I get the same tempertature and precipitation values, probably an overwriting problem.

I also tried to use only the ReduceRegions function on the selected dataset:

   var startDate = ee.Date('2014-10-01');
   var endDate = ee.Date('2014-10-10');

   var dataset = ee.ImageCollection("ECMWF/ERA5_LAND/HOURLY")
                                   .filterDate(startDate, endDate)
                                   .select('temperature_2m');

   var reducedTemp = ee.FeatureCollection(dataset.map(function(img){
       return img.reduceRegions({
              collection: tos,
              reducer: ee.Reducer.mean(),
              scale: 30,
              crs: 'EPSG:4326'});
        }));

The problem here is that I get 24 data (per sector) for a single day and I'm not capable to reduce them to a single record per day.

2 Answers 2

3

With your two links code, I got an asset error so, I assumed only one arbitrary point in Italy (13.797235003125458, 41.65261836389952) for testing my code. It calculates for this point 'total_precipitation_hourly' as sum and 'temperature_2m' as mean for 24 hours each day. Values were corrected for expressing them in its respective units (mm for total precipitation and ºC for temperature). I mapped Image collection with individual functions for precipitation and temperature but they can be combined in only one. These functions produce for your date range (9 days) a list of 9 distinct dates and a list of paired values of precipitation and temperature for exporting them to Google Drive. Complete code looks as follows:

var pt = ee.Geometry.Point([13.797235003125458, 41.65261836389952]);

Map.addLayer(pt);
Map.centerObject(pt);

var dataset = ee.ImageCollection("ECMWF/ERA5_LAND/HOURLY");

var startDate = ee.Date('2014-10-01');
var endDate = ee.Date('2014-10-10');
var diff = endDate.difference(startDate, 'day');

var precD = dataset.select('total_precipitation_hourly')
                  .filterDate(startDate, endDate);

var list_precD = precD.toList(dataset.size());

var tempD = dataset.select('temperature_2m')
                  .filterDate(startDate, endDate);

var list_tempD = tempD.toList(dataset.size());

var getPrecipitation = function(image) {

  var value_precipit = ee.Image(image)
    .reduceRegion(ee.Reducer.first(), pt)
    .get('total_precipitation_hourly');
  
  var precipit_mm = ee.Number(value_precipit)
    .multiply(ee.Number(1000)); //original values are in meters

  var time = ee.Image(image).get('system:time_start');

  return precipit_mm;
};

var getTemperature = function(image) {

  var value_temp = ee.Image(image)
    .reduceRegion(ee.Reducer.first(), pt)
    .get('temperature_2m');
  
  var temp = ee.Number(value_temp)
    .subtract(ee.Number(273.15)); //original values are in kelvin

  var time = ee.Image(image).get('system:time_start');

  // Return the time (in milliseconds since Jan 1, 1970) as a Date

  return temp;
};

var precipit_list = list_precD.map(getPrecipitation);

print("precipitation list", precipit_list);

var temp_list = list_tempD.map(getTemperature);

print("temperature list", temp_list);

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

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

var len = precipit_list.size();

var list = ee.List.sequence(0, len.subtract(1), 24);

//print(list);

var sum_precipit_list = list.map(function(ele){

  var start = ee.Number(ele).int(); 
  var end = ee.Number(ele).add(24).int(); 

  var new_list = ee.List([]);
  var element = ee.List(precipit_list.slice(start, end)).reduce(ee.Reducer.sum());

  new_list = new_list.add(element);

  return new_list;

}).flatten();

var mean_temp_list = list.map(function(ele){

  var start = ee.Number(ele).int(); 
  var end = ee.Number(ele).add(24).int(); 

  var new_list = ee.List([]);
  var element = ee.List(temp_list.slice(start, end)).reduce(ee.Reducer.mean());

  new_list = new_list.add(element);

  return new_list;

}).flatten();

//print(mean_temp_list);

var paired = sum_precipit_list.zip(mean_temp_list);

paired = allDatesSimple.zip(paired);

print (paired);

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

//print(myFeatures);

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

After running it in GEE code editor, my csv file can be perfectly edited for producing corresponding stats. After edition, it looks as follows (dates, total precipitation and mean temperature daily; respectively):

2014-10-01,0.151218777034501,14.4043162027995
2014-10-02,9.27646323742692,13.3050126393636
2014-10-03,1.24336779106216,12.6744043986003
2014-10-04,0.531125068732763,12.1380198160808
2014-10-05,0.270527601173853,12.5899838765462
2014-10-06,0.627899169899138,12.472039159139
2014-10-07,0.014889240162575,13.0912865956625
2014-10-08,0.000860646668599,13.8759221394857
2014-10-09,0.00085234631797,14.7941274007162
3
  • Thanks a lot, that is huge! It works perfectly fine, though, my asset is a collection of points. To extend the iteration over my asset should I use reduceRegions instead of reduce Region? Mar 25, 2021 at 7:11
  • If you want a result for each point you should have a Feature Collection of them and to map each feature with a function.
    – xunilk
    Mar 25, 2021 at 12:56
  • I'll try, thanks again! Mar 25, 2021 at 16:02
1

You can reduce the ImageCollection before doing your call to reduceRegions(). This will leave you with only 1 outcome per sector:

var startDate = ee.Date('2014-10-01');
var endDate = ee.Date('2014-10-10');

var dataset = ee.ImageCollection("ECMWF/ERA5_LAND/HOURLY")
                               .filterDate(startDate, endDate)
                               .select('temperature_2m')
                               .mean();

var reducedTemp = dataset.reduceRegions({
  collection: tos,
  reducer: ee.Reducer.mean(),
  scale: 30,
  crs: 'EPSG:4326'
});

Then you can also do the same with precipitation but instead reduce the Image Collection and the Regions with .sum().

1
  • Hi, thank you for your answer. I tried that but it is not what I need since I want to have one value per sector per each day of the selected period. Reducing the dataset by the mean I only get one value for the entire period. Mar 24, 2021 at 13:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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