0

I am trying to create a median image per year from my image collection but when I apply the function ".filter(ee.Filter.calendarRange(y,y,'year')", it doesn't work and reports an error of "ImageCollection (Error) Collection.toList: The value of 'count' must be positive. Got: 0".

What do I do?

Here is a link to the GEE code below:

https://code.earthengine.google.com/b0efb0c9e8f806e3e22b7c9ea823c84b

code:

// Area of Interest
var aoi = ee.FeatureCollection(roi);
var my_roi = ee.Geometry.Rectangle(101.635,3.005,101.654,3.045);
Map.centerObject(aoi,10);
Map.addLayer(aoi,{}, 'aoi',false);
Map.addLayer(my_roi,{}, 'roi',true);

// Apply scaling factor to images
var applyScaleFactor = function(image){
  var opticalBands = image.select('SR_B.').multiply(0.0000275).add(-0.2);
  var thermalBands = image.select('ST_B.*').multiply(0.00341802).add(149.0);
  return image.addBands(opticalBands, null, true)
              .addBands(thermalBands, null, true);
};

// Function to rename bands for Landsat 5 & 7
var renamebands_L57 = function(image){
  var bands = ['SR_B1','SR_B2','SR_B3','SR_B4','SR_B5','SR_B7'];
  var newbands = ['B','G','R','NIR','SWIR1','SWIR2'];
  return image.select(bands).rename(newbands);
};

// Function to rename bands for Landsat 8
var renamebands_L8 = function(image){
  var bands = ['SR_B2','SR_B3','SR_B4','SR_B5','SR_B6','SR_B7'];
  var newbands = ['B','G','R','NIR','SWIR1','SWIR2'];
  return image.select(bands).rename(newbands);
};

// Cloud and shadow masking
var cloudMask = function(image){
  var qa_band = image.select('QA_PIXEL');
  var cloudShadowBitValue = 8;
  var cloudBitValue = 32;
  // create masks
  var shadowMask = qa_band.bitwiseAnd(cloudShadowBitValue).eq(0);
  var cloudMask = qa_band.bitwiseAnd(cloudBitValue).eq(0);
  var finalMask = shadowMask.and(cloudMask);
  return image.updateMask(finalMask);
};

// Load the satellite images
var lsat5 = ee.ImageCollection("LANDSAT/LT05/C02/T1_L2")
                          .filterBounds(aoi)
                          .sort('CLOUD_COVER')
                          .map(cloudMask)
                          .map(applyScaleFactor)
                          .map(renamebands_L57)
                          .filter(ee.Filter.calendarRange(6,9,'month'))
                          .map(function(image){return image.clip(aoi)});

var lsat7 = ee.ImageCollection("LANDSAT/LE07/C02/T1_L2")
                          .filterBounds(aoi)
                          .sort('CLOUD_COVER')
                          .map(cloudMask)
                          .map(applyScaleFactor)
                          .map(renamebands_L57)
                          .filter(ee.Filter.calendarRange(6,9,'month'))
                          .filter(ee.Filter.calendarRange(1999,2021,'year'))
                          .map(function(image){return image.clip(aoi)});

var lsat8 = ee.ImageCollection("LANDSAT/LC08/C02/T1_L2")
                          .filterBounds(aoi)
                          .sort('CLOUD_COVER')
                          .map(cloudMask)
                          .map(applyScaleFactor)
                          .map(renamebands_L8)
                          .filter(ee.Filter.calendarRange(6,9,'month'))
                          .filter(ee.Filter.calendarRange(2013,2021,'year'))
                          .map(function(image){return image.clip(aoi)});

// Merge Images and sort by date
var merged_img = lsat5.merge(lsat7).merge(lsat8);

// Sort the merged images by date
var merged_img = merged_img.sort('system:time_start');

// Display images
print('Landsat 5 images', lsat5);
print('Landsat 7 images', lsat7);
print('Landsat 8 images', lsat8);
print('Merged Landsat images', merged_img);

