working with landcover data

analyzing change dynamics

Question 1: copy the code below into the code editor and study the landcover timeseries

var classStruct = {
  'evergreen': {number: 0, color: '267300'},
  'semi-evergreen': {number: 1, color: '38A800'},
  'deciduous': {number: 2, color: '70A800'}, 
  'mangrove': {number: 3, color: '00A884'}, 
  'flooded forest': {number: 4, color: 'B4D79E'}, 
  'rubber': {number: 5, color: 'AAFF00'}, 
  'other plantations': {number: 6, color: 'F5F57A'}, 
  'rice': {number: 7, color: 'FFFFBE'},
  'cropland': {number: 8, color: 'FFD37F'}, 
  'surface water': {number: 9, color: '004DA8'},
  'grassland': {number: 10, color: 'D7C29E'}, 
  'woodshrub': {number: 11, color: '89CD66'}, 
  'built-up area': {number: 12, color: 'E600A9'}, 
  'village': {number: 13, color: 'A900E6'}, 
  'other': {number: 14, color: '6f6f6f'}
};

  var classNamesList = getIds(classStruct);
  var probNames = cleanList(classNamesList);
  var classNames = ee.List(classNamesList);
  var classNumbers = getList(classStruct,'number');
  var PALETTE_list = getList(classStruct,'color');

  var PALETTE = PALETTE_list.join(',');


//var mode = ee.Image("projects/cemis-camp/assets/landcover/lcBandsv1/alandcover2012").reduce(ee.Reducer.mode())

//Map.addLayer(mode,{palette:PALETTE,min:0,max:classNamesList.length-1},"mode");

//var mode = ee.Image("projects/cemis-camp/assets/landcover/lcBandsv1/landcover2012").reduce(ee.Reducer.mode())

//Map.addLayer(mode,{palette:PALETTE,min:0,max:classNamesList.length-1},"mode original");


print(ee.ImageCollection("projects/servir-mekong/composites"))

var years = [2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020]
 
for (var i = 0; i< 21; i++){
  var year = years[i]
  print(year)
  var start = ee.Date.fromYMD(year,1,1)
  var end = ee.Date.fromYMD(year,12,31)
  var composite = ee.Image(ee.ImageCollection("projects/servir-mekong/composites").filterDate(start,end).first()).divide(10000)
  Map.addLayer(composite,{min:0,max:0.3,bands:"red,green,blue"},"composite " + year.toString(),false)
  
  var lcMap = ee.Image("projects/cemis-camp/assets/landcover/lcv4/"+year.toString())
  Map.addLayer(lcMap,{palette:PALETTE,min:0,max:classNamesList.length-1},year.toString(),false);

}

///////////////////////////////////////////////////////////////////////////////
// Function to get a list of ids (keys) from a structure
function getIds(struct){
  return Object.keys(struct);
}

// Function to replace spaces with underscores in a list of strings
function cleanList(list){
  return list.map(function(name){
    return name.replace(/\s+/g,'_'); 
  });
}

///////////////////////////////////////////////////////////////////////////////
// Function to get a list of column values from a structure
function getList(struct,column){
  return Object.keys(struct).map(function(k){
    var value = struct[k][column];
    return value;
  });
}


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

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

// 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 ui.Panel({
    widgets: [colorBox, description],
    layout: ui.Panel.Layout.Flow('horizontal')
  });
};



for (var i = 0; i < classNamesList.length; i++){
  legend.add(makeRow(PALETTE_list[i],classNamesList[i]));
}

legend.add(legendTitle);
// Add the legend to the map.
Map.add(legend)

// 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 ui.Panel({
    widgets: [colorBox, description],
    layout: ui.Panel.Layout.Flow('horizontal')
  });
};

Question 2: use the below and analyse the amount of change

// import the landcover time series
var lcMap = ee.ImageCollection("projects/cemis-camp/assets/landcover/lcv4");

// create a list with years
var years = ee.List.sequence(2000,2019,1);

// create a map function to extract the current and next year
var analyseTimeSeries = function(year){
  var start = ee.Date.fromYMD(year,1,1);
  var end = ee.Date.fromYMD(year,12,31);
  var lcCurrent = ee.Image(lcMap.filterDate(start,end).first());
  
  var start = ee.Date.fromYMD(year,1,1).advance(1,"year");
  var end = ee.Date.fromYMD(year,12,31).advance(1,"year");
  var lcNext = ee.Image(lcMap.filterDate(start,end).first());
  
  // chekc wether the classes are the same or if they change
  var change = lcCurrent.neq(lcNext);
  return change;
};

// mapp the years over the function, an image collection is returned
var changeData = ee.ImageCollection(years.map(analyseTimeSeries));

//vizualize the results
Map.addLayer(ee.Image(changeData.sum()),{min:0,max:20,palette:"white,yellow,red,purple"},"change")

Question 3: we analyse forest into cropland conversions using the code below

// import the landcover time series
var lcMap = ee.ImageCollection("projects/cemis-camp/assets/landcover/lcv4");

// create a list with years
var years = ee.List.sequence(2000,2019,1);

// create a map function to extract the current and next year
var analyseTimeSeries = function(year){
  var start = ee.Date.fromYMD(year,1,1);
  var end = ee.Date.fromYMD(year,12,31);
  var lcCurrent = ee.Image(lcMap.filterDate(start,end).first());
  
  var start = ee.Date.fromYMD(year,1,1).advance(1,"year");
  var end = ee.Date.fromYMD(year,12,31).advance(1,"year");
  var lcNext = ee.Image(lcMap.filterDate(start,end).first());
  
  // check wether the classes are the same or if they change
  var change = lcCurrent.lt(3).and(lcNext.eq(8)).set("system:time_start",lcCurrent.get("system:time_start"));
  return change;
};

// mapp the years over the function, an image collection is returned
var changeData = ee.ImageCollection(years.map(analyseTimeSeries));

//vizualize the results
Map.addLayer(ee.Image(changeData.sum()).gt(0),{min:0,max:1,palette:"white,red"},"change")

question 4: analyse the timeseries using the code below

// select Cambodia
var kh = ee.FeatureCollection("projects/servir-mekong/admin/KHM_adm0");

// Define the chart and print it to the console.
var chart =
    ui.Chart.image
        .series({
          imageCollection: changeData,
          region: kh,
          reducer: ee.Reducer.sum(),
          scale: 300,
          xProperty: 'system:time_start'
        })
        .setSeriesNames(['forest cropland change'])
        .setOptions({
          title: 'Date',
          hAxis: {title: 'Date', titleTextStyle: {italic: false, bold: true}},
          vAxis: {
            title: 'change pixel area',
            titleTextStyle: {italic: false, bold: true}
          },
          lineWidth: 5,
          colors: ['e37d05'],
          curveType: 'function'
        });
           
print(chart);

Question 5: analyse the forest into rubber conversions

Leave a Reply