0

Below is my code to build a time series collection of all ETM+ and OLI Landsat images intersecting my region of interest. Now I want to build an ImageCollection that represents the mean or median of all images within a year for all years. Can you provide an example of how to build intra-annual composites in Earth Engine.

var coefficients = {
  itcps: ee.Image.constant([0.0003, 0.0088, 0.0061, 0.0412, 0.0254, 0.0172]).multiply(10000),
  slopes: ee.Image.constant([0.8474, 0.8483, 0.9047, 0.8462, 0.8937, 0.9071]),
};

// Define function to get and rename bands of interest from OLI.
function renameOLI(img) {
  return img.select(
        ['B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'pixel_qa'],
        ['Blue', 'Green', 'Red', 'NIR', 'SWIR1', 'SWIR2', 'pixel_qa']
    );
}

// Define function to get and rename bands of interest from ETM+.
function renameETM(img) {
  return img.select(
        ['B1', 'B2', 'B3', 'B4', 'B5', 'B7', 'pixel_qa'],
        ['Blue', 'Green', 'Red', 'NIR', 'SWIR1', 'SWIR2', 'pixel_qa']
  );
}

// Define function to apply harmonization transformation.
function etm2oli(img) {
  return img.select(['Blue', 'Green', 'Red', 'NIR', 'SWIR1', 'SWIR2'])
    .multiply(coefficients.slopes)
    .add(coefficients.itcps)
    .round()
    .toShort()
    .addBands(img.select('pixel_qa')
    .copyProperties(img, ['system:time_start'])
  );
}

// Define function to mask out clouds and cloud shadows.
function fmask(img) {
  var cloudShadowBitMask = 1 << 3;
  var cloudsBitMask = 1 << 5;
  var qa = img.select('pixel_qa');
  var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
    .and(qa.bitwiseAnd(cloudsBitMask).eq(0));
  return img.updateMask(mask);
}

// Define function to calculate NDVI.
function calcNdvi(img) {
  return img.normalizedDifference(['NIR', 'Red']).rename('NDVI');

}

// Define function to prepare OLI images.
function prepOLI(img) {
  var orig = img;
  img = renameOLI(img);
  img = fmask(img);
  img = calcNdvi(img);
  return ee.Image(img.copyProperties(orig, orig.propertyNames()));
}

// Define function to prepare ETM+ images.
function prepETM(img) {
  var orig = img;
  img = renameETM(img);
  img = fmask(img);
  img = etm2oli(img);
  img = calcNdvi(img);
  return ee.Image(img.copyProperties(orig, orig.propertyNames()));
}


// Define a point on the study area
  var aoi = ee.Geometry.Point([34.0049766165165,-6.137332241818918]);

// Define AOI on the map.
Map.centerObject(aoi, 10);
Map.addLayer(aoi, {color: 'f8766d'}, 'AOI');
Map.setOptions('HYBRID');

// Get Landsat surface reflectance collections for OLI, ETM+ and TM sensors.
var oliCol = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR');
var etmCol= ee.ImageCollection('LANDSAT/LE07/C01/T1_SR');

// Define a collection filter.
var colFilter = ee.Filter.and(
  ee.Filter.bounds(aoi),
  ee.Filter.calendarRange(1, 365, 'day_of_year'),
  ee.Filter.lt('CLOUD_COVER', 50),
  ee.Filter.lt('GEOMETRIC_RMSE_MODEL', 10),
  ee.Filter.or(
    ee.Filter.eq('IMAGE_QUALITY', 9),
    ee.Filter.eq('IMAGE_QUALITY_OLI', 9)
  )
);

// Filter collections and prepare them for merging.
oliCol = oliCol.filter(colFilter).map(prepOLI);
etmCol= etmCol.filter(colFilter).map(prepETM);


// Merge the collections.
var col = oliCol
  .merge(etmCol);



Export.image.toAsset({image:col, 
description:"collection", 
assetId:"rungwa", 
region:aoi.bounds(), 
scale:10, 
maxPixels:1e13}); 
  • Welcome to GIS SE! As a new user be sure to take the Tour to learn about our focussed Q&A format. As it stands I think your question would benefit from being heavily revised to try and make what you are asking clearer. I recommend reviewing meta.gis.stackexchange.com/a/3353/115 for tips on how to structure a good question. – PolyGeo Nov 1 '19 at 4:06
0
  1. Make an ee.List of years that you want to make intra-annual composites for.
  2. Map a compositing function over the list of years. Use each year passed to the function as the start and end time inputs to the ee.Filter.calendarRange filter to limit the merged collection to images within a given year. Reduce the resulting intra-annual collection.

Add the following snippet to your script after the merged collection is defined:

// #######################################################################
// ### USER INPUT ###
// #######################################################################

// Define start and end years.
var startYear = 2000;
var endYear = 2019;

// Define a reducer.
var myReducer = ee.Reducer.mean();

// #######################################################################

// Make a list of years to generate composites for.
var yearList = ee.List.sequence(startYear, endYear);

// Map over the list of years to generate a composite for each year - returns an List.
var yearCompList = yearList.map(function(year){
  // Filter the merged collection by the given year.  
  var yearCol = col.filter(ee.Filter.calendarRange(year, year, 'year'));
  // Make a list of filtered images for this year as a record.
  var imgList = yearCol.aggregate_array('LANDSAT_ID');
  // Reduce (composite) the images for this year.
  var yearComp = yearCol.reduce(myReducer);
  // Count the number of bands (used as a filter in a following step).
  var nBands = yearComp.bandNames().size();
  // Return the intra-annual composite - set properties just defined.
  return yearComp.set({
    'year': year,
    'image_list': imgList,
    'n_bands': nBands
  });
});

// Convert the annual composite image List to an ImageCollection
var yearCompCol = ee.ImageCollection.fromImages(yearCompList);

// Filter out years with no bands.
//(can happen if there were no images to composite)
yearCompCol = yearCompCol.filter(ee.Filter.gt('n_bands', 0));

// Check the work using year 2015. Filter year 2015.
var year2015 = yearCompCol.filter(ee.Filter.eq('year', 2015)).first();
// Get the list of images used to make the 2015 composite.
var imgList = year2015.get('image_list');
// Print the image list.
print('Images composited:', imgList);
// Display 2015 NDVI mean composite to the Map. 
Map.addLayer(year2015, {bands: ['NDVI_mean'], min: 0.2, max: 0.7, 
  palette: [
    'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
    '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
    '012E01', '011D01', '011301'
  ]}
);

Here is the entire script: https://code.earthengine.google.com/f8fd2c51107d2663c3f308efbf046c06

| improve this answer | |
  • Thanks a lot, it worked very well.but I need to go further to make each year a band in this collection from 2000 to 2019, so that ultimately my collection is made of 20 bands. how can I do this? – atu Nov 7 '19 at 4:08
  • Use the toBands() ImageCollection method. If you get stuck, ask a separate question on it. – Justin Braaten Nov 7 '19 at 18:51

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.