Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions sentinel-2/penguin_locator/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ examples:
evalscripturl: https://raw.githubusercontent.com/sentinel-hub/customScripts/master/sentinel-2/penguin_locator/script.js
---

The layout `script` automatically adds the title defined in the front matter and adds buttons to visualize the script. For the buttons to work the evalscript has to be named `script.js` and must be in the same directory as the `README.md` file.


## General description of the script

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions sentinel-5p/air_pollution_RGB/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: Air Pollution RGB
parent: Sentinel-5P
grand_parent: Sentinel
layout: script
permalink: /sentinel-5p/air_pollution_RGB/
layout: script
nav_exclude: true
examples:
- zoom: '6'
lat: '42.008'
lng: '16.620'
datasetId: S5PL2
fromTime: '2025-08-01T00:00:00.000Z'
toTime: '2025-08-31T23:59:59.999Z'
platform:
- CDSE
evalscripturl: https://custom-scripts.sentinel-hub.com/custom-scripts/sentinel-5p/air_pollution_RGB/script.js
---


## General description of the script

This script creates an RGB visualization of key air pollutants NO<sub>2</sub>, SO<sub>2</sub> and HCHO, based on their mean values within a studied interval.
It "tricks" Copernicus Browser into creating a data fusion with all three datasets coming from the same source, Sentinel-5PL2. This is necessary because otherwise Sentinel-5P is not configured to return multiple bands.

Red: NO<sub>2</sub> is mainly releasd by internal combustion engines. It represents a public health hazard, worsening asthma and lung conditions such as chronic bronchitis. It is also used as a generic proxy of emissions from industry and traffic. High seas shipping is a particularly important source of this gas.

Green: SO<sub>2</sub> is released by combustion of fossil fuels, especially coal, and by volcanoes. Sulfur dioxide also leads to airway narrowing and thus worsens asthma and bronchitis, but additionally, it is highly irritating to the eyes, nose, throat and lungs.

Blue: Formaldehyde (HCHO) is also released during biomass burning, vehicle exhausts, and to some extend from vegetation and seawater. It is also a secondary product of the photo-oxidation of other volatile organic compounds in the atmosphere. Exposure to HCHO affects the central nervous system, can produce eye and skin irritation and irritation of the respiratory tract.

## How to use

- Open Copernicus Browser, navigate to your area of interest
- Select Sentinel-5P and a time range - typically a few weeks to a month
- Select NO<sub>2</sub>, click the </> icon to edit the code
- Select "use additional datasets (advanced)
- Add S5PL2 twice
- Rename the new data sources to S5PL2_1 and S5PL2_2, respectively (change the dash to an underscore)
- Paste in the script and wait for the data to load. It will take a while, since Sentinel-5P provides daily datasets
- Tune the min and max values

## Example image

This image shows the Middle East, with the Air Pollution RGB overlain on the panchromatic version of the Sentinel-2 Quarterly Cloudless Mosaic.

![Air Pollution RGB Middle East](fig/air_pollution_rgb_middle_east.jpg)

Direct link to image: https://link.dataspace.copernicus.eu/38fr


75 changes: 75 additions & 0 deletions sentinel-5p/air_pollution_RGB/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//VERSION=3
// By András Zlinszky, Sinergise and Github Copilot
// RGB visualization of air pollution from Sentinel-5P
// Red: NO2, Green: SO2, Blue: HCHO

//How to use this script:
// In Copernicus Browser, select Sentinel-5P and N02 as the dataset
// On the date selector panel, choose time interval mode and set your time of interest - a period of typically a month
// you need to enable data fusion in Copernicus Browser, and add the data source S5P_L2 twice.
// Then rename the new data sources to S5PL2_1 and S5PL2_2, respectively (replace the dash with the underscore)
// Finally, you can tune the min and max values below to get a better contrast for your area of interest.

var NO2minVal = 0.00001;
var NO2maxVal = 0.0001;

var SO2minVal = 0.0001;
var SO2maxVal = 0.001;

var HCHOminVal = 0.00001;
var HCHOmaxVal = 0.0005;

function setup() {
return {
input: [
{ datasource: "S5PL2", bands: ["NO2", "dataMask"] },
{ datasource: "S5PL2_1", bands: ["SO2", "dataMask"] },
{ datasource: "S5PL2_2", bands: ["HCHO", "dataMask"] }
],
output: [
{ id: "default", bands: 4 },
{ id: "dataMask", bands: 1 }
],
mosaicking: "ORBIT"
};
}

