1

I'm trying to detect how many times land type has changed between 2001 and 2018 (inclusively).

For example, suppose a pixel that was:

  1. Forest from 2001 to 2003
  2. Bare ground from 2003 to 2010
  3. Agriculture from 2010 to 2015
  4. City from 2015 to 2018

Since the land use for this pixel changed 3 times, a value of 3 for this pixel would be written to the output image. The resulting image would show which areas changed a lot, and which areas changed less.

I think there must be a function to do this, but I cannot find it.

I've considered writing code that calls subtract. However, if I do that, I'll need to subtract all land types (17 landtype) between each 2 years. Since there are 18 years of data, that works out to 17 X 17 X 18= 5,202 lines of code.

nsw_border is NSW.Australia shapefile (I got it from the Internet)

var dataset = ee.ImageCollection('MODIS/006/MCD12Q1');

var igbpLandCover = dataset.select('LC_Type1');

var multiband = igbpLandCover.toBands().clip(nsw_border);

var onlycity = multiband; // Just change name of variable

var city2001 = onlycity.select(0); 
var city2002 = onlycity.select(1);
var city2003 = onlycity.select(2);
var city2004 = onlycity.select(3);
var city2005 = onlycity.select(4);
var city2006 = onlycity.select(5);
var city2007 = onlycity.select(6);
var city2008 = onlycity.select(7);
var city2009 = onlycity.select(8);
var city2010 = onlycity.select(9);
var city2011 = onlycity.select(10);
var city2012 = onlycity.select(11);
var city2013 = onlycity.select(12);
var city2014 = onlycity.select(13);
var city2015 = onlycity.select(14);
var city2016 = onlycity.select(15);
var city2017 = onlycity.select(16);
var city2018 = onlycity.select(17);


var difer2002_2001 = city2002.subtract(city2001).rename('differ2002_2001');
0

Well you could do it the way you are doing and get the results but instead of using subtract, using neq would be better as it directly gives pixels that are not equal. Additionally, you can shorten the code by iterating through the image collection and calculating difference between two consequent images within the iteration. You can use either iterate or map (among other methods) to achieve this. I prefer map as it does not wait for operation from other iteration to continue but it also means we need to change a few things to get it working.

// convert image collection to list
igbpLandCover = igbpLandCover.toList(dataset.size());
// generate list of indexes from 1st image to 2nd last image as
// we are trying to get difference between two images
var indexes = igbpLandCover.size();
indexes = ee.List.sequence(0,indexes.subtract(2));
// now apply a mapping function that takes an image at index and
// the next index to check if the land covers are same
var changeList = indexes.map(function(index){
  index = ee.Number(index);
  var thisImg = ee.Image(igbpLandCover.get(index));
  var nextImg = ee.Image(igbpLandCover.get(index.add(1)));
  return thisImg.neq(nextImg);
});
// each image in the list now has 0 or 1 value from the neq
// operation which means each change has value 1. So if we
// add this we get the total number of changes. 
changeList = ee.ImageCollection.fromImages(changeList);
var changes = changeList.sum().clip(nsw_border);
Map.addLayer(changes,{min:0, max:17});

If you are not concerned about classes going back to what they were and just want to get unique classes that the pixel has then a countDistinct Reducer should do the trick

var distinct = igbpLandCover.reduce(ee.Reducer.countDistinct()).clip(nsw_border);

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.