Skip to content

Instantly share code, notes, and snippets.

@jmasselink
Last active October 15, 2024 19:30
Show Gist options
  • Save jmasselink/be618d52bf164965d464f6fa561f6806 to your computer and use it in GitHub Desktop.
Save jmasselink/be618d52bf164965d464f6fa561f6806 to your computer and use it in GitHub Desktop.
Water detection in Sentinel Hub
//VERSION=3
const colorRamp = [[0, 0x000000], [1, 0xFFFFFF]]; // Color ramp for water detection (black for water)
let viz = new ColorRampVisualizer(colorRamp);
function setup() {
return {
input: ["B02", "B03", "B04", "B08", "B11", "dataMask"],
output: [
{ id: "default", bands: 4 }, // RGBA output for combined visualization
{ id: "index", bands: 1, sampleType: 'FLOAT32' }, // Binary index output
{ id: "eobrowserStats", bands: 2, sampleType: 'FLOAT32' }, // Stats for mNDWI and data mask
{ id: "dataMask", bands: 1 } // Mask output
]
};
}
function evaluatePixel(samples) {
// Step 1: Create True-Color RGB Image (using B04, B03, B02)
let trueColor = [samples.B04 * 2.5, samples.B03 * 2.5, samples.B02 * 2.5]; // Adjust brightness
// Step 2: Calculate indices for water detection
let mNDWI = (samples.B03 - samples.B11) / (samples.B03 + samples.B11);
let NDVI = (samples.B08 - samples.B04) / (samples.B08 + samples.B04);
let EVI = 2.5 * (samples.B08 - samples.B04) / (samples.B08 + 6 * samples.B04 - 7.5 * samples.B02 + 1);
// Step 3: Apply water detection criteria from Xia et al.
let isWater = (mNDWI > NDVI && EVI < 0.1) && (mNDWI > EVI && EVI < 0.1);
// Step 4: Create Overlay for Water Detection: Black for water, transparent for non-water
let overlay = isWater ? [0, 0, 1, 0.6] : [0, 0, 0, 0]; // Water is black, non-water is transparent
// Step 5: Combine True Color Image and Water Detection Overlay
let combined = [
trueColor[0] * (1 - overlay[3]) + overlay[0], trueColor[1] * (1 - overlay[3]) + overlay[1],trueColor[2] * (1 - overlay[3]) + overlay[2],samples.dataMask
];
let indexVal = samples.dataMask === 1 ? (isWater ? 1 : 0) : NaN;
return {
default: combined, // Visualization: True color + water detection overlay
index: [indexVal], // Binary index (1 for water, 0 for non-water)
eobrowserStats: [mNDWI, samples.dataMask], // Output mNDWI for analysis
dataMask: [samples.dataMask] // Data mask
};
}
//VERSION=3
const colorRamp = [[0, 0xFF69B4], [1, 0x000000]];
let viz = new ColorRampVisualizer(colorRamp);
function setup() {
return {
input: ["B02", "B03", "B04", "B08", "B11", "dataMask"],
output: [
{ id: "default", bands: 4 }, // RGBA output for combined visualization
{ id: "index", bands: 1, sampleType: 'FLOAT32' }, // Binary index output
{ id: "eobrowserStats", bands: 2, sampleType: 'FLOAT32' }, // Stats for mNDWI and data mask
{ id: "dataMask", bands: 1 } // Mask output
]
};
}
function evaluatePixel(samples) {
// Step 1: RGB
let trueColor = [samples.B04 * 2.55, samples.B03 * 2.55, samples.B02 * 2.55];
// Step 2: water detection
let mNDWI = (samples.B03 - samples.B11) / (samples.B03 + samples.B11);
let NDVI = (samples.B08 - samples.B04) / (samples.B08 + samples.B04);
let EVI = 2.5 * (samples.B08 - samples.B04) / (samples.B08 + 6 * samples.B04 - 7.5 * samples.B02 + 1);
// Step 3: Apply water detection
let isWater = (mNDWI > NDVI && EVI < 0.1) && (mNDWI > EVI && EVI < 0.1);
// Step 4: Create Overlay
let overlay = isWater ? [1, 0.11, 0.71, 0.8] : [0, 0, 0, 0]; // Water is pink, non-water is transparent
// Step 5:
let combined = [
trueColor[0] * (1 - overlay[3]) + overlay[0], // Red channel
trueColor[1] * (1 - overlay[3]) + overlay[1], // Green channel
trueColor[2] * (1 - overlay[3]) + overlay[2], // Blue channel
samples.dataMask // Alpha channel (transparency based on mask)
];
// Step 6: Handle index and stats output
let indexVal = samples.dataMask === 1 ? (isWater ? 1 : 0) : NaN;
return {
default: combined,
index: [indexVal],
eobrowserStats: [mNDWI, samples.dataMask], dataMask: [samples.dataMask]
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment