Methodology
The numbers in this app are simulated. This page documents the method the app implements and the pipeline it is designed to run on β see Data Provenance below for exactly which values are measured and which are generated.
1. Lake detection
Glacial lakes are delineated from Landsat Surface Reflectance imagery using the Modified Normalized Difference Water Index (MNDWI). A 2000β2024 record spans three sensors: Landsat 5 TM and 7 ETM+ for 2000β2012, Landsat 8 OLI from 2013, and Landsat 9 from late 2021. Sentinel-2 MSI (10 m) is used from 2016 onward on the Change Detection page.
Threshold: pixels with MNDWI > 0.2 are classified as water.
2. Hazard scoring
| Factor | Max score | Notes |
|---|---|---|
| Dam type | 40 | Moraine=40, Ice=30, Bedrock=10 |
| Area growth rate | 25 | Capped at 0.05 kmΒ²/yr = 25 pts |
| Downstream slope | 20 | Capped at 35Β° = 20 pts |
| Distance to settlement | 15 | Inverse linear; 0 km = 15 pts, β₯80 km = 0 pts |
Every non-dam component floors at 0: a shrinking lake or a negative slope contributes no hazard points, it never subtracts from the dam-type baseline.
3. Data sources
| Dataset | Provider | Resolution | Use | In shipped data? |
|---|---|---|---|---|
| Landsat 5/7/8/9 SR | USGS / NASA | 30 m | Lake delineation (MNDWI) | No β pipeline only |
| Sentinel-2 MSI | ESA | 10 m | Recent area measurements | No β needs fetch_sentinel.py |
| Copernicus DEM GLO-30 | ESA / Copernicus | 30 m | Downstream slope | No β slopes are simulated |
| ICIMOD GLOF Database | ICIMOD | β | Event catalogue for ML training | Events yes, attributes unverified |
| WorldPop Nepal 2020 | WorldPop / Univ. of Southampton | 100 m | Population exposure | Yes |
| OpenStreetMap | OSM contributors | β | Building footprints | Yes |
4. Data provenance
Which numbers on this site are measured, and which are generated for demonstration:
| Value | Source |
|---|---|
| Lake names, coordinates, basin, district, elevation | Real β published lake inventories |
| Lake area 2000β2024 | Simulated β data/generate_data.py |
| Area growth rate | Simulated β data/generate_data.py |
| Dam type | Simulated β random draw, weighted toward moraine |
| Downstream slope, distance to settlement | Simulated β random draw |
| Hazard score and risk class | Computed from the simulated inputs above |
| Sentinel-2 change detection cache | Derived from the simulated series (data/create_demo_cache.py) |
| GLOF event catalogue | Real events, unverified attribute values; HKH-wide, not Nepal-only |
| ML probabilities and climate projections | Computed from the simulated inputs above |
| Population and building counts | Real β WorldPop 2020 (100 m) and OpenStreetMap |
| Flood corridors | 8 digitised from valley topography; 17 synthetic centroid paths |
Because the hazard inputs are simulated, this site carries no validation against observed GLOF events β a scoring method built on generated slopes and dam types cannot be tested against real outcomes. Validation becomes meaningful once a real inventory is loaded via data/fetch_icimod.py.
5. Google Earth Engine script
/**
* Google Earth Engine Script β Nepal Glacial Lake Detection
* Detects water bodies in the Nepal Himalaya using Landsat 8 SR + SRTM elevation.
*
* Instructions:
* 1. Open https://code.earthengine.google.com/
* 2. Paste this script and click Run.
* 3. The export task will appear in the Tasks panel β click Run to export to Drive.
*/
// ββ 1. Define Nepal bounding box ββββββββββββββββββββββββββββββββββββββββββ
var nepal = ee.Geometry.Rectangle([80.0, 26.3, 88.2, 30.5]);
// ββ 2. Load Landsat 8 Surface Reflectance Collection 2 βββββββββββββββββββ
var l8 = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
.filterBounds(nepal)
.filterDate('2013-01-01', '2024-12-31')
.filter(ee.Filter.lt('CLOUD_COVER', 20))
.select(['SR_B3', 'SR_B6'], ['Green', 'SWIR1']); // bands for MNDWI
// ββ 3. Scale reflectance values βββββββββββββββββββββββββββββββββββββββββββ
function applyScaleFactors(image) {
var opticalBands = image.select(['Green', 'SWIR1']).multiply(0.0000275).add(-0.2);
return image.addBands(opticalBands, null, true);
}
l8 = l8.map(applyScaleFactors);
// ββ 4. Compute MNDWI per image ββββββββββββββββββββββββββββββββββββββββββββ
// MNDWI = (Green - SWIR) / (Green + SWIR)
function computeMNDWI(image) {
var mndwi = image.normalizedDifference(['Green', 'SWIR1']).rename('MNDWI');
return image.addBands(mndwi);
}
l8 = l8.map(computeMNDWI);
// ββ 5. Build annual median composites βββββββββββββββββββββββββββββββββββββ
var years = ee.List.sequence(2013, 2024);
var annualComposites = ee.ImageCollection(years.map(function(year) {
var yearlyMed = l8
.filter(ee.Filter.calendarRange(year, year, 'year'))
.select('MNDWI')
.median()
.set('year', year);
return yearlyMed;
}));
// ββ 6. Create overall median MNDWI composite ββββββββββββββββββββββββββββββ
var mndwiComposite = annualComposites.median().rename('MNDWI');
print('MNDWI composite band info:', mndwiComposite.bandNames());
// ββ 7. Threshold to produce water mask (MNDWI > 0.2) βββββββββββββββββββββ
var waterMask = mndwiComposite.gt(0.2).rename('water');
// ββ 8. Apply elevation filter (> 3500m using SRTM) βββββββββββββββββββββββ
var srtm = ee.Image('USGS/SRTMGL1_003').select('elevation');
var highElevMask = srtm.gt(3500);
var glacialWater = waterMask.updateMask(highElevMask);
// ββ 9. Convert water pixels to vectors ββββββββββββββββββββββββββββββββββββ
var waterVectors = glacialWater.reduceToVectors({
geometry: nepal,
crs: glacialWater.projection(),
scale: 30,
geometryType: 'polygon',
eightConnected: false,
labelProperty: 'water',
reducer: ee.Reducer.countEvery(),
maxPixels: 1e10,
});
// ββ 10. Filter by minimum area (> 0.01 kmΒ² = 10,000 mΒ²) βββββββββββββββββ
var filteredLakes = waterVectors.filter(
ee.Filter.gt('count', 11) // 11 pixels Γ 900 mΒ²/pixel β 10,000 mΒ²
);
print('Detected lake count:', filteredLakes.size());
// ββ 11. Add area property βββββββββββββββββββββββββββββββββββββββββββββββββ
var lakesWithArea = filteredLakes.map(function(feat) {
var areaSqKm = feat.geometry().area().divide(1e6);
return feat.set('area_km2', areaSqKm);
});
// ββ 12. Visualise on map ββββββββββββββββββββββββββββββββββββββββββββββββββ
Map.centerObject(nepal, 7);
Map.addLayer(mndwiComposite, {min: -0.5, max: 0.8, palette: ['brown', 'white', 'blue']}, 'MNDWI Composite');
Map.addLayer(glacialWater.selfMask(), {palette: ['00AAFF']}, 'Glacial Water Mask');
Map.addLayer(lakesWithArea, {color: 'red'}, 'Detected Lakes (> 0.01 kmΒ², > 3500m)');
// ββ 13. Export to Google Drive as GeoJSON βββββββββββββββββββββββββββββββββ
Export.table.toDrive({
collection: lakesWithArea,
description: 'Nepal_Glacial_Lakes_2013_2024',
fileFormat: 'GeoJSON',
folder: 'GEE_Exports',
fileNamePrefix: 'nepal_glacial_lakes',
});