SentinelExplorer

SentinelExplorer is a pure Julia package for querying and downloading Sentinel data from the Copernicus Data Space Ecosystem.

Installation

To install this package, start the Julia REPL and open the package manager by typing ]. You can then install SentinelExplorer from the official Julia repository like so:

(@v1.9) pkg> add SentinelExplorer

Quick Start

using SentinelExplorer, GeoDataFrames, Dates

# Only Necessary if `SENTINEL_EXPLORER_USER` and `SENTINEL_EXPLORER_PASS` are not Already Set
authenticate("my_username", "my_password")

# Load Region of Interest From External GeoJSON or Shapefile
roi = GeoDataFrames.read("data/roi.geojson").geometry |> first

# Define Region of Interest as a Bounding Box
bb = BoundingBox((52.1, -114.4), (51.9, -114.1))

# Define Region of Interest Centered on a Point
p = Point(52.0, -114.25)

# Search For Sentinel-2 Imagery Intersecting our ROI Between August 1 2020 and August 9 2020
dates = (DateTime(2020, 8, 1), DateTime(2020, 8, 9))
results_1 = search("SENTINEL-2", dates=dates, geom=roi)

# Limit Search to Scenes with no More Than 15% Clouds
results_2 = search("SENTINEL-2", dates=dates, geom=roi, clouds=15)

# Further Limit to L2A Products
results_3 = search("SENTINEL-2", dates=dates, geom=roi, clouds=15, product="L2A")

# Retrieve Result with Lowest Cloud Cover
scene = sort(results_3, :CloudCover) |> first

# Download Scene
download_scene(scene.Name; unzip=true)

Integration with DataDeps

using SentinelExplorer, DataDeps, SatelliteDataSources, Rasters

# Register Data Dependency
DataDep(
    "S2B_MSIL2A_20200804T183919_N0500_R070_T11UPT_20230321T050221", 
    "Sentinel 2 Test Data", 
    "S2B_MSIL2A_20200804T183919_N0500_R070_T11UPT_20230321T050221", 
    "b320ecdaf31bf8555a37b426623adde7becd5d3b00e9b62c65fb49738290a4c4",
    fetch_method = download_scene,
    post_fetch_method = unpack
) |> register

# Only Necessary if `SENTINEL_EXPLORER_USER` and `SENTINEL_EXPLORER_PASS` are not Already Set
authenticate("my_username", "my_password")

# Download Data and Read Green and NIR Bands
src = datadep"S2B_MSIL2A_20200804T183919_N0500_R070_T11UPT_20230321T050221"
sentinel_2_10m = SatelliteDataSources.Sentinel2{10}(src)
green, nir = RasterStack(sentinel_2_10m, [:green, :nir])

# Convert DNs to Reflectance
green = green .* 0.0001f0
nir = nir .* 0.0001f0

# Compute NDWI
ndwi = (green .- nir) ./ (green .+ nir)

Index

API

SentinelExplorer.BoundingBoxType
BoundingBox(ul, lr)

Construct a bounding box defined by the corners ul and lr.

All coordinates should be provided in latitude and longitude.

Parameters

  • ul: The upper-left corner of the box as a Tuple{T,T} of latitude and longitude.
  • lr: The lower-right corner of the box as a Tuple{T,T} of latitude and longitude.

Example

bb = BoundingBox((52.1, -114.4), (51.9, -114.1))
source
SentinelExplorer.PointType
Point(lat, lon)

Construct a point located at the provided latitude and longitude.

Parameters

  • lat: The latitude of the point.
  • lon: The longitude of the point.

Example

p = Point(52.0, -114.25)
source
SentinelExplorer.authenticateMethod
authenticate(username, password)

Authenticate with your Copernicus Data Space credentials.

Sets the environment variables SENTINEL_EXPLORER_USER and SENTINEL_EXPLORER_PASS, which will be used to authenticate future requests.

Parameters

  • username: Your Copernicus Data Space username.
  • password: Your Copernicus Data Space password.

Example