Map.addLayer(lsat5,{bands: ['R','G','B'], min:0, max:0.3},'Landsat 5 image',false);
Map.addLayer(lsat7,{bands: ['R','G','B'], min:0, max:0.3},'Landsat 7 image',false);
Map.addLayer(lsat8,{bands: ['R','G','B'], min:0, max:0.3},'Landsat 8 image',false);
Map.addLayer(merged_img,{bands: ['R','G','B'], min:0, max:0.3},'Merged Landsat image',false);

// Create a function for NDVI
var my_ndvi = function(image){
  var ndvi = image.normalizedDifference(['NIR','R']);
  return image.addBands(ndvi.rename('NDVI')).float();
};

// Add indices to Image collection
var merged_img_indices = merged_img.map(my_ndvi);
print('Merged Img NDVI', merged_img_indices);

//create a time series chart with the trendline
var my_chart = ui.Chart.image.series({imageCollection:
  merged_img_indices.select('NDVI'),
  region: my_roi,
  reducer: ee.Reducer.mean(),
  scale:30
}).setChartType('ScatterChart')
  .setOptions({
    title: 'NDVI during the summer months',
    vAxis: {title: 'NDVI'},
    hAxis: {title: 'Date'},
    pointSize:2,
    trendlines: {0: {color: 'red'}}
  });
print(my_chart);

// Create a function to create a median image per year
// Define the earliest available date
var start_date = ee.Date(merged_img_indices.first().get('system:time_start'));
print('Start date',start_date);
// Convert the start date year from string to number
var start_year = ee.Number.parse(start_date.format('YYYY'));
print('start year',start_year);
// Define years as a sequence from the first year with available data until 2021
var years = ee.List.sequence(start_year, 2021);
print('years',years);

// Creating median images per year
var Annual_img = ee.ImageCollection.fromImages(
  years.map(function(y){
         // filter by year
         var current_year = merged_img_indices
             .filter(ee.Filter.calendarRange(y, y,'year'));
           // Check number of images within a year
           var year_size = current_year.size();
           // get the middle of the collection for the system:time_start info
           var year_size_div = year_size.divide(2);
           var year_size_div_round = year_size_div.round();
           var current_year_list = current_year.toList(year_size);
           var current_mid = current_year_list.get(year_size_div_round);
           // Return the median of the current year and define the current year
           // date and unix time of the middle image of the year
           return current_year
                      .median()
                      .set('Year', y)
                      .set('No_of_images', year_size)
                      .copyProperties(ee.Image(current_mid), ['system:time_start']);
  }));

// Display the Annual Image Collection
print('Annual Image Collection', Annual_img);

// Concver the Annual imgage collection to liste and display the 21st
var Annual_img_list = Annual_img.toList(Annual_img.size());
Map.addLayer(ee.Image(Annual_img_list.get(21)), {bands: ['R','G','B'], min:0, max:0.3}, '21th Annual Image', true);

// Create Time Series Chart
var my_chart = ui.Chart.image.series({imageCollection: Annual_img.select('NDVI'),
  region: my_roi,
  reducer: ee.Reducer.mean(),
  scale:30
}).setChartType('ScatterChart')
  .setOptions({
    title: 'Annual NDVI During Summer Months',
    vAxis: {title: 'NDVI'},
    hAxis: {title: 'Date'},
    pointSize: 2,
    lineSize: 1,
    trendlines: {0: {color: 'red'}}
  });
  
print(my_chart);

1 Answer 1

2

There are no images for one of the years in the region you're working in (looks like it's 2004). So the size of the collection is 0. And you're not allowed to call toList() with a 0 value. You could use max() to make that at least 1, but that'll just cause failures farther down.

The easiest thing here is just to avoid the bad year by removing it from the list you're mapping over. Or check year_size and skip the rest of the map over years if it's 0, using ee.Algorithms.If().

0

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.