├── Chlorophylla_conc_GEE.js ├── Damage_Assessment_Script.js ├── Extract_MODIS_FireCCI_data_from_GEE.js ├── Extracting_Forest_NonForestData_from_GEE.js ├── Fire_Hotspot_Mapping_using_FIRMS_Sentinel_2.js ├── Flood_Mapping_S1_Affected_Agri_Pop_Export.js ├── GEE_S1_GRD_Script_ShahriarRahman.js ├── GEE_classification_script.js ├── LST_estimation_graph_GEE.js ├── README.md ├── Rainfall_Estimation_Raingraph_GEE.js ├── Reducing_L8_Collection_GEE.js └── Yearly_Average_ET_Calculation_GEE.js /Chlorophylla_conc_GEE.js: -------------------------------------------------------------------------------- 1 | /* 2 | Title: Calculate Chlorophyll-a Concentration in GEE and Export Chlorphyll-a mean images 3 | Author: Shahriar Rahman 4 | Email: shahriar.env12@gmail.com 5 | Acknowledgements: Google Earth Engine 6 | */ 7 | 8 | //Chlorophyll-a image data from 1 Jan - 31 De 2020 from Global Change Observation Mission (GCOM) 9 | //JAXA 10 | /* Data CitatioN: Murakami, H. (Jan. 2020). ATBD of GCOM-C chlorophyll-a 11 | concentration algorithm (Version 2). Retrieved from 12 | https://suzaku.eorc.jaxa.jp/GCOM_C/data/ATBD/ver2/V2ATBD_O3AB_Chla_Murakami.pdf 13 | */ 14 | var GCOM_Img = ee.ImageCollection("JAXA/GCOM-C/L3/OCEAN/CHLA/V2") 15 | .filterDate('2020-01-01', '2020-12-31'); 16 | var GCOM = GCOM_Img.mean().multiply(0.0016).log10(); 17 | var geometry = AusOcean.geometry(); 18 | var GCOM_clp = GCOM.clip(geometry); 19 | 20 | //Chart titles 21 | var title = { 22 | title: 'Chlorophyll-a Concentration', 23 | hAxis: {title: 'Time'}, 24 | vAxis: {title: 'mg/m^3'}, 25 | }; 26 | 27 | //Bar chart with CHLA (Chlorophyll-A) & CHLA_QA Flag 28 | var chart = ui.Chart.image.series 29 | (GCOM_Img,geometry, ee.Reducer.mean(), 4639,'system:time_start') 30 | .setOptions(title) 31 | .setChartType('ColumnChart'); 32 | print('Chlorophyll-a Concentration from 1 Jan - 31 Dec 2020'); 33 | print(chart); 34 | 35 | //Export mean Chlorophyll-a (two bands)images to GoogleDrive 36 | Export.image.toDrive({ 37 | image: GCOM_clp, 38 | description: 'GCOM_ChlorA', 39 | region: geometry, 40 | scale: 4639, 41 | crs:'epsg:4326', 42 | maxPixels:4e10, 43 | }); 44 | 45 | //End of script. 46 | //Thank you for watching. 47 | //Please subscribe to my youtube channel. 48 | -------------------------------------------------------------------------------- /Damage_Assessment_Script.js: -------------------------------------------------------------------------------- 1 | /* 2 | Title: Agricultural Damage Assessment Land due to Cyclone Amphan in Khulna District 3 | Email: shahriar.env12@gmail.com 4 | Acknowledgements: UN-SPIDER.org 5 | */ 6 | //Please follow this video after calculating the floodwater extent 7 | //Watch my previous video, Title: "Flood mapping using Sentinel-1 (GRD) in Google Earth Engine (GEE)" 8 | 9 | //Image Collection: MCD12Q1.006 MODIS Land Cover Type Yearly Global 500m (2001-2019) 10 | var landcover = ee.ImageCollection('MODIS/006/MCD12Q1') 11 | .filterDate('2015-01-01',after_end) 12 | .sort('system:index',false) 13 | .select("LC_Type1") 14 | .first() 15 | .clip(geometry); 16 | 17 | //Considering only agricultural land 18 | var mask_crp = landcover 19 | .eq(12) 20 | .or(landcover.eq(14)); 21 | var croparea = landcover 22 | .updateMask(mask_crp); 23 | 24 | //Defining projection 25 | var MODISprojection = landcover.projection(); 26 | 27 | var flooded_reproj = flooded_area 28 | .reproject({ 29 | crs: MODISprojection 30 | }); 31 | 32 | //Clipping agricultural land based on the final flooded area 33 | var Affected_agriculture = flooded_reproj 34 | .updateMask(croparea).rename('affected_agri'); 35 | 36 | //Calculating area of the affected agricultural land in Khulna 37 | var pixel_agri_total = Affected_agriculture 38 | .multiply(ee.Image.pixelArea()); 39 | var agri_pix = pixel_agri_total.reduceRegion({ 40 | reducer: ee.Reducer.sum(), 41 | geometry: geometry, 42 | scale: 500, 43 | maxPixels: 1e9 44 | }); 45 | var affected_agri = ee.Number(agri_pix.get('affected_agri')).divide(10000); 46 | print('Affected Agricultural Area in Khulna (Ha)',affected_agri); 47 | 48 | //Adding and visualising the afffected agricultural land in GEE 49 | //Remember that MCD12Q1 is a 500m spatial resolution product 50 | var agriVis = { 51 | min: 0, 52 | max: 14.0, 53 | palette: ['Yellow'], 54 | }; 55 | Map.addLayer(Affected_agriculture, agriVis, 'Affected Agriculture Land'); 56 | //End of script// 57 | //Please like, share and subscribe for more videos!!! 58 | //Thank you for watching! :) 59 | -------------------------------------------------------------------------------- /Extract_MODIS_FireCCI_data_from_GEE.js: -------------------------------------------------------------------------------- 1 | /* 2 | Title: Extract MODIS Fire_cci Burned Area Pixel Product with it's three bands from GEE 3 | Email: shahriar.env12@gmail.com 4 | Acknowledgements: Google Earth Engine 5 | */ 6 | 7 | var geometry = ee.FeatureCollection('users/shahriar***/KangarooIsland'); // shapefile 8 | var dataset = ee.ImageCollection('ESA/CCI/FireCCI/5_1') 9 | .map(function(image) { 10 | return image.toInt16(); // I set it to Integer 16 bit, but it may vary for different dataset 11 | }); 12 | //Data date 13 | var startYear = 2019; 14 | var endYear = 2020; 15 | var bandNames = ['BurnDate', 'ConfidenceLevel', 'LandCover']; //FireCCI51 v5.1 has these three bands 16 | //loop through monthly data, mosaic each band and export data 17 | for (var year = startYear; year <= endYear; year++) { 18 | for (var month = 1; month <= 12; month++) { 19 | var startDate = ee.Date.fromYMD(year, month, 1); 20 | var endDate = startDate.advance(1, 'month'); 21 | var monthlyCollection = dataset.filterDate(startDate, endDate); 22 | var collectionSize = monthlyCollection.size().getInfo(); 23 | print('Year:', year, 'Month:', month, 'Number of images:', collectionSize); 24 | if (collectionSize > 0) { 25 | var mosaicImage = monthlyCollection.mosaic().clip(geometry); 26 | bandNames.forEach(function(bandName) { 27 | var singleBandImage = mosaicImage.select(bandName); 28 | print('Exporting band:', bandName, 'for', year + '-' + month); 29 | Export.image.toDrive({ 30 | image: singleBandImage, 31 | description: 'FireCCI_' + year + '_' + month + '_' + bandName + '_250m', 32 | folder: 'EarthEngineImages', 33 | fileNamePrefix: 'FireCCI_' + year + '_' + month + '_' + bandName + '_250m', // filename 34 | scale: 250, // spatial resolution: here 250m 35 | region: geometry, 36 | fileFormat: 'GeoTIFF', 37 | maxPixels: 1e13 38 | }); 39 | print('Export task created for ' + year + '-' + month + ' ' + bandName + ' at 250m resolution.'); 40 | }); 41 | } else { 42 | print('No images found for Year:', year, 'Month:', month); 43 | } 44 | } 45 | } 46 | //End of script// 47 | -------------------------------------------------------------------------------- /Extracting_Forest_NonForestData_from_GEE.js: -------------------------------------------------------------------------------- 1 | /* 2 | Title: Extracting forest and non-forest data from FNF4 product of GEE 3 | Author: Shahriar Rahman 4 | Email: shahriar.env12@gmail.com 5 | Acknowledgements: Google Earth Engine 6 | */ 7 | 8 | var geometry = ee.FeatureCollection('users/shahriar***/KangarooIsland'); //your shapefile (here, I have uploaded my zipped shape file as an asset to my GEE code environment 9 | var years = [2017, 2018, 2019, 2020, 2021]; // List of years I am interested (if you need only 2019 to 2021, then chose only three, example: var years = [2019, 2020, 2021] 10 | var dataset = ee.ImageCollection('JAXA/ALOS/PALSAR/YEARLY/FNF4'); // Load the ALOS PALSAR FNF dataset 11 | 12 | // Function to clip and export data for every year individually 13 | years.forEach(function(year) { 14 | var filtered = dataset.filter(ee.Filter.calendarRange(year, year, 'year')); 15 | var collectionSize = filtered.size().getInfo(); 16 | print('Year:', year, 'Number of images:', collectionSize); 17 | if (collectionSize > 0) { 18 | var image = filtered.first(); 19 | if (image && image.bandNames().size().getInfo() > 0) { 20 | var clippedImage = image.clip(geometry); 21 | Export.image.toDrive({ 22 | image: clippedImage, 23 | description: 'ALOS_PALSAR_' + year, 24 | scale: 25, //25m spatial resolution 25 | region: geometry, 26 | fileFormat: 'GeoTIFF', 27 | maxPixels: 1e13 28 | }); 29 | print('Export task created for year ' + year); 30 | } else { 31 | print('Year:', year, 'No valid image or bands available.'); //used it to check whether data for the respective year is present or not 32 | } 33 | } else { 34 | print('No images found for year ' + year); 35 | } 36 | }); 37 | 38 | //End of script. 39 | -------------------------------------------------------------------------------- /Fire_Hotspot_Mapping_using_FIRMS_Sentinel_2.js: -------------------------------------------------------------------------------- 1 | /* 2 | Title: Fire Mapping using FIRMS & Sentinel-2 Data for Australian Black Summer Bushfires (2019-2020) 3 | Email: shahriar.env12@gmail.com 4 | Acknowledgements: GEE 5 | */ 6 | 7 | //Defining administrative boundary 8 | var NSW = ee.FeatureCollection("FAO/GAUL/2015/level1") 9 | .filter(ee.Filter.eq("ADM1_NAME","New South Wales")); 10 | 11 | //Import and filter FIRMS fire hotspot data 12 | var FIRMS = ee.ImageCollection("FIRMS") 13 | .filterBounds(NSW).filterDate("2019-10-01","2020-02-15"); 14 | 15 | //Import and filter Sentinel-2 dataset 16 | var S2 = ee.ImageCollection("COPERNICUS/S2") 17 | .filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE', 10)) 18 | .filterBounds(NSW).filterDate("2019-10-01","2020-02-15"); 19 | 20 | //Setting map centre with zoom level 8 21 | Map.centerObject(NSW, 8); 22 | 23 | //Create and add a true colour composite layer of Sentinel-2 images (median value) 24 | Map.addLayer(S2.median(),{min:0,max:5000,bands:["B4", "B3", "B2"]},"True Colour Composite"); 25 | 26 | //Add FIRMS fire hotspot layer (brightness temperature in Kelvin) 27 | Map.addLayer(FIRMS.max(), {min:300, max:509.29, bands:"T21", palette:"yellow, orange, red"}, "Brightness Temperature (K)"); 28 | 29 | //End of script// 30 | //Please like, share and subscribe for more videos!!! 31 | //Thank you for watching! 32 | //Happy New Year 2023!!! :) 33 | -------------------------------------------------------------------------------- /Flood_Mapping_S1_Affected_Agri_Pop_Export.js: -------------------------------------------------------------------------------- 1 | /* 2 | Title: Flood Mapping in Khulna District due to Cyclone Amphan (16 May - 21 May 2020) 3 | Email: shahriar.env12@gmail.com 4 | Acknowledgements: UN-SPIDER.org 5 | */ 6 | 7 | // Before and After Flood Dates 8 | var before_start = '2020-05-01'; 9 | var before_end = '2020-05-15'; 10 | var after_start = '2020-05-16'; 11 | var after_end = '2020-05-31'; 12 | 13 | //Add this line to get GSW 14 | var GSW = ee.Image("JRC/GSW1_3/GlobalSurfaceWater"); 15 | 16 | //Add this line to get HydroSHEDS DEM 17 | var Hydro_DEM = ee.Image('WWF/HydroSHEDS/03VFDEM'); 18 | 19 | //FAO Global Administrative Unit Layers 2015 20 | var admin = ee.FeatureCollection("FAO/GAUL_SIMPLIFIED_500m/2015/level1"); 21 | 22 | //Khulna District of Bangladesh 23 | var Khulna = admin.filter(ee.Filter.eq('ADM1_NAME', 'Khulna')); 24 | var geometry = Khulna.geometry(); 25 | print('Khulna District Area (Ha)',geometry.area().divide(10000)); 26 | Map.addLayer(geometry, {color: 'silver'}, 'Khulna'); 27 | 28 | // Collection of S1 GRD images (only one polarisation 'VH' is used) 29 | var collection= ee.ImageCollection('COPERNICUS/S1_GRD') 30 | .filter(ee.Filter.eq('instrumentMode','IW')) 31 | .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH')) 32 | .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV')) 33 | .filter(ee.Filter.eq('orbitProperties_pass', 'DESCENDING')) 34 | .filter(ee.Filter.eq('resolution_meters',10)) 35 | .filterBounds(geometry) 36 | .select(['VH']); 37 | 38 | print(collection.first()); //to get the additional parameters of the collection of Sentinel-1 images 39 | 40 | //Filtering collection of images based on before and after flood 41 | var before_collection = collection.filter(ee.Filter.date(before_start, before_end)); 42 | var after_collection = collection.filter(ee.Filter.date(after_start, after_end)); 43 | 44 | //Clipping before and after images based on the Khulna District 45 | var before = before_collection.mosaic().clip(geometry); 46 | var after = after_collection.mosaic().clip(geometry); 47 | 48 | //Add layers of before and after flood images 49 | Map.addLayer(before, {min:-25,max:0},'Before Flood', false); 50 | Map.addLayer(after, {min:-25,max:0},'After Flood', false); 51 | 52 | //Reducing radar speckles using smooting technique 53 | var smoothing_radius = 25; 54 | var before_filtered = before.focal_mean(smoothing_radius, 'square', 'meters'); 55 | var after_filtered = after.focal_mean(smoothing_radius, 'square', 'meters'); 56 | Map.addLayer(before_filtered, {min:-25,max:0},'Before Flood (Filtered)', false); 57 | Map.addLayer(after_filtered, {min:-25,max:0},'After Flood (Filtered)', false); 58 | 59 | //Calculating preliminary floodwater extent 60 | var difference = after_filtered.divide(before_filtered); 61 | var diff_threshold = 1.25; 62 | var flooded_area = difference.gt(diff_threshold).rename('flood_water').selfMask(); 63 | Map.addLayer(flooded_area, {min:0,max:1, palette: ['orange']}, 'Floodwater Extent', false); 64 | 65 | //Masking the perennial water 66 | var perennialWater = GSW.select('seasonality').gte(8).clip(geometry); 67 | var flooded_area = flooded_area.where(perennialWater,0).selfMask(); 68 | Map.addLayer(perennialWater.selfMask(), {min:0, max:1, palette: ['Aqua']}, 'Perennial Water', false); 69 | 70 | //Masking areas greater than 0.05 percent slope 71 | //Khulna is a low-lying area, use the slope threshold based on the local geography 72 | var slope_threshold = 0.05; 73 | var terrain = ee.Algorithms.Terrain(Hydro_DEM); //Hydrosheds void-filled DEM used 74 | var slope = terrain.select('slope'); 75 | var flooded_area = flooded_area.updateMask(slope.lt(slope_threshold)); 76 | //Layer of the elevated area 77 | Map.addLayer(slope.gte(slope_threshold).selfMask(), {min:0, max:1, palette: ['Teal']}, 'Elevated Area', false); 78 | 79 | //Remove unclustered pixels 80 | //Clustered pixel threshold and connected pixel counts should be selected based on local contexts and knowledge 81 | var clustered_pix_threshold = 5; 82 | var clustered = flooded_area.connectedPixelCount(15); 83 | var flooded_area = flooded_area.updateMask(clustered.gt(clustered_pix_threshold)); 84 | //Layer of the final floodwater extent 85 | Map.addLayer(flooded_area, {min:0,max:1, palette: ['Red']}, 'Final Floodwater extent', false); 86 | 87 | //Calculate total flooded area (in Hectares) of Khulna District after Cyclone Amphan 88 | var stats = flooded_area.multiply(ee.Image.pixelArea()).reduceRegion({ 89 | reducer: ee.Reducer.sum(), 90 | geometry: geometry, 91 | scale: 30, 92 | maxPixels: 1e10}); 93 | var floodedArea = ee.Number(stats.get('flood_water')).divide(10000); 94 | print('Total Flooded Area in Khulna (Ha)',floodedArea); 95 | 96 | // Export the image 97 | Export.image.toDrive({ 98 | image: flooded_area, 99 | description: 'FinalFloodwaterExtent', 100 | scale: 30, 101 | region: geometry, 102 | crs: 'epsg:4326', 103 | maxPixels: 1e9}); 104 | //****End of Script [Flood mapping using Sentinel-1 in Google Earth Engine] ****// 105 | //////////////////////////////////////////////////////////////////////////////////////////// 106 | /* 107 | Title: Agricultural Damage Assessment Land due to Cyclone Amphan in Khulna District 108 | Email: shahriar.env12@gmail.com 109 | Acknowledgements: UN-SPIDER.org 110 | */ 111 | //Please follow this video after calculating the floodwater extent 112 | //Watch my previous video, Title: "Flood mapping using Sentinel-1 (GRD) in Google Earth Engine (GEE)" 113 | 114 | //Image Collection: MCD12Q1.006 MODIS Land Cover Type Yearly Global 500m (2001-2019) 115 | var landcover = ee.ImageCollection('MODIS/006/MCD12Q1') 116 | .filterDate('2015-01-01',after_end) 117 | .sort('system:index',false) 118 | .select("LC_Type1") 119 | .first() 120 | .clip(geometry); 121 | 122 | //Considering only agricultural land 123 | var mask_crp = landcover 124 | .eq(12) 125 | .or(landcover.eq(14)); 126 | var croparea = landcover 127 | .updateMask(mask_crp); 128 | 129 | //Defining projection 130 | var MODISprojection = landcover.projection(); 131 | 132 | var flooded_reproj = flooded_area 133 | .reproject({ 134 | crs: MODISprojection 135 | }); 136 | 137 | //Clipping agricultural land based on the final flooded area 138 | var Affected_agriculture = flooded_reproj 139 | .updateMask(croparea).rename('affected_agri'); 140 | 141 | //Calculating area of the affected agricultural land in Khulna 142 | var pixel_agri_total = Affected_agriculture 143 | .multiply(ee.Image.pixelArea()); 144 | var agri_pix = pixel_agri_total.reduceRegion({ 145 | reducer: ee.Reducer.sum(), 146 | geometry: geometry, 147 | scale: 500, 148 | maxPixels: 1e9 149 | }); 150 | var affected_agri = ee.Number(agri_pix.get('affected_agri')).divide(10000); 151 | print('Affected Agricultural Area in Khulna (Ha)',affected_agri); 152 | 153 | //Adding and visualising the afffected agricultural land in GEE 154 | //MCD12Q1 is a 500m spatial resolution product 155 | var agriVis = { 156 | min: 0, 157 | max: 14.0, 158 | palette: ['Yellow'], 159 | }; 160 | Map.addLayer(Affected_agriculture, agriVis, 'Affected Agriculture Land'); 161 | 162 | Export.image.toDrive({ 163 | image: Affected_agriculture, 164 | description: 'AffectedAgriculturalLand', 165 | scale: 30, 166 | region: geometry, 167 | crs: 'epsg:4326', 168 | maxPixels: 1e9}); 169 | //End of script// 170 | //Please like, share and subscribe for more videos!!! 171 | //Thank you for watching! :) 172 | 173 | // JRC Global Human Settlement Popluation Density layer (250m resolution) 174 | var pop_count = ee.Image('JRC/GHSL/P2016/POP_GPW_GLOBE_V1/2015').clip(geometry); 175 | 176 | // Change projection 177 | var GHSLprojection = pop_count.projection(); 178 | 179 | // Floodwater extent to GHSL reprojection 180 | var flooded_reproj = flooded_area 181 | .reproject({ 182 | crs: GHSLprojection 183 | }); 184 | 185 | // Creating layer of affected population 186 | var pop_affected = pop_count 187 | .updateMask(flooded_reproj) 188 | .updateMask(pop_count).rename('pop_affected'); 189 | 190 | //Count the pixel values of affected population 191 | var stats = pop_affected.reduceRegion({ 192 | reducer: ee.Reducer.sum(), 193 | geometry: geometry, 194 | scale: 250, 195 | maxPixels:1e9 196 | }); 197 | 198 | // get number of exposed people as integer 199 | var number_pp_affected = stats.getNumber('pop_affected').round(); 200 | print('Affected number of population',number_pp_affected); 201 | 202 | 203 | var popAffected = { 204 | min: 0, 205 | max: 14.0, 206 | palette: ['Magenta'], 207 | }; 208 | Map.addLayer(pop_affected, popAffected, 'Affected Population'); 209 | 210 | //Export image 211 | Export.image.toDrive({ 212 | image: pop_affected, 213 | description: 'affected_population', 214 | scale: 30, 215 | region: geometry, 216 | crs: 'epsg:4326', 217 | maxPixels: 1e9}); 218 | 219 | // End of script!!! 220 | //Thank you for watching! 221 | //Please subscribe to my youtube channel. 222 | //Please find the revised script in the description box. Take care :) 223 | -------------------------------------------------------------------------------- /GEE_S1_GRD_Script_ShahriarRahman.js: -------------------------------------------------------------------------------- 1 | /* 2 | Title: Flood Mapping at Khulna District due to Cyclone Amphan (16 May - 21 May 2020) 3 | Email: shahriar.env12@gmail.com 4 | Acknowledgements: UN-SPIDER.org 5 | */ 6 | 7 | // Before and After Flood Dates 8 | var before_start = '2020-05-01'; 9 | var before_end = '2020-05-15'; 10 | var after_start = '2020-05-16'; 11 | var after_end = '2020-05-31'; 12 | 13 | //FAO Global Administrative Unit Layers 2015 14 | var admin = ee.FeatureCollection("FAO/GAUL_SIMPLIFIED_500m/2015/level1"); 15 | 16 | //Khulna District of Bangladesh 17 | var Khulna = admin.filter(ee.Filter.eq('ADM1_NAME', 'Khulna')); 18 | var geometry = Khulna.geometry(); 19 | print('Khulna District Area (Ha)',geometry.area().divide(10000)); 20 | Map.addLayer(geometry, {color: 'silver'}, 'Khulna'); 21 | 22 | // Collection of S1 GRD images (only one polarisation 'VH' is used) 23 | var collection= ee.ImageCollection('COPERNICUS/S1_GRD') 24 | .filter(ee.Filter.eq('instrumentMode','IW')) 25 | .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH')) 26 | .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV')) 27 | .filter(ee.Filter.eq('orbitProperties_pass', 'DESCENDING')) 28 | .filter(ee.Filter.eq('resolution_meters',10)) 29 | .filterBounds(geometry) 30 | .select(['VH']); 31 | 32 | print(collection.first()); //to get the additional parameters of the collection of Sentinel-1 images 33 | 34 | //Filtering collection of images based on before and after flood 35 | var before_collection = collection.filter(ee.Filter.date(before_start, before_end)); 36 | var after_collection = collection.filter(ee.Filter.date(after_start, after_end)); 37 | 38 | //Clipping before and after images based on the Khulna District 39 | var before = before_collection.mosaic().clip(geometry); 40 | var after = after_collection.mosaic().clip(geometry); 41 | 42 | //Add layers of before and after flood images 43 | Map.addLayer(before, {min:-25,max:0},'Before Flood', false); 44 | Map.addLayer(after, {min:-25,max:0},'After Flood', false); 45 | 46 | //Reducing radar speckles using smoothing technique 47 | var smoothing_radius = 25; 48 | var before_filtered = before.focal_mean(smoothing_radius, 'square', 'meters'); 49 | var after_filtered = after.focal_mean(smoothing_radius, 'square', 'meters'); 50 | Map.addLayer(before_filtered, {min:-25,max:0},'Before Flood (Filtered)', false); 51 | Map.addLayer(after_filtered, {min:-25,max:0},'After Flood (Filtered)', false); 52 | 53 | //Calculating preliminary floodwater extent 54 | var difference = after_filtered.divide(before_filtered); 55 | var diff_threshold = 1.25; 56 | var flooded_area = difference.gt(diff_threshold).rename('flood_water').selfMask(); 57 | Map.addLayer(flooded_area, {min:0,max:1, palette: ['orange']}, 'Floodwater Extent', false); 58 | 59 | //Masking the perennial water 60 | var perennialWater = GSW.select('seasonality').gte(8).clip(geometry); 61 | var flooded_area = flooded_area.where(perennialWater,0).selfMask(); 62 | Map.addLayer(perennialWater.selfMask(), {min:0, max:1, palette: ['Aqua']}, 'Perennial Water', false); 63 | 64 | //Masking areas greater than 0.05 percent slope 65 | //Khulna is a low-lying area, use the slope threshold based on the local geography 66 | var slope_threshold = 0.05; 67 | var terrain = ee.Algorithms.Terrain(Hydro_DEM); //Hydrosheds void-filled DEM used 68 | var slope = terrain.select('slope'); 69 | var flooded_area = flooded_area.updateMask(slope.lt(slope_threshold)); 70 | //Layer of the elevated area 71 | Map.addLayer(slope.gte(slope_threshold).selfMask(), {min:0, max:1, palette: ['Teal']}, 'Elevated Area', false); 72 | 73 | //Remove unclustered pixels 74 | //Clustered pixel threshold and connected pixel counts should be selected based on local contexts and knowledge 75 | var clustered_pix_threshold = 5; 76 | var clustered = flooded_area.connectedPixelCount(15); 77 | var flooded_area = flooded_area.updateMask(clustered.gt(clustered_pix_threshold)); 78 | //Layer of the final floodwater extent 79 | Map.addLayer(flooded_area, {min:0,max:1, palette: ['Red']}, 'Final Floodwater extent', false); 80 | 81 | //Calculate total flooded area (in Hectares) of Khulna District after Cyclone Amphan 82 | var stats = flooded_area.multiply(ee.Image.pixelArea()).reduceRegion({ 83 | reducer: ee.Reducer.sum(), 84 | geometry: geometry, 85 | scale: 30, 86 | maxPixels: 1e10}); 87 | var floodedArea = ee.Number(stats.get('flood_water')).divide(10000); 88 | print('Total Flooded Area in Khulna (Ha)',floodedArea); 89 | 90 | //End of script// 91 | -------------------------------------------------------------------------------- /GEE_classification_script.js: -------------------------------------------------------------------------------- 1 | /* Title: Land Cover Classification using CART Regression Tree in GEE 2 | Script and Demo: Shahriar Rahman 3 | Please like, share and subscribe to my youtube channel!!! 4 | Email: shahriar.env12@gmail.com 5 | Courtesy: Google Earth Engine (GEE), GEARS-LAB. 6 | */ 7 | 8 | // Image selection 9 | var image = imageCollection 10 | .filterDate('2021-01-01','2021-05-29') 11 | .filterBounds(ROI) 12 | .sort('CLOUD_COVER') // sort the collection by cloud cover 13 | .first(); // Now lets select the first image out of this collection 14 | print(image); 15 | 16 | // Clipping the image data based on the bounding box 17 | var image = image.clip(Bounding_Box); 18 | 19 | // Centres the map view on a given object 20 | Map.centerObject(Bounding_Box, 13); //zoom level: 13 21 | 22 | // Adding a given EE object to the map as a layer 23 | Map.addLayer(image,{bands:['B4','B3','B2'], min: 0, max:0.3},'True Color Image', false); 24 | 25 | // Merge features into one FeatureCollection 26 | var trainingfc= Urban.merge(Water).merge(Vegetation).merge(Barren); 27 | 28 | // Band selection for machine learning algorithm 29 | var bands = ['B1','B2','B3','B4','B5','B6','B7']; 30 | 31 | // Sample the reflectance values for each training point 32 | var training= image.select(bands).sampleRegions({ 33 | collection: trainingfc, 34 | properties: ['landcover'], 35 | scale: 30 // 36 | }); 37 | print (training); 38 | 39 | // Splitting the data using random sampling technique 40 | var withRandom = training.randomColumn('random'); 41 | 42 | //Here, training will be on 70%, and the rest is for testing 43 | var split = 0.7; 44 | var trainingPartition = withRandom.filter(ee.Filter.lt('random', split)); 45 | var testingPartition = withRandom.filter(ee.Filter.gte('random', split)); 46 | 47 | // Setting up the model (here, CART Regression Tree) 48 | var classifier = ee.Classifier.smileCart().train({ 49 | features: trainingPartition, 50 | classProperty: 'landcover', 51 | inputProperties: bands 52 | }); 53 | 54 | // Run the classification 55 | var classified = image.select(bands).classify(classifier); 56 | 57 | // Display the classification map 58 | Map.addLayer(classified,lc_cls,'classification'); 59 | 60 | // Generating a confusion matrix considering resubstituion error matrix 61 | var trainAccuracy = classifier.confusionMatrix(); 62 | print('Resubstitution error matrix: ', trainAccuracy); 63 | print('Overall training accuracy: ', trainAccuracy.accuracy()); 64 | 65 | // Testing data 66 | print ('Data before classification',testingPartition); 67 | 68 | // Classifying the testing data 69 | var test = testingPartition.classify(classifier); 70 | 71 | // Results after run... 72 | print (' The classified set"',test); 73 | 74 | // Print the confusion matrix. 75 | var confusionMatrix = test.errorMatrix('landcover', 'classification'); 76 | print('Confusion Matrix', confusionMatrix); 77 | print('Validation accuracy: ',confusionMatrix.accuracy()); 78 | 79 | // Export the classified image to Google Drive 80 | Export.image.toDrive({ 81 | image: classified, 82 | description:"LULC_WesternSydney", 83 | scale: 30, 84 | region:Bounding_Box, 85 | maxPixels:3e10 86 | }); 87 | // End of the Script!!! 88 | -------------------------------------------------------------------------------- /LST_estimation_graph_GEE.js: -------------------------------------------------------------------------------- 1 | /* 2 | Title: Mean Temperature Calculation & Temperature Graph Generation in GEE 3 | Author: Shahriar Rahman 4 | Acknowledgements: Google Earth Engine 5 | */ 6 | //FAO Global Administrative Unit Layers 2015 7 | var admin = ee.FeatureCollection("FAO/GAUL_SIMPLIFIED_500m/2015/level1"); 8 | //Khulna District of Bangladesh 9 | var Khulna = admin.filter(ee.Filter.eq('ADM1_NAME', 'Khulna')); 10 | var geometry = Khulna.geometry(); 11 | 12 | //MODIS Day-time temperature 13 | var modisLSTD = MODIS_LST.select('LST_Day_1km') 14 | .filterDate('2020-04-01', '2020-06-30'); //selected date 15 | 16 | //Converting Temperature from Kelvin to Celsius 17 | modisLSTD = modisLSTD.map(function(image){ 18 | return image.multiply(0.02).subtract(273.15).copyProperties(image, ['system:time_start']); 19 | }); 20 | 21 | //Chart titles 22 | var title = { 23 | title: 'Day Temperature', 24 | hAxis: {title: 'Time'}, 25 | vAxis: {title: 'Temperature C'}, 26 | }; 27 | 28 | //Chart for day time temperature 29 | var chart = ui.Chart.image.series 30 | (modisLSTD,geometry, ee.Reducer.mean(), 1000,'system:time_start') 31 | .setOptions(title) 32 | .setChartType('ColumnChart'); 33 | print('Day Surface Temperature in Celsius'); 34 | print(chart); 35 | 36 | //Add LST layer in GEE 37 | var landSurfaceTemperatureVis = { 38 | min: -10, 39 | max: 40.0, 40 | palette: [ 41 | '040274', '040281', '0502a3', '0502b8', '0502ce', '0502e6', 42 | '0602ff', '235cb1', '307ef3', '269db1', '30c8e2', '32d3ef', 43 | '3be285', '3ff38f', '86e26f', '3ae237', 'b5e22e', 'd6e21f', 44 | 'fff705', 'ffd611', 'ffb613', 'ff8b13', 'ff6e08', 'ff500d', 45 | 'ff0000', 'de0101', 'c21301', 'a71001', '911003' 46 | ], 47 | }; 48 | Map.addLayer(modisLSTD.select('LST_Day_1km').mean().clip(geometry), landSurfaceTemperatureVis,'Land Surface Temperature (Day)'); 49 | 50 | //Export the mean LST image in 30m spatial resolution 51 | Export.image.toDrive({ 52 | image: modisLSTD.mean().clip(geometry), 53 | description: 'Land_Surface_Temp_Day', 54 | region: geometry, 55 | scale: 30, 56 | crs:'epsg:4326', 57 | maxPixels:1e10, 58 | }); 59 | 60 | //End of script// 61 | //Please like, share and subscribe to my youtube channel. 62 | //Be safe and take care :) 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GEE Scripts 2 | All the Google Earth Engine scripts I wrote and shared with the scientific community. Please like, share and subscribe to my youtube channel (https://www.youtube.com/channel/UCvH8JoH8zMLPjyT2S0T8s9g). 3 | -------------------------------------------------------------------------------- /Rainfall_Estimation_Raingraph_GEE.js: -------------------------------------------------------------------------------- 1 | /* 2 | Title: Calculating mean rainfall during cyclone Amphan 3 | Author: Shahriar Rahman 4 | Email: shahriar.env12@gmail.com 5 | Acknowledgements: Google Earth Engine 6 | */ 7 | 8 | //Load CHIRPS rainfall collection 9 | var CHIRPS= ee.ImageCollection('UCSB-CHG/CHIRPS/PENTAD'); 10 | 11 | //FAO Global Administrative Unit Layers 2015 12 | var admin = ee.FeatureCollection("FAO/GAUL_SIMPLIFIED_500m/2015/level1"); 13 | 14 | //Khulna District of Bangladesh 15 | var Khulna = admin.filter(ee.Filter.eq('ADM1_NAME', 'Khulna')); 16 | var geometry = Khulna.geometry(); 17 | 18 | //Define the rainfall date range (Year 2020) 19 | var rainfall = CHIRPS.filterDate('2020-01-01','2020-12-31'); 20 | 21 | //Plot full year (2020) rainfall data for Khulna district of Bangladesh 22 | var total_rnfl = ui.Chart.image.series(rainfall, geometry, ee.Reducer.mean(),1000, 'system:time_start').setOptions({ 23 | title: 'Rainfall Time Series of Year 2020', 24 | vAxis: {title: 'mm/pentad'}, }); 25 | print(total_rnfl); 26 | 27 | //Rainfall during Amphan 28 | var rnfl_amphan =CHIRPS.filterDate('2020-05-10','2020-05-30'); //Date from 10 May - 30 May 2020 29 | var rnfl_apr_jun20 = ui.Chart.image.series(rnfl_amphan, geometry, ee.Reducer.mean(),1000, 'system:time_start').setOptions({ 30 | title: 'Rainfall (10 May 2020 - 30 May 2020)', 31 | vAxis: {title: 'mm/pentad'}, }); 32 | print(rnfl_apr_jun20); 33 | 34 | //Clip the rainfall based on Khulna 35 | var total_rainfall = rnfl_amphan.mean().clip(geometry); 36 | 37 | //Mean rainfall during Amphan 38 | //Defining the colour palette 39 | var mean_rnfl_amphan = rnfl_amphan.mean().clip(geometry).rename('mean_rnfl'); 40 | Map.addLayer(mean_rnfl_amphan, {min: 0, max: 40, 41 | palette:['green','orange','red']}, 'Mean Rainfall during Amphan'); 42 | 43 | // Export the image to your google drive 44 | Export.image.toDrive({ 45 | image: mean_rnfl_amphan, 46 | description: 'mean_rnfl', 47 | scale: 250, //change the spatial resolution according to your need 48 | region: geometry, 49 | maxPixels: 1e10}); 50 | 51 | //End of script! 52 | //Please like, share and subscribe to my youtube channel. 53 | //Be safe and stay at home. :) 54 | -------------------------------------------------------------------------------- /Reducing_L8_Collection_GEE.js: -------------------------------------------------------------------------------- 1 | /* 2 | Title: Reducing Landsat 8 Collection 2 Tier 1 Image Collection on GEE 3 | Email: shahriar.env12@gmail.com 4 | Acknowledgements: GEE 5 | */ 6 | 7 | //Geometry settings 8 | var geometry = ee.Geometry.Point([150.45, -33.63]); //define as per your requirements 9 | //Image Collection: Landsat 8 10 | var dataset_ls = ee.ImageCollection('LANDSAT/LC08/C02/T1') 11 | .filterDate('2020-05-01', '2021-06-01') //date range 1 May 2020 - 1 June 2021 12 | .filterBounds(geometry); //choose geometry as per your requirements 13 | 14 | //Computes a Landsat TOA composite from a collection of Landsat scenes 15 | var dataset = ee.Algorithms.Landsat.simpleComposite({ 16 | collection: dataset_ls, 17 | cloudScoreRange: 10, 18 | asFloat: true 19 | }); 20 | 21 | //Band combination for visualisation 22 | var visualisation = { 23 | bands: ['B4', 'B3', 'B2'], 24 | min: 0.0, 25 | max: 0.3, 26 | }; 27 | 28 | //Setting the map center according to the provided geometry 29 | Map.centerObject(geometry, 11); 30 | 31 | //Adding a layer for the reduced Landsat 8 composite 32 | Map.addLayer(dataset, visualisation, "L8_RGB"); 33 | 34 | //End of script// 35 | //Please like, share and subscribe for more videos!!! 36 | //Thank you for watching! Happy New Year 2023!!! :) 37 | -------------------------------------------------------------------------------- /Yearly_Average_ET_Calculation_GEE.js: -------------------------------------------------------------------------------- 1 | /* 2 | Title: Calculating annual average evapotranspiration using MOD16A2.006 (ET) data 3 | Author: Shahriar Rahman 4 | Email: shahriar.env12@gmail.com 5 | Acknowledgements: Google Earth Engine, Stack Exchange 6 | */ 7 | 8 | //MOD16A2.006 data product settings 9 | //We are using total evapotranspiration data for this video 10 | var MOD16A2 = ee.ImageCollection('MODIS/006/MOD16A2') //Data product MOD16A2.006: Terra Net Evapotranspiration 8-Day Global 500m (has data from 2001-2022) 11 | var start_year = 2001; 12 | var end_year = 2022; 13 | var startdate = ee.Date.fromYMD(start_year,1, 1); 14 | var enddate = ee.Date.fromYMD(end_year + 1, 1, 1); 15 | var years = ee.List.sequence(start_year, end_year); //setting the year bounds (line 11-15) 16 | 17 | //study area settings (change the area as per your requirements) 18 | var admin = ee.FeatureCollection("FAO/GAUL_SIMPLIFIED_500m/2015/level1"); //FAO GAUL 500m: Global Administrative Unit Layers 2015 used 19 | var Khulna = admin.filter(ee.Filter.eq('ADM1_NAME', 'Khulna')); //here I have considered Khulna from Bangladesh, but you can choose the geographic area of your choice 20 | var geometry = Khulna.geometry(); //getting the geometry of the study area 21 | 22 | var ET = MOD16A2.select("ET") //it has four other products, here I am using "ET" or evapotranspiration product 23 | 24 | //function to get yearly evapotranspiration 25 | var yearly_ET = ee.ImageCollection.fromImages( 26 | years.map(function (year) { 27 | var annual = ET 28 | .filter(ee.Filter.calendarRange(year, year, 'year')) 29 | .sum() 30 | .multiply(0.1); 31 | return annual 32 | .set('year', year) 33 | .set('system:time_start', ee.Date.fromYMD(year, 1, 1)); 34 | })); 35 | 36 | //creating bar chart of annual average evapotranspiration for Khulna, Bangladesh from 2001 to 2022 37 | var title = { 38 | title: 'Annual Average Evapotranspiration from 2001-2022 (Khulna, Bangladesh)', 39 | hAxis: {title: 'Year'}, 40 | vAxis: {title: 'ET (mm)'}, 41 | }; 42 | 43 | //chart settings for plotting... 44 | var chart = ui.Chart.image.seriesByRegion({ 45 | imageCollection: yearly_ET, 46 | regions: Khulna, 47 | reducer: ee.Reducer.mean(), 48 | band: 'ET', 49 | scale: 2000, 50 | xProperty: 'system:time_start', 51 | seriesProperty: 'SITE' 52 | }).setOptions(title) 53 | .setChartType('ColumnChart'); //change the chart type as per your requirements 54 | print(chart); 55 | 56 | //map visualisation of ET distribution over Khulna, Bangladesh 57 | var annual_avgET = yearly_ET.mean().clip(Khulna); //yearly average evapotranspiration of Khulna, Bangladesh 58 | var ET_Vis = { 59 | min: 0, 60 | max: 600, //depends on your data range...when we will run the script then you will see why I put it to 600 :) 61 | palette: '152106, 225129, 369b47, 30eb5b, 387242' //you can choose your own colour palette 62 | }; 63 | Map.centerObject(Khulna, 5); 64 | Map.addLayer(annual_avgET, ET_Vis, 'Annual Average ET'); 65 | 66 | //End of script! 67 | //Please like, share and subscribe to my youtube channel (https://www.youtube.com/channel/UCvH8JoH8zMLPjyT2S0T8s9g). 68 | --------------------------------------------------------------------------------