I'd do something like this:
// Landsat 5 TM Raw Image Collection
var lt5 = ee.ImageCollection("LANDSAT/LT5_L1T");
// Filter by date and location (Landsat Path and Row Designation)
var lakeTiticaca_Early = lt5.filterDate('1985-01-01', '1986-01-01')
.filter(ee.Filter.eq('WRS_PATH', 2))
.filter(ee.Filter.eq('WRS_ROW', 71));
// Selecting Images with least cloud cover
var leastCloud = ee.Image(lakeTiticaca_Early.sort('CLOUD_COVER').first());
// Filter by date and location (Landsat Path and Row Designation)
var lakeTiticaca_Later = lt5.filterDate('2011-01-01', '2012-01-01')
.filter(ee.Filter.eq('WRS_PATH', 2))
.filter(ee.Filter.eq('WRS_ROW', 71));
// Selecting Images with least cloud cover
var leastCloud2 = ee.Image(lakeTiticaca_Later.sort('CLOUD_COVER').first());
// Applying MNDWI Function to Least Cloudy Images
var mNDWI_Early = leastCloud.expression(
'(Green - MIR) / (Green + MIR)', {
'Green': leastCloud.select('B2'),
'MIR': leastCloud.select('B5')
});
var mNDWI_Later = leastCloud2.expression(
'(Green - MIR) / (Green + MIR)', {
'Green': leastCloud2.select('B2'),
'MIR': leastCloud2.select('B5')
});
// Creating an image collection from the MNDWI calculated Images
var constant1 = ee.Image(mNDWI_Early).select([0],["mNDWI"]);
Map.addLayer(leastCloud,{bands:["B4","B5","B3"]},"before")
var constant2 = ee.Image(mNDWI_Later).select([0],["mNDWI"]);
Map.addLayer(leastCloud2,{bands:["B4","B5","B3"]},"after")
var dif = constant2.subtract(constant1)
Map.addLayer(dif,{},"dif")
var img1 = leastCloud.addBands(constant1)
var img2 = leastCloud2.addBands(constant2)
var final = ee.Image.cat(img1,img2)
Map.addLayer(final,{},"final")
//* Supervised Image Classification *//
var training = ee.FeatureCollection([water_nochange, water_gain, water_loss, land_nochange]).flatten()
var sample = final.sampleRegions(training, ["class"], 30)
var trained = ee.Classifier.cart().train(sample, "class")
var classified = final.classify(trained)
Map.addLayer(classified,{min:1, max:4, palette:["#b3b3ff","#0000e6", "#ff0000", "#009900"]},"classified")
You can access the feature collections in the following link:
https://code.earthengine.google.com/3f4c2908fcf7c469357b80783f3ef26f
You should mask clouds, use another path/row to include the missing part of the lake, and make more training points. You can also try another classifier like svm, randomForest, etc.
You are filtering year in the correct way. This is how I'd do it:
//Load and filter the Hansen data
var gfc2014 = ee.Image('UMD/hansen/global_forest_change_2015')
.select(['treecover2000','loss','gain','lossyear']);
// list for filter iteration
var years = ee.List.sequence(1, 14)
// turn your scale into a var in case you want to change it
var scale = gfc2014.projection().nominalScale()
//add country districts as a feature collection
var distr = ee.FeatureCollection('ft:1U7sXFHXtxQ--g7XMeXlvPhNXPBcDtPg8Yzr2pvsg', 'geometry');
//look at tree cover, find the area
var treeCover = gfc2014.select(['treecover2000']);
// most recent version of Hansen's data has the treecover2000 layer
// ranging from 0-100. It needs to be divided by 100 if ones wants
// to calculate the areas in ha and not hundreds of ha. If not, the
// layers areaLoss/areaGain are not comparable to the areaCover. Thus
treeCover = treeCover.divide(100); // Thanks to Bruno
var areaCover = treeCover.multiply(ee.Image.pixelArea())
.divide(10000).select([0],["areacover"])
// total loss area
var loss = gfc2014.select(['loss']);
var areaLoss = loss.gt(0).multiply(ee.Image.pixelArea()).multiply(treeCover)
.divide(10000).select([0],["arealoss"]);
// total gain area
var gain = gfc2014.select(['gain'])
var areaGain = gain.gt(0).multiply(ee.Image.pixelArea()).multiply(treeCover)
.divide(10000).select([0],["areagain"]);
// final image
var total = gfc2014.addBands(areaCover)
.addBands(areaLoss)
.addBands(areaGain)
Map.addLayer(total,{},"total")
// Map cover area per feature
var districtSums = areaCover.reduceRegions({
collection: distr,
reducer: ee.Reducer.sum(),
scale: scale,
});
var addVar = function(feature) {
// function to iterate over the sequence of years
var addVarYear = function(year, feat) {
// cast var
year = ee.Number(year).toInt()
feat = ee.Feature(feat)
// actual year to write as property
var actual_year = ee.Number(2000).add(year)
// filter year:
// 1st: get mask
var filtered = total.select("lossyear").eq(year)
// 2nd: apply mask
filtered = total.updateMask(filtered)
// reduce variables over the feature
var reduc = filtered.reduceRegion({
geometry: feature.geometry(),
reducer: ee.Reducer.sum(),
scale: scale,
maxPixels: 1e13
})
// get results
var loss = ee.Number(reduc.get("arealoss"))
var gain = ee.Number(reduc.get("areagain"))
// set names
var nameloss = ee.String("loss_").cat(actual_year)
var namegain = ee.String("gain_").cat(actual_year)
// alternative 1: set property only if change greater than 0
var cond = loss.gt(0).or(gain.gt(0))
return ee.Algorithms.If(cond,
feat.set(nameloss, loss, namegain, gain),
feat)
// alternative 2: always set property
// set properties to the feature
// return feat.set(nameloss, loss, namegain, gain)
}
// iterate over the sequence
var newfeat = ee.Feature(years.iterate(addVarYear, feature))
// return feature with new properties
return newfeat
}
// Map over the FeatureCollection
var areas = districtSums.map(addVar);
Map.addLayer(areas, {}, "areas")
In that script you get 3 fields: loss_{year}, gain_{year}, sum
But if you want better 4 fields: loss, gain, year, sum; change for:
return ee.Algorithms.If(cond,
feat.set("loss", loss, "gain", gain, "year", actual_year),
feat)
You could also compute percentage and set it to the features.
Edit:
Thank to @Bruno_Conte_Leite, who made me reconsider my answer, I have made some updates, the one suggested by Bruno and others.
Scale:
I suggest to keep the original scale of Hansen data.
treeCover:
most recent version of Hansen's data has the treecover2000 layer ranging from 0-100. It needs to be divided by 100 if ones wants to calculate the areas in ha and not hundreds of ha. (Bruno)
areaLoss and areaGain:
Added .multiply(treeCover)
otherwise the area would be of the whole pixel and not of the indicated percentage
maxPixels: I added maxPixels: 1e13
in the reduction
Best Answer
In your case you have just a single part Polygon, I give you a solution for both, single and multi part Polygons: