Grasberg’s Open Pit, Indonesia (Sentinel-2 image with applied false color script, acquired on May 14th, 2018) — See the details here!

Sentinelhub-js — open-source library for satellite imagery powered web applications

Introducing JavaScript/TypeScript library for seamless integration of Sentinel Hub and other similar EO web services in web or node.js applications.

Sinergise
Sentinel Hub Blog
Published in
6 min readMar 31, 2020

--

We are happy to announce the availability of a new opensource JavaScript / TypeScript library, sentinelhub-js (MIT license). It will join our existing libraries that simplify EO data processing, such as sentinelhub-py and eo-learn (both Python). The library is used in production by two well-known remote sensing web applications (EO Browser and Sentinel Playground) and we are in the process of migrating other applications too.

Why is this big news? sentinelhub-js allows web developers to easily access remote sensing data and to integrate it with their applications — no need to construct queries using fetch, axios and similar anymore. The library is not limited just to the Sentinel Hub service either, it allows integration of any remote sensing service which supports standard OGC queries.

In other words, the goal of the library is to provide a simple, unified JavaScript interface to multiple Earth Observation (EO) services. All datasets are treated similarly in a sense that a set of common operations is provided for each of them, but user can still use dataset-specific functionality where available.

This post tries to provide an introduction to the library as it exists at the time of writing (27th of March 2020). As the library is being developed actively, please consult sentinelhub-js repository for installation instructions and up-to-date documentation.

We hope that this library will help developers build applications that will help bring field of remote sensing closer to end users. These application will join existing apps such as opensource EO Browser and Sentinel Playground, which can already serve as a starting point for any application developer working on satellite imagery tool.

Layer

The core concept in this library is that of a “layer”. Layer has all the information about the satellite data that will be used — which dataset is used (including its infrastructure location), which combination of bands is used, and any other dataset-specific filter parameters, such as orbit direction, acquisition mode, polarization, maximum cloud cover and similar.

Constructing layers manually

To create a new layer, we can use one of the …Layer classes, for example WmsLayer:

To get the WMS URL / instance ID, and to create your own layers, Sentinel Hub Dashboard should be used. If you don’t have an account yet, sign up — there is a free trial available.

WmsLayer allows using any dataset on any service that supports the OGC WMS standard. However Sentinel Hub provides additional capabilities which are not accessible through WmsLayer. To use them, we must create dataset-specific layers. For example, here’s how you create a layer for Sentinel-2 L2A:

There are dataset-specific classes available for every dataset that Sentinel Hub service supports, including:

  • S1GRDAWSEULayer and S1GRDEOCloudLayer (Sentinel-1 on AWS and on EO Cloud infrastructure respectively)
  • S2L1CLayer and S2L2ALayer (Sentinel-2 L1C and L2A)
  • S3OLCILayer and S3SLSTRLayer (Sentinel-3 OLCI and SLSTR)
  • S5PL2Layer (Sentinel-5P)
  • EnvisatMerisEOCloudLayer (Envisat MERIS)
  • BYOCLayer (Bring Your Own Data/COG)
  • Landsat5EOCloudLayer, Landsat7EOCloudLayer, Landsat8EOCloudLayer and Landsat8AWSLayer (Landsat 5, 7 and 8 on EO Cloud infrastructure, and Landsat 8 on AWS)
  • MODISLayer (MODIS)
  • DEMLayer (Digital Elevation Model)

For access to other remote sensing services WmsLayer should be used.

Constructing layers by querying service

It is also possible to construct multiple layers at once with LayersFactory.This method uses WMS GetCapabilities request to get the information about the layers from service, and then constructs the appropriate objects automatically. Factory method LayersFactory.makeLayers returns an array of …Layer objects with all the available parameters set:

To avoid constructing unnecessary layer objects, we can also filter them:

Searching for available satellite data

Before we can display data, we need to know the times at which the data is available, given the dataset and our area of interest (bounding box).

Note: special care must be taken when using times. As is usual, all communication with services uses UTC times. However, the common representation of dates in JavaScript is a Date object, which doesn’t support setting a custom (non-local) timezone — even if constructed with new Date(Date.UTC(…)), the result is a Date object in the local timezone. This means that when interacting with the library, all times (parameters for the functions and the returned results) are represented as Date objects (again, always in local timezone). If your application needs to work with times in UTC (as is often the case), it needs to convert these Date objects from/to UTC. For example, if using moment.js:

Layers support three methods that allow searching for available data:

  • findTiles()
  • findDatesUTC()
  • findFlyovers()

These functions allow searching either for times of the individual tiles, for dates, or for flyovers — parts of orbits over a given area.

For example, function findFlyovers returns an array of time intervals. Each time interval tells us when the satellite started collecting data over the specified area, and when it has exited the area. The code says it best:

Fetching satellite images

Once we have a layer instance, we can fetch satellite images using getMap or getMapUrl methods. First we need to specify the parameters such as area, time frame, output format and similar:

If the data is not available for the specified bounding box and time range, you will not get an error — the result will be an empty image (transparent or single color, depending on the layer definition and output format). Similarly, if the time range includes multiple orbits, they will be merged together (stacked on top of each other).

With that, we can get the image binary data. In a browser, data is returned as Blob, while in node.js a string is returned:

There are different ways we can use this data, for example we can display it in an <img> DOM element (browser) or save the image to disk (node.js).

If we have selected a Sentinel-2 L2A “true color” layer, the resulting image looks like this:

Richat Structure, Mauritania (inspect in EO Browser)

Up until now we have only used WMS, but this library also supports the Sentinel Hub Processing API. To use it, you need to authenticate first.

Access credentials (clientId and clientSecret) should be retrieved from Sentinel Hub Dashboard by creating a new OAuth client.

Once we are authenticated, we call getMap with ApiType.PROCESSING parameter. The content of the resulting image should be exactly the same as when using WMS:

We can also get just the URL of the image, if the API supports HTTP GET:

getMapUrl method will only work with the WMS API, because the Processing API uses HTTP POST method which can’t be represented by an URL. However a benefit of POST requests is that the request is not limited in size, as is the case with GET. Side note: Processing API also supports additional functionalities like data fusion (not yet available through this library — coming soon!).

Final thoughts

We are very excited about this library and hope you will find it as useful as we do. Even though the library is young, we do not anticipate any breaking changes happening anytime soon. We do have quite a lot of new functionalities in mind for the coming months. We welcome suggestions, bug reports (or even fixes), feature requests, or any feedback really... :) Use GitHub issues or Sentinel Hub Forum to get in touch with us, we’d be happy to hear from you!

--

--