1

When I graph the tree health for regions of interest for multiple years; during a twelve month period, there appears to be significant drops in the returned NDVI values. I believe these drops are coming from clouds.

NDVI Chart

Regions of Interest

I have tried unsuccessfully to implement the cloud masking per USGS Landsat 8 Surface Reflectance Tier 1.

How could I implement cloud masking into my code below?

var ROI = ee.Geometry.Point([141.041807, -34.033391]);

var kulkurna_A = ee.Geometry.Polygon([
  [
    [141.045513, -34.031637], [141.045252, -34.031597], [141.045002, -34.031647], 
    [141.044686, -34.031915], [141.044520, -34.032018], [141.040777, -34.035606], 
    [141.040349, -34.036386], [141.041069, -34.036233], [141.041372, -34.035775], 
    [141.042721, -34.034827], [141.043463, -34.034567], [141.045337, -34.031958]
    ]
    ]);

Map.addLayer(kulkurna_A, {color: 'blue'}, 'Kulkurna_A');

var kulkurna_B = ee.Geometry.Polygon([
  [
    [141.041761, -34.031699], [141.041590, -34.031794], [141.039482, -34.033245], 
    [141.038768, -34.034018], [141.039511, -34.035584], [141.039796, -34.034948], 
    [141.039535, -34.033698], [141.040783, -34.032723], [141.041335, -34.032393], 
    [141.041793, -34.031935]
    ]
    ]);

Map.addLayer(kulkurna_B, {color: 'red'}, 'Kulkurna_B');


//Center the Map
Map.setCenter(141.041807, -34.033391, 15);


var ens = [
ee.Feature(kulkurna_A, {label : 'Kulkurna A'}),
ee.Feature(kulkurna_B, {label : 'Kulkurna B'})
];

var collection =  ee.FeatureCollection(ens);
//print(collection); //Un comment to see values in console

// NDVI: NIR B5 and RED B4
var addNDVI = function(L8) {
var nir = L8.select('B5');
var red = L8.select('B4');
var ndvi = nir.subtract(red).divide(nir.add(red)).rename('NDVI');  
return L8.addBands(ndvi);
};

// Apply the cloud mask and NDVI function to Landsat 8 imagery and print the chart
var l8 = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR")
      .filter(ee.Filter.calendarRange(2013,2019,'year'))
      .filter(ee.Filter.calendarRange(1,12,'month'))
      .filterBounds(ROI)
       //Filter the WRS Row to 84 to prevent NDVI readings coming in from the overlap of adjacent rows 
      //(Landsat.usgs.gov/landsat_acq#convertPathRow)
      .filter(ee.Filter.eq('WRS_ROW',84))
      //Filter the row
      .filter(ee.Filter.eq('WRS_PATH',96))
      .map(addNDVI);

//------------------------------------------------
//Start graphing results
//------------------------------------------------

// Create an empty panel in which to arrange widgets.
// The layout is vertical flow by default.
var panel = ui.Panel({style: {width: '400px'}})
    .add(ui.Label('NDVI Charts'));

// Define customisation options.
var options = {
  title: {label: ens},
  hAxis: {title: 'Time'},
  vAxis: {title: 'NDVI'},
  lineWidth: 2,
  pointSize: 3,
  series: {
    0: {color: 'blue'}, //Colour of Chart
}};

//Graph all regions on same chart
var all_regions_graph = ui.Chart.image.seriesByRegion({
  imageCollection: l8, 
  regions: collection, 
  band: 'NDVI',
  reducer: ee.Reducer.mean(),
  scale: 30,
  seriesProperty: 'label'
      })
      .setChartType('ScatterChart')
      .setOptions({
  title: 'Kulkurna A & B',
  hAxis: {title: 'Time'},
  vAxis: {title: 'NDVI'},
  lineWidth: 2,
  pointSize: 3,
  });
//Print graph to User Interface, .set(x, name of graph) where: x = UI vertical position
panel.widgets().set(2, all_regions_graph);

//Graph individual region on its own chart
var kulkurna_A_graph = ui.Chart.image.seriesByRegion({
  imageCollection: l8, 
  regions: kulkurna_A, 
  band: 'NDVI',
  reducer: ee.Reducer.mean(),
  scale: 30,
  seriesProperty: 'kulkurna_A',
 })
      .setChartType('ScatterChart')
      .setOptions({
  title: 'Kulkurna A',
  hAxis: {title: 'Time'},
  vAxis: {title: 'NDVI'},
  lineWidth: 2,
  pointSize: 3,
  series: {0: {color: 'blue'}},
  });
//Print graph to User Interface, .set(x, name of graph) where: x = UI vertical position
panel.widgets().set(3, kulkurna_A_graph);

//Graph individual region on its own chart
var kulkurna_B_graph = ui.Chart.image.seriesByRegion({
        imageCollection: l8, 
        regions: kulkurna_B,
        band: 'NDVI',
        reducer: ee.Reducer.mean(),
        scale: 30,
        seriesProperty: 'Kulkurna B'
 })
      .setChartType('ScatterChart')
      .setOptions({
  title: 'Kulkurna B',
  hAxis: {title: 'Time'},
  vAxis: {title: 'NDVI'},
  lineWidth: 2,
  pointSize: 3,
  series: {0: {color: 'red'}},
  });
//Print graph to User Interface, .set(x, name of graph to show) where: x = UI vertical position
panel.widgets().set(4, kulkurna_B_graph);


// Add the panel to the ui.root.
ui.root.add(panel);
0

The function in the link you provided worked for me.

var ROI = ee.Geometry.Point([141.041807, -34.033391]);

var kulkurna_A = ee.Geometry.Polygon([
  [
    [141.045513, -34.031637], [141.045252, -34.031597], [141.045002, -34.031647], 
    [141.044686, -34.031915], [141.044520, -34.032018], [141.040777, -34.035606], 
    [141.040349, -34.036386], [141.041069, -34.036233], [141.041372, -34.035775], 
    [141.042721, -34.034827], [141.043463, -34.034567], [141.045337, -34.031958]
    ]
    ]);

Map.addLayer(kulkurna_A, {color: 'blue'}, 'Kulkurna_A');

var kulkurna_B = ee.Geometry.Polygon([
  [
    [141.041761, -34.031699], [141.041590, -34.031794], [141.039482, -34.033245], 
    [141.038768, -34.034018], [141.039511, -34.035584], [141.039796, -34.034948], 
    [141.039535, -34.033698], [141.040783, -34.032723], [141.041335, -34.032393], 
    [141.041793, -34.031935]
    ]
    ]);

Map.addLayer(kulkurna_B, {color: 'red'}, 'Kulkurna_B');


//Center the Map
Map.setCenter(141.041807, -34.033391, 15);


var ens = [
ee.Feature(kulkurna_A, {label : 'Kulkurna A'}),
ee.Feature(kulkurna_B, {label : 'Kulkurna B'})
];

var collection =  ee.FeatureCollection(ens);
//print(collection); //Un comment to see values in console

// NDVI: NIR B5 and RED B4
var addNDVI = function(L8) {
var nir = L8.select('B5');
var red = L8.select('B4');
var ndvi = nir.subtract(red).divide(nir.add(red)).rename('NDVI');  
return L8.addBands(ndvi);
};

//Function to mask clouds based on the pixel_qa band of Landsat 8 SR data.
function maskL8sr(image) {
  // Bits 3 and 5 are cloud shadow and cloud, respectively.
  var cloudShadowBitMask = (1 << 3);
  var cloudsBitMask = (1 << 5);
  // Get the pixel QA band.
  var qa = image.select('pixel_qa');
  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
                 .and(qa.bitwiseAnd(cloudsBitMask).eq(0));
  return image.updateMask(mask);
}


// Apply the cloud mask and NDVI function to Landsat 8 imagery and print the chart
var l8 = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR")
      .filter(ee.Filter.calendarRange(2013,2019,'year'))
      .filter(ee.Filter.calendarRange(1,12,'month'))
      .filterBounds(ROI)
       //Filter the WRS Row to 84 to prevent NDVI readings coming in from the overlap of adjacent rows 
      //(Landsat.usgs.gov/landsat_acq#convertPathRow)
      .filter(ee.Filter.eq('WRS_ROW',84))
      //Filter the row
      .filter(ee.Filter.eq('WRS_PATH',96))
      .map(addNDVI)
      .map(maskL8sr); // apply cloud masking function

//------------------------------------------------
//Start graphing results
//------------------------------------------------

// Create an empty panel in which to arrange widgets.
// The layout is vertical flow by default.
var panel = ui.Panel({style: {width: '400px'}})
    .add(ui.Label('NDVI Charts'));

// Define customisation options.
var options = {
  title: {label: ens},
  hAxis: {title: 'Time'},
  vAxis: {title: 'NDVI'},
  lineWidth: 2,
  pointSize: 3,
  series: {
    0: {color: 'blue'}, //Colour of Chart
}};

//Graph all regions on same chart
var all_regions_graph = ui.Chart.image.seriesByRegion({
  imageCollection: l8, 
  regions: collection, 
  band: 'NDVI',
  reducer: ee.Reducer.mean(),
  scale: 30,
  seriesProperty: 'label'
      })
      .setChartType('ScatterChart')
      .setOptions({
  title: 'Kulkurna A & B',
  hAxis: {title: 'Time'},
  vAxis: {title: 'NDVI'},
  lineWidth: 2,
  pointSize: 3,
  });
//Print graph to User Interface, .set(x, name of graph) where: x = UI vertical position
panel.widgets().set(2, all_regions_graph);

//Graph individual region on its own chart
var kulkurna_A_graph = ui.Chart.image.seriesByRegion({
  imageCollection: l8, 
  regions: kulkurna_A, 
  band: 'NDVI',
  reducer: ee.Reducer.mean(),
  scale: 30,
  seriesProperty: 'kulkurna_A',
 })
      .setChartType('ScatterChart')
      .setOptions({
  title: 'Kulkurna A',
  hAxis: {title: 'Time'},
  vAxis: {title: 'NDVI'},
  lineWidth: 2,
  pointSize: 3,
  series: {0: {color: 'blue'}},
  });
//Print graph to User Interface, .set(x, name of graph) where: x = UI vertical position
panel.widgets().set(3, kulkurna_A_graph);

//Graph individual region on its own chart
var kulkurna_B_graph = ui.Chart.image.seriesByRegion({
        imageCollection: l8, 
        regions: kulkurna_B,
        band: 'NDVI',
        reducer: ee.Reducer.mean(),
        scale: 30,
        seriesProperty: 'Kulkurna B'
 })
      .setChartType('ScatterChart')
      .setOptions({
  title: 'Kulkurna B',
  hAxis: {title: 'Time'},
  vAxis: {title: 'NDVI'},
  lineWidth: 2,
  pointSize: 3,
  series: {0: {color: 'red'}},
  });
//Print graph to User Interface, .set(x, name of graph to show) where: x = UI vertical position
panel.widgets().set(4, kulkurna_B_graph);


// Add the panel to the ui.root.
ui.root.add(panel);
| improve this answer | |
  • Thanks HMSP, I did not realise i could add .map(maskL8sr); // apply cloud masking function after .map(addNDVI) as I though I would be adding separate layers if that makes sense. – Damien N Aug 20 '19 at 6:52

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.