Edit

Sentinel Hub Custom Script

SentinelHub3 process3 Evalscript1

Updating the Evalscript used by the Sentinel Hub source.

This example demonstrates how a custom script can be used to render tiles from Sentinel Hub. Edit the setup() and evaluatePixel() functions above and click the update button to change the visualization. See the Sentinel Hub documentation on Evalscript for more information. See the basic Sentinel Hub example for details on authentication.

main.js
import {javascript} from '@codemirror/lang-javascript';
import {EditorView, basicSetup} from 'codemirror';
import Map from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/WebGLTile.js';
import {useGeographic} from 'ol/proj.js';
import SentinelHub from 'ol/source/SentinelHub.js';

useGeographic();

const source = new SentinelHub({
  data: [
    {
      type: 'sentinel-2-l2a',
      dataFilter: {
        timeRange: {
          from: '2024-05-15T00:00:00Z',
          to: '2024-05-25T00:00:00Z',
        },
      },
    },
  ],
});

const map = new Map({
  layers: [new TileLayer({source})],
  target: 'map',
  view: new View({
    center: [30.674, 29.935],
    zoom: 10,
    minZoom: 13,
    maxZoom: 15,
  }),
});

document.getElementById('auth-form').addEventListener('submit', (event) => {
  const clientId = event.target.elements['id'].value;
  const clientSecret = event.target.elements['secret'].value;
  source.setAuth({clientId, clientSecret});
});

const script = `//VERSION=3
function setup() {
  return {
    input: ['B02', 'B03', 'B04', 'B08', 'B11'],
    output: {bands: 3},
  };
}

function evaluatePixel(sample) {
  // Normalized Difference Moisture Index
  const ndmi = (sample.B08 - sample.B11) / (sample.B08 + sample.B11);
  if (ndmi <= 0) {
    return [3 * sample.B04, 3 * sample.B03, 3 * sample.B02];
  }
  if (ndmi <= 0.2) {
    return [0, 0.8, 0.9];
  }
  if (ndmi <= 0.4) {
    return [0, 0.5, 0.9];
  }
  return [0, 0, 0.7];
}`;

const editor = new EditorView({
  doc: script,
  extensions: [basicSetup, javascript()],
  parent: document.getElementById('evalscript'),
});

document
  .getElementById('evalscript-form')
  .addEventListener('submit', (event) => {
    event.preventDefault();
    source.setEvalscript(editor.state.doc.toString());
  });

source.setEvalscript(script);

source.on('change', () => {
  if (source.getState() === 'error') {
    alert(source.getError());
  }
});
index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>Sentinel Hub Custom Script</title>
    <link rel="stylesheet" href="node_modules/ol/ol.css">
    <style>
      .map {
        width: 100%;
        height: 400px;
      }
      dialog {
        top: 13rem;
      }

      #auth-form {
        display: flex;
        flex-direction: column;
      }

      #auth-form>label {
        margin-bottom: 1rem;
      }

      #auth-form>input[type=submit] {
        margin-top: 1rem;
      }

      #evalscript-form {
        display: flex;
        flex-direction: column;
      }

      #evalscript-form>input[type=submit] {
        margin-top: 1rem;
        width: fit-content;
        align-self: flex-end;
      }

      .cm-editor {
        font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
        font-size: 13px;
      }
    </style>
  </head>
  <body>
    <div id="map" class="map"></div>
    <form id="evalscript-form">
      <div id="evalscript"></div>
      <input type="submit" value="update">
    </form>
    <dialog id="auth-dialog" open>
      <form method="dialog" id="auth-form">
        <label>Client id
          <br>
          <input type="text" name="id" autofocus>
        </label>
        <label>Client secret
          <br>
          <input type="password" name="secret">
        </label>
        <input type="submit" value="show map">
      </form>
    </dialog>

    <script type="module" src="main.js"></script>
  </body>
</html>
package.json
{
  "name": "sentinel-hub-custom-script",
  "dependencies": {
    "ol": "10.5.0",
    "@codemirror/lang-javascript": "^6.2.2",
    "codemirror": "^6.0.1"
  },
  "devDependencies": {
    "vite": "^3.2.3"
  },
  "scripts": {
    "start": "vite",
    "build": "vite build"
  }
}