Portfolio Entry I — September 18, 2020

Using image analysis from Hansen et al. (2013), how has tree cover in parks across Rwanda changed from 2000 to 2019?

In this analysis, we compare tree cover in parks of different protection levels across Rwanda. Using IUCN classifications for determining park protection levels and data from Hansen et al. (2013) about tree cover, we investigate if international standards and satellite imagery-based analyses reflect land use practices on the ground.

Land cover in parks

In 2019, all parks in Rwanda contributed to very little of the overall loss of tree cover. Strictly protected parks lost 0.0001% of the tree cover, and less-strictly protected parks lost 0.00001% of the tree cover. This difference is negligible, with less protected parks having barely fewer amounts of deforestation than more strictly protected parks. None of the parks exhibit large-scale deforestation, though wooded areas outside of the parks did experience tree cover loss.

Park boundary designations and IUCN categories

Our assumptions about park boundary designations are limited by how we break down which parks are strictly and less-strictly protected, the number of parks that fall into each designation, and overlaps between international park designations. Our categorizations of park designations (where strictly protected parks matched the IUCN categories between ‘Ia’ and ‘IV,’ and less-strictly designated parks were in categories ‘V,’ ‘VI,’ ‘Not Applicable,’ and ‘Not Reported’) place parks into categories that may not accurately represent local communities and conditions. For example, parks that have an IUCN status of ‘Not Reported’ or ‘Not Applicable’ are not necessarily less protected, but may be governed by local conditions that are outside of the IUCN categories. By calculating the raw percentage of total forest loss in strictly protected versus less protected parks, even when there are far fewer less protected than strictly protected parks, we distort the overall number of applicable pixels that could be counted for in each type of park. Further, some parks may have protected status from two different bodies (national government and international protection status), leading to two overlapping boundaries and a double-counting of deforested pixels in our assessment (Fig. 2). These inconsistencies in park designations can lead to misconceptions about global forest protection, demonstrating that all findings combining park boundaries and global forest change need to be assessed with a lens towards local conditions.

Aside from misinterpretations about park boundary designations, the underlying reasons for tree loss and growth patterns, along with community relationships to the land, cannot be captured entirely by satellite imagery data. Building off the work by Hansen et al. (2013), the definitions of “tree cover,” “forest,” and “forest loss” create problematic assumptions about how land coverage is recognized and categorized based on satellite imagery. In this land classification scheme, tree cover loss is often assumed to be caused by logging and extractive harvesting practices, but does not account for non-extractive canopy loss from wildfires, flooded swamps, and other ecosystem regime changes. In IUCN category VI, sustainable harvesting of natural resources is permitted, meaning that deforestation could be captured in satellite imagery without recognition of long-term sustainable regrowth efforts. Additionally, local communities may not be actively cognizant about different park protection statuses (access that you have in an IUCN II vs. IUCN IV), as these guidelines may exist in a more international context than local practice. Despite the immense power of satellite imagery to measure large-scale forest ecosystem changes, our assessment of tree cover change in a national park does not always capture the nuances of local land use practices.


Code block

/*
Portfolio project #1
Name: Jacob Freedman
Middlebury email: jafreedman@middlebury.edu
Date: 9/17/20
*/

//######## 1. Select Rwanda #########\\
var countries = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017');
var rwanda = ee.Feature(
  countries
    .filter(ee.Filter.eq('country_na', 'Rwanda'))
    .first()
);

//####### 2. Select Rwanda parks and categorize into 
// 'stricly protected' and 'less protected' ########\\
var rwandaParks = ee.FeatureCollection('WCMC/WDPA/current/polygons')
  .filter(ee.Filter.and(
    ee.Filter.bounds(rwanda.geometry())
  ));
  
var strictlyProtectedAreas = rwandaParks
  .filter(ee.Filter.or(               // .and() versus .or() allows you to link a series of filters. .and() means all conditions have to be true.
    ee.Filter.eq('IUCN_CAT', 'Ia'),
    ee.Filter.eq('IUCN_CAT', 'Ib'),
    ee.Filter.eq('IUCN_CAT', 'II'),
    ee.Filter.eq('IUCN_CAT', 'III'),
    ee.Filter.eq('IUCN_CAT', 'IV')
  ))
  .map(function(feature){
    return rwanda.intersection(feature);
  });
  
var lessProtectedAreas = rwandaParks
  .filter(ee.Filter.or( 
    ee.Filter.eq('IUCN_CAT', 'V'),
    ee.Filter.eq('IUCN_CAT', 'VI'),
    ee.Filter.eq('IUCN_CAT', 'Not Applicable'),
    ee.Filter.eq('IUCN_CAT', 'Not Reported'),
    ee.Filter.eq('STATUS', 'Proposed')
  ))
  .map(function(feature){
    return rwanda.intersection(feature);
  });


//####### 3. Calculate percentage of tree cover loss within 
// strictly and less-strictly protected parks in 2019  ########\\
var lossIn2019 = gfc2019.select(['lossyear']).eq(19);// the raster produced here is binary: 1 = loss in 2019, 0 = no loss in 2019
var strictParkLoss2019 = lossIn2019.reduceRegion({  // this how we summarize and get statistics of an area. 
  reducer: ee.Reducer.sum(), // here we are adding up all of those pixels with an area value, to get total area of the pixels
  geometry: strictlyProtectedAreas.geometry(),
  scale: 30, 
  maxPixels: 1e13
});
/*
print('pixels lost in strictly protected areas:',
  strictParkLoss2019.get('lossyear'), // so the reduceRegion() function returns a dictionary. 
  'pixels' //we use .get() to read the value from within the dictionary. It is still a dictionary object, though
);
*/

var lessStrictParkLoss2019 = lossIn2019.reduceRegion({
  reducer: ee.Reducer.sum(),
  geometry: lessProtectedAreas.geometry(),
  scale: 30,
  maxPixels: 1e9
});
/*
print('pixels lost in less strictly protected areas:',
  lessStrictParkLoss2019.get('lossyear'),
  'pixels'
);
*/


// 3a. Show tree cover (30% coverage) in Rwanda in 2000
var treeCover = gfc2019.select(['treecover2000']);

// Canopy cover percentage (30%).
var cc = ee.Number(30);
var treeCover30 = treeCover.gte(cc).selfMask();

var treeCoverStats = treeCover30.reduceRegion({  // this how we summarize and get statistics of an area. 
  reducer: ee.Reducer.sum(), // here we are adding up all of those pixels with an area value, to get total area of the pixels
  geometry: rwanda.geometry(),
  scale: 30, 
  maxPixels: 1e13
});
/*
print('sum of tree cover pixels (30% and greater)',
  treeCoverStats.get('treecover2000'), 
  'pixels' 
);
*/


//####### 4. Final Printouts ########\\
var pixelsLostStrict = ee.Number(strictParkLoss2019.get('lossyear'));
var pixelsLostLessStrict = ee.Number(lessStrictParkLoss2019.get('lossyear'));
var treePixels2000 = ee.Number(treeCoverStats.get('treecover2000'));

print('Strictly protected parks lost',
  pixelsLostStrict.divide(treePixels2000), '%',
  'of the tree cover'
);

print('Less protected parks lost',
  pixelsLostLessStrict.divide(treePixels2000), '%',
  'of the tree cover'
);


//####### 5. Final Map Layers ########\\
// 5a. Show tree cover in 2000
var treeCoverVisParam = {
  bands: ['treecover2000'],
  min: 0,
  max: 1,
  palette: ['#8FBC8F']
};
Map.addLayer(treeCover30.clip(rwanda), treeCoverVisParam, 'Tree Cover in 2000');

// 5b. Show forest cover loss in the Congo in 2019
var treeLossVisParam = {
  bands: ['lossyear'],
  min: 0,
  max: 1,
  palette: ['#8b0000']
};
Map.addLayer(lossIn2019.clip(rwanda), treeLossVisParam, 'Forest Cover Loss in 2019');


// 5c. Differentiate  protected area boundaries
// Create empty images to paint features onto
var empty1 = ee.Image().byte();
var empty2 = ee.Image().byte();

// Display less protected area boundaries with the same color and width.
var outlineLessStrictPA = empty1.paint({
  featureCollection: lessProtectedAreas,
  width: 2
});
Map.addLayer(outlineLessStrictPA, {palette: ['blue']}, 'Less Protected Areas (blue)');

// Display strict protected area boundaries with the same color and width.
var outlineStrictPA = empty2.paint({
  featureCollection: strictlyProtectedAreas,
  width: 2
});
Map.addLayer(outlineStrictPA, {palette: ['black']}, 'Strict Protected Areas (black)');

Link to code: https://code.earthengine.google.com/3de1b36e464bc788f1aef2d29418a1cd