authenticate("my_username", "my_password")
token = get_access_token()
source
SentinelExplorer.download_sceneFunction
download_scene(scene, dir=pwd(); unzip=false, log_progress=true, access_token=nothing)

Download the requested Sentinel scene using the provided access token.

Parameters

  • scene: The name of the jentinel scene to download.
  • dir: The destination directory of the downloaded scene (default = pwd()).

Keywords

  • unzip: If true, unzips and deletes the downloaded zip file (default = false).
  • log_progress: If true, logs the download progress at 1-second intervals (default = true).
  • access_token: A token to authenticate the request. Calls get_access_token() if nothing (default).
source
SentinelExplorer.download_scenesFunction
download_scenes(scenes, dir=pwd(); unzip=false, access_token=nothing)

Download multiple scenes in parallel.

The number of parallel downloads is determined by Threads.nthreads().

Parameters

  • scenes: A list of scenes to download.

Keywords

  • dir: The destination directory of the downloaded scene (default = pwd()).
  • unzip: If true, unzips and deletes the downloaded zip file (default = false).
  • access_token: A token to authenticate the request. Calls get_access_token() if nothing (default).
source
SentinelExplorer.get_access_tokenMethod
get_access_token()
get_access_token(username, password)

Receive a data access token with the provided credentials.

The username and password may be passed explicitly, or provided as a pair of environment variables.

In the case of the latter, get_access_token() expects your username and password to be provided as the environment variables SENTINEL_EXPLORER_USER and SENTINEL_EXPLORER_PASS.

Parameters

  • username: Your Copernicus Data Space username.
  • password: Your Copernicus Data Space password.

Returns

An access token for downloading data.

Example

token = get_access_token(ENV["SENTINEL_EXPLORER_USER"], ENV["SENTINEL_EXPLORER_PASS"])
token = get_access_token()  # Same as Above
source
SentinelExplorer.get_scene_idMethod
get_scene_id(scene)

Lookup the unique identifier for the provided scene.

Parameters

  • scene: The name of the Sentinel scene to lookup.

Returns

The unique identifier for downloading the provided scene.

Example

julia> scene = "S2B_MSIL2A_20200804T183919_N0500_R070_T11UPT_20230321T050221";

julia> get_scene_id(scene)
"29f0eaaf-0b15-412b-9597-16c16d4d79c6"
source
SentinelExplorer.searchMethod
search(satellite; product=nothing, dates=nothing, tile=nothing, clouds=nothing, geom=nothing, max_results=100)

Search for satellite images matching the provided filters.

Parameters

  • satellite: One of "SENTINEL-1", "SENTINEL-2", or "SENTINEL-3".

Keywords

  • product: The product type to search for such as "L2A", "L1C", "GRD", etc.
  • dates: The date range for image acquisition. Should be a tuple of DateTime objects.
  • tile: Restrict results to a given tile. Only available for Sentinel-2.
  • clouds: The maximum allowable cloud cover as a percentage. Not available for Sentinel-1.
  • geom: A geometry specifying the region of interest. Can be a Point, BoundingBox, or any other GeoInterface compatible geometry.
  • max_results: The maximum number of results to return (default = 100).

Returns

A DataFrame with the columns :Name, :AcquisitionDate, :PublicationDate, :CloudCover, and :Id.

Example

julia> geom = GeoDataFrames.read("test/data/roi.geojson").geometry[1];

julia> dates = (DateTime(2020, 8, 4), DateTime(2020, 8, 5));

julia> search("SENTINEL-2",  geom=geom, dates=dates)
3×5 DataFrame
 Row │ Name                               AcquisitionDate           Pub ⋯
     │ String                             String                    Str ⋯
─────┼───────────────────────────────────────────────────────────────────
   1 │ S2B_MSIL2A_20200804T183919_N0500…  2020-08-04T18:39:19.024Z  202 ⋯
   2 │ S2B_MSIL1C_20200804T183919_N0209…  2020-08-04T18:39:19.024Z  202
   3 │ S2B_MSIL1C_20200804T183919_N0500…  2020-08-04T18:39:19.024Z  202
                                                        3 columns omitted
source