function mean(arr, key) {
if (arr.length === 0) return 0;
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i][key];
}
return sum / arr.length;
}

function isClear(sample) {
return sample.dataMask === 1;
}

function evaluatePixel(samples, inputData, inputMetadata, customData) {
// samples.S5PL2 = NO2, samples.S5PL2_1 = SO2, samples.S5PL2_2 = HCHO
const clearNO2 = samples.S5PL2.filter(isClear);
const clearSO2 = samples.S5PL2_1.filter(isClear);
const clearHCHO = samples.S5PL2_2.filter(isClear);

const meanNO2 = mean(clearNO2, "NO2");
const meanSO2 = mean(clearSO2, "SO2");
const meanHCHO = mean(clearHCHO, "HCHO");

let r = (meanNO2 - NO2minVal) / (NO2maxVal - NO2minVal);
let g = (meanSO2 - SO2minVal) / (SO2maxVal - SO2minVal);
let b = (meanHCHO - HCHOminVal) / (HCHOmaxVal - HCHOminVal);

r = Math.max(0, Math.min(1, r));
g = Math.max(0, Math.min(1, g));
b = Math.max(0, Math.min(1, b));

// Data is valid only if all three bands have at least one valid sample
let dataMask = (clearNO2.length > 0 && clearSO2.length > 0 && clearHCHO.length > 0) ? 1 : 0;

return {
default: [r, g, b, dataMask],
dataMask: [dataMask]
};
}
64 changes: 64 additions & 0 deletions sentinel-5p/multiband_sen5p_mosaics/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//VERSION=3
// example script to calculate Sentinel-5P multi-band mosaics

function setup() {
return {
input: [
{ datasource: "S5PL2", bands: ["CH4", "dataMask"] },
{ datasource: "S5PL2_1", bands: ["CLOUD_FRACTION", "dataMask"] },
{ datasource: "S5PL2_2", bands: ["CO", "dataMask"] },
{ datasource: "S5PL2_3", bands: ["HCHO", "dataMask"] },
{ datasource: "S5PL2_4", bands: ["NO2", "dataMask"] },
{ datasource: "S5PL2_5", bands: ["SO2", "dataMask"] }
],
output: [
{ id: "default", bands: 6, sampleType: "FLOAT32" },
{ id: "dataMask", bands: 1 }
],
mosaicking: "ORBIT"
};
}

function mean(arr, key) {
if (arr.length === 0) return 0;
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i][key];
}
return sum / arr.length;
}

function isClear(sample) {
return sample.dataMask === 1;
}

function evaluatePixel(samples, inputData, inputMetadata, customData) {
const clearCH4 = samples.S5PL2.filter(isClear);
const clearCLOUD = samples.S5PL2_1.filter(isClear);
const clearCO = samples.S5PL2_2.filter(isClear);
const clearHCHO = samples.S5PL2_3.filter(isClear);
const clearNO2 = samples.S5PL2_4.filter(isClear);
const clearSO2 = samples.S5PL2_5.filter(isClear);

const meanCH4 = mean(clearCH4, "CH4");
const meanCLOUD = mean(clearCLOUD, "CLOUD_FRACTION");
const meanCO = mean(clearCO, "CO");
const meanHCHO = mean(clearHCHO, "HCHO");
const meanNO2 = mean(clearNO2, "NO2");
const meanSO2 = mean(clearSO2, "SO2");

// Data is valid if any of the bands have at least one valid sample
let dataMask = (
clearCH4.length > 0 ||
clearCLOUD.length > 0 ||
clearCO.length > 0 ||
clearHCHO.length > 0 ||
clearNO2.length > 0 ||
clearSO2.length > 0
) ? 1 : 0;

return {
default: [meanCH4, meanCLOUD, meanCO, meanHCHO, meanNO2, meanSO2],
dataMask: [dataMask]
};
}
3 changes: 2 additions & 1 deletion sentinel-5p/sentinel-5p.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ Sentinel-5P provides atmospheric measurements, relating to air quality, climate

#### Additional Products

- [Nitrogen Dioxide monthly mean](/sentinel-5p/no2_monthly_mean)
- [Nitrogen Dioxide monthly mean](/sentinel-5p/no2_monthly_mean)
- [Air Pollution RGB](/sentinel-5p/air_pollution_RGB/)