Geography 423/523 Problem set 2.

After working through page 35 of the Introduction to Google Earth Engine, you will have a basic understanding of how the cloud computing system works.

The goal for you will be to calculate the change in vegetation cover between two time periods related to a specific set of events and then verballly (qualitatively) describe the landscape pattern related to those events in terms of landscape metrics. You will need to present at least three images: the pre-event image, the post-event image, and the change image calculated as a vegetation-change index called dNBR or the differenced normalized burn ratio. It is calculated as the difference between near infrared and shortwave infrared wavelengths (bands 5 and 7). It actually shows all vegetation change quite well (not only fire), including increased greenness (as negative numbers).

There are two main differences in the code below from what was shown in the introductory tutorial. Here we use the Landsat 8 surface reflectance product which has atmospheric corrections applied. We also filter out clouds using the 'qa' band which codes whether each pixel is cloud or cloud shadow, and we mask these pixels out of the image using the maskL8sr function (which is in the code below).

Here are the steps for the assignment.

  1. Landsat 8 imagery covers from 2013 to present and is useable between 65N and 65S latitude. Choose a place where you know there has been a distinct disturbance to vegetation (forests, cropland, grassland) that occurred on the years between (and including) 2014 and 2017. Any change in greenness of the landscape could be studied, but a major dieback should be involved and better if it occurred in patches at least 50 m in size. Do not choose a random location. While you may detect a change occurred, you will not be able to easily describe the causes of the change. Rather, choose a location where you can find a news report describing the disturbance. Some suggestions: forest fires, major windstorms, very large earthquakes and rainstorms cause landslides in mountains, tsunamis, major insect outbreaks, increased logging, etc.
  2. Open the code editor in Google Earth Engine. Go the location of your study area, and use the polygon tool to draw a box over the area of interest. It should be at least a few kilometers per edge, but not hundreds of kilometers on each edge. Rename the polygon from the default ('geometry') to 'studyArea'
  3. Copy all the code below into the code editor. Change the dates for the pre- and post- images so that they are the year-before and the year-after the event. If the climate is seasonal in your study area, choose the same time of year for both images (with least amount of snow), and include enough time period so that some cloud-free days are likely to occur every few days when Landsat 8 takes pictures.
  4. Press the 'Run' button. It should work. You should hide the polygon by unchecking 'Geometry Imports" in the upper left corner. There will be four images in the Layers menu in the upper right corner of the map.
    1. The pre- and post- images
    2. The dNBR image and the categorized dNBR image. There should be a legend in the lower left for the categories. The categories help interpretation of patch sizes, shapes, etc. I followed the category description from the website link above that describes dNBR.
  5. You can explore the imagery using the layers menu. Turn on and off images, and change the opacity. For example, using the 'Map" rather than 'Satellite' basemap, you can look at the relationship of the disturbance with topography by viewing only 'dnbr-c' and changing its opacity using the slider bar. Or if the terrain is flat, you can use the satellite base map to show general land cover and then compare the 'dnbr-c' coverage against it.
  6. You may not like your study area choice. Change it by clicking reset button above the code editor (not the 'clear script' on the menu, just click Reset.) Then delete the studyArea polgon (trash can next to the item at the top of the lines of code). Then draw a new polygon and rename it studyArea, and select new dates.
  7. Use screen capture to get images from the desktop to save them as png image files to put into your report. On a Mac, press command-shift-4 then drag the mouse over the area that you want to capture as an image. Always include the scale bar in the lower right corner. A png image file is then saved in your Desktop folder. Rename it to something that describes the image.
  8. Answer the following questions in your report. Length should be 1.5 to 2 pages of text double-spaced, plus images on additional pages.
    1. Describe the site and event that you are studying. What is the natural or agricultural land cover? What is the process that is disturbing the vegetation?
    2. Show images of the pre- and post- vegetation. Put a caption under each image describing the content of the image. Refer to them as FIgure 1, Figure 2, etc.
    3. Show the image of the dNBR or classified dNBR. Note that you can change the color ramp or category boundaries to enhance some vegetation changes...but there is good basis for the categories in the provided code.
    4. The main task is to report on the following aspects:
      1. The spatial configuration of the patches of disturbance (and/or regrowth) with respect to topography and prior landcover.
      2. Qualitative desciption of the dnbr_c patch sizes, isolation, contagion, shape and other basic spatial properties described in the chapter on landscape metrics.
    5. Speculate on the processes that caused the patchiness in the images. Some processes might be obvious (as in the case for some human-made disturbances)...but try to say why people made those shapes.

Copy and paste all of the lines below into the code editor.

// Store the Landsat 8 surface-reflectance image collection in a variable. 
var landsat8_collection = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR"); 
// Filter to scenes that intersect your study region. 
var landsat8_studyArea = landsat8_collection.filterBounds(studyArea); 
// Filter to scenes for your time period of interest.  
// the image ending _pre is the pre-event image.
// the image ending _post is the post-event image.
var landsat8_SA_pre = landsat8_studyArea.filterDate('2016-08-01', '2016-8-30'); 
var landsat8_SA_post = landsat8_studyArea.filterDate('2018-08-01', '2018-8-30'); 

// Function to cloud mask from the pixel_qa band of Landsat 8 SR data.
function maskL8sr(image) {
  // Bits 3 and 5 are cloud shadow and cloud, respectively.
  var cloudShadowBitMask = ee.Number(2).pow(3).int();
  var cloudsBitMask = ee.Number(2).pow(5).int();

  // 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 the masked image, scaled to TOA reflectance, without the QA bands.
  return image.updateMask(mask).divide(10000)
      .select("B[0-9]*")
      .copyProperties(image, ["system:time_start"]);
}

// Mask the clouds from all images in the image collection 
// with the map function. 
var landsat8_SA_1NoClouds = landsat8_SA_pre.map(maskL8sr); 
var landsat8_SA_2NoClouds = landsat8_SA_post.map(maskL8sr); 

// Center your map. You may need to change the scale value from 9 to cover the correct area of map
Map.centerObject(studyArea, 9);

// Reduce the collection to the median value per pixel. 
var median_L8_pre = landsat8_SA_1NoClouds.median();
var median_L8_post = landsat8_SA_2NoClouds.median();

// Print the information of the reduced image. 
print(median_L8_pre, 'median_L8_pre');
print(median_L8_post, 'median_L8_post');

// Display reduced image in the map window. 
Map.addLayer(median_L8_pre, {min: 0.05, max: 0.8, bands: 'B6,B5,B4'}, 'pre-event: median composite');
Map.addLayer(median_L8_post, {min: 0.05, max: 0.8, bands: 'B6,B5,B4'}, 'post-event: median composite');

// Function to returns vegetation index for LS8
var ls8_Indices = function(lsImage){
  var nbr = lsImage.normalizedDifference(['B5', 'B7']).toFloat();
  return nbr;
  };

var l8_index_pre = ls8_Indices(median_L8_pre);
var l8_index_post = ls8_Indices(median_L8_post);

// calculate dNBR  
var dnbr = l8_index_pre.subtract(l8_index_post);

var dnbrViz = {min: -.250, max: .660, palette: ['green', 'yellow','orange','red']};
Map.addLayer(dnbr, dnbrViz,'dnbr');

//categorize the dnbr map into standard thresholds, categories 0 to 6.
var thresholds = ee.Image([-0.25,-0.1,0.1,0.27,0.44,0.66]);
var dnbr_c = dnbr.lt(thresholds).reduce('sum');
var dnbrViz_c = {min: 0, max: 6, palette: ['d73027','f46d43','fdae61','fee08b','ffffbf','91cf60','1a9850']};
Map.addLayer(dnbr_c, dnbrViz_c, 'dnbr_c');

//everything below here is to add a legend to the lower left of the map.
//showing the categorized dnbr values.  you can change these category break values
//in the ee.Image command above.

// set position of panel
var legend = ui.Panel({
  style: {
    position: 'bottom-left',
    padding: '8px 15px'
  }
});

// Create legend title
var legendTitle = ui.Label({
  value: 'dNBR classification',
  style: {
    fontWeight: 'bold',
    fontSize: '18px',
    margin: '0 0 4px 0',
    padding: '0'
    }
});

// Add the title to the panel
legend.add(legendTitle);

// Creates and styles 1 row of the legend.
var makeRow = function(color, name) {

      // Create the label that is actually the colored box.
      var colorBox = ui.Label({
        style: {
          backgroundColor: '#' + color,
          // Use padding to give the box height and width.
          padding: '8px',
          margin: '0 0 4px 0'
        }
      });

      // Create the label filled with the description text.
      var description = ui.Label({
        value: name,
        style: {margin: '0 0 4px 6px'}
      });

      // return the panel
      return ui.Panel({
        widgets: [colorBox, description],
        layout: ui.Panel.Layout.Flow('horizontal')
      });
};

//  Palette with the colors
var palette =['d73027','f46d43','fdae61','fee08b','ffffbf','91cf60','1a9850'];

// name of the legend
var names = ['High severity','Moderate-high severity','Moderate-low severity','Low severity','Unchanged','Low regrowth','High regrowth'];

// Add color and and names
for (var i = 0; i < 7; i++) {
  legend.add(makeRow(palette[i], names[i]));
  }  

// add legend to map (alternatively you can also print the legend to the console)
Map.add(legend);