[GIS] Extracting land cover type in Google Earth Engine

google-earth-engineland-coverremote sensing

I have a question related to Drawing polygon and extracting land cover inside using Google Earth Engine?

I'm trying to work out how to calculate habitat type area from within a specific polygon in google earth engine using Copernicus data. I can do both of these tasks, just not together.

var s1 = ee.ImageCollection("COPERNICUS/S1_GRD"),
S2 = ee.ImageCollection("COPERNICUS/S2"),
fc = ee.FeatureCollection("ft:1w_ciwxR9FKm0rzMH8oJ3MdyE-1U15PfiOFlGW5Ib"),
fc2 = ee.FeatureCollection("ft:18Xvf7jG2EI4mJMwj0oLV2u-05bAPiwJDaxSRy2ep");
//Set a point of interest 
var aoi = fc; 
//Set bands of interest
var bands = ['B2', 'B3', 'B4','B8', 'B11', 'B12'];

//Import and filter Sentinel 2 collection
var S2 = ee.ImageCollection('COPERNICUS/S2')
.filterDate('2016-07-01', '2016-08-01')
.filterBounds(aoi)
print(S2);
var image = S2.mosaic();

Map.addLayer(S2, {'bands': 'B12,B8,B4','min': 0,'max': 4000}, 'Sentinel 2A         SWIR,NIT,R', 0);
var training = image.sampleRegions(fc2, ["info"], 30);
var classifier = ee.Classifier.cart()
.train(training, "info", image.bandNames());
var out = image.classify(classifier);
Map.addLayer(out, {palette: [
'ff0000',// cleared red
'ffcc66',// cultivated
'387242',// forest 
'99ff33',// grass 
'e0e0d1',// rock 
'e0e0d1'// rock grass
], min:1, max:6});

// Create a geometry representing an export region.
var geometry =         ee.Geometry.Rectangle([36.977296602,-15.364411987,37.057018981,-15.447436229]);

Map.addLayer(ee.Image().paint(fc, 1, 3));
var fc = fc2;
Map.addLayer(fc2);

//Create a band for each veg type
var class1 = out.eq(1).select([0],['cleared']);
var class2 = out.eq(2).select([0],['cultivated']);
var class3 = out.eq(3).select([0],['forest']);
var class4 = out.eq(4).select([0],['grass']);
var class5 = out.eq(5).select([0],['rock']);
var class6 = out.eq(6).select([0],['rockgrass']);
// Concatanate the bands into a single image
var total = ee.Image.cat([class1,class2,class3,class4,class5,class6]);

// Extract the landcover band
var landcover = image.select('landcover');

 // Clip the image to the polygon geometry
 var landcover_roi = landcover.clip(geometry);

 //Calculate the total area of each veg type in meters^2
 var count = total.multiply(ee.Image.pixelArea());
 print(total);
 print(count);

 var area = count.reduceRegion(ee.Reducer.sum(), geometry, 30, null, null,        false, 1e10, 1)
print(area);
var cleared = ee.Number(area.get('cleared'));



Export.image.toDrive({ 
image: out,
description: 'imageToDriveDeforestation',
scale: 30,
region: geometry
 });

Best Answer

Here are two ways of doing this. The first is your method of masking with some simplified code. The second is using a grouped reducer:

var s1 = ee.ImageCollection("COPERNICUS/S1_GRD"),
S2 = ee.ImageCollection("COPERNICUS/S2"),
fc = ee.FeatureCollection("ft:1w_ciwxR9FKm0rzMH8oJ3MdyE-1U15PfiOFlGW5Ib"),
fc2 = ee.FeatureCollection("ft:18Xvf7jG2EI4mJMwj0oLV2u-05bAPiwJDaxSRy2ep");

var aoi = fc; 

var bands = ['B2', 'B3', 'B4', 'B8', 'B11', 'B12'];

var S2 = ee.ImageCollection('COPERNICUS/S2')
  .filterDate('2016-07-01', '2016-08-01')
  .filterBounds(aoi);

// You may want to use median here if there's overlapping imagery.
var image = S2.mosaic();

var geometry = ee.Geometry.Rectangle([36.977296602,-15.364411987,37.057018981,-15.447436229]);
Map.centerObject(geometry);

var landcover_roi = image.clip(geometry);

Map.addLayer(landcover_roi, {'bands': 'B12,B8,B4','min': 0,'max': 4000}, 'Sentinel 2A SWIR,NIT,R', 0);

var training = landcover_roi.sampleRegions(fc2, ["info"], 30);
var classifier = ee.Classifier.cart()
    .train(training, "info", image.bandNames());
var out = landcover_roi.classify(classifier);
Map.addLayer(out, {palette: [
  'ff0000',// cleared red
  'ffcc66',// cultivated
  '387242',// forest 
  '99ff33',// grass 
  'e0e0d1',// rock 
  'e0e0d1'// rock grass
], min:1, max:6});

Map.addLayer(ee.Image().paint(fc, 1, 3));
var fc = fc2;
Map.addLayer(fc2);

var names = ['cleared', 'cultivated1', 'cultivated2', 'grass', 'rock', 'rockgrass'];
var total = out.eq([1, 2, 3, 4, 5, 6]).rename(names);

var count = total.multiply(ee.Image.pixelArea());

// The grouped reducer ignores the weights.  Unweight here for comparison.
var area = count.reduceRegion(ee.Reducer.sum().unweighted(), geometry, 30);
print(area);

var stats = ee.Image.pixelArea().addBands(out).reduceRegion({
  reducer: ee.Reducer.sum().group(1), 
  geometry: geometry, 
  scale: 30,
});
print(stats);
Related Question