//////////////////////////////////////// ///////////// PREPARE IMAGE //////////// //////////////////////////////////////// // Center map on Honduras study area Map.centerObject(honduras_mar); // Establish function for masking clouds from Sentinel-2 image collection function maskS2clouds(image) { var qa = image.select('QA60'); // Bits 10 and 11 are clouds and cirrus, respectively. var cloudBitMask = 1 << 10; var cirrusBitMask = 1 << 11; // Both flags should be set to zero, indicating clear conditions. var mask = qa.bitwiseAnd(cloudBitMask).eq(0) .and(qa.bitwiseAnd(cirrusBitMask).eq(0)); return image.updateMask(mask).divide(10000); } // Load image collection of Sentinel-2 surface reflectance data var sentinel_collection = ee.ImageCollection('COPERNICUS/S2_SR') .filterDate('2020-01-01', '2020-05-31') // Pre-filter to get less cloudy granules. .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20)) .map(maskS2clouds); // Establish variable for visualizing data on screen (true color) var median_vis = { min: 0.0, max: 0.2, bands: ['B4_median', 'B3_median', 'B2_median'], }; // Reduce Sentinel image collection to single image var sentinel_image = sentinel_collection.reduce(ee.Reducer.median()); // Clip Sentinel image to Honduras boundary var honduras_image = sentinel_image.clip(honduras_mar); // Display Honduras image Map.addLayer(honduras_image, median_vis, "Honduras Image"); //////////////////////////////////////// ///////////// FILTER IMAGE ///////////// //////////////////////////////////////// // Create "NDWI" layer to mask out water features var ndwi_layer = honduras_image.normalizedDifference(['B3_median', 'B8_median']); // Mask water out of Sentinel image using NDWI layer var honduras_ndwi = honduras_image.updateMask(ndwi_layer.lte(0.0)); //Map.addLayer(honduras_ndwi, median_vis, 'NDWI mask applied'); // Create "elevation" layer to mask out high-elevation features var srtm = ee.Image('USGS/SRTMGL1_003'); var elevation_layer = srtm.select('elevation'); // Mask high elevations out of Sentinel image using elevation layer var honduras_elevation = honduras_ndwi.updateMask(elevation_layer.lte(20.0)); //Map.addLayer(honduras_elevation, median_vis, 'Elevation mask applied'); // Create "NDMI" layer to mask out non-mangrove candidates var ndmi_layer = honduras_image.normalizedDifference(['B12_median', 'B3_median']); // Mask non-mangrove candidates out of Sentinel image using NDMI layer var honduras_ndmi = honduras_elevation.updateMask(ndmi_layer.lte(0.1)); //Map.addLayer(honduras_ndmi, median_vis, "NDMI mask applied"); //////////////////////////////////////// /////////// CLASSIFY IMAGE ///////////// //////////////////////////////////////// // Designate which spectral bands to include in the classification var bands = ['B8_median', 'B4_median', 'B3_median', 'B2_median']; // Train the classifier using the training points var training = honduras_image.select(bands).sampleRegions({ collection: honduras_training, properties: ['class'], scale: 10 }); // Establish the classifier var classifier = ee.Classifier.smileRandomForest(200) .train({ features: training, classProperty: 'class', inputProperties: bands }); // Classify the image var honduras_classified = honduras_ndmi.select(bands).classify(classifier); // Mask out all non-mangrove pixels from the classified thematic map var honduras_class_mask = honduras_classified.updateMask(honduras_classified.lte(0)); // Display the classified thematic map //Map.addLayer(honduras_class_mask, {palette: ('FF0000')}, 'Preliminary Honduras Mangrove Classification'); //////////////////////////////////////// //////// REFINE CLASSIFICATION ///////// //////////////////////////////////////// // Display Bunting mangrove layer for reference var honduras_bunting_2016 = honduras_bunting.reduceToImage({ properties: ['pxlval'], reducer: ee.Reducer.first() }); //Map.addLayer(honduras_bunting_2016, {palette: ('00FF00')}, 'Bunting 2016'); // Display only the mangrove trainnig points for reference //Map.addLayer(honduras_mang_training, {palette: ('00FF00')}, 'Honduras Mangrove Training Points'); // Make sure that the manual adjustment geometry is of type FeatureCollection var honduras_include = ee.FeatureCollection(honduras_include); // Dissolve the polygons in the Feature Collection, so the overlapping polygons // don't "cancel each other out" var honduras_include = honduras_include.union(); // Clip the classification to the Feature Collection of manual adjustments, and display var honduras_mangroves = honduras_class_mask.clip(honduras_include); Map.addLayer(honduras_mangroves, {palette: ('00FF00')}, 'Honduras MAR Mangroves'); //////////////////////////////////////// //////////// CALCULATE AREA //////////// //////////////////////////////////////// // Calculate mangrove area for Honduras, and print to console var honduras_mangrove_area = honduras_mangroves.reduceRegion({ reducer: ee.Reducer.count(), geometry: honduras_include, scale: 10, maxPixels: 1e9 }); var honduras_mangrove_area = ee.Number(honduras_mangrove_area.get('classification')).divide(10000); var honduras_mangrove_area = ee.Number(honduras_mangrove_area).format(); print('Honduras MAR mangrove area (km2) as of 2020:', honduras_mangrove_area); //////////////////////////////////////// ////////////// EXPORT MAP ////////////// //////////////////////////////////////// // Convert Honduras mangrove raster to polygon var honduras_mangroves_polygon = honduras_mangroves.toInt().reduceToVectors({ geometry: honduras_include, crs: honduras_mangroves.projection(), scale: 10, geometryType: 'polygon', eightConnected: false, maxPixels: 1e9 }); // Export Honduras mangrove polygon to Google Drive //Export.table.toDrive({ // collection: honduras_mangroves_polygon, // description:'honduras_mar_mangroves', // fileFormat: 'KMZ' //}); //////////////////////////////////////// ////////////// VALIDATION ////////////// //////////////////////////////////////// // Generate random points for "mangrove presence" validation, and export to Google Drive // I will generate "mangrove absence" buffer and points in GIS program var honduras_validation_points_presence = ee.FeatureCollection.randomPoints(honduras_mangroves_polygon, 200); //Export.table.toDrive({collection: honduras_validation_points_presence, fileFormat: 'GeoJSON'});