Initial Example#


Short description

This notebook introduces the SpaceSense library. In this notebook, you will search and download a Sentinel-2 image.


0 - Install Spacesense Client Library and dependencies#

Please follow the installation process and use the virtual environment in this notebook.

1 - Import spacesense object(s) and other dependencies#

[1]:
from spacesense import Client
import matplotlib.pyplot as plt
import numpy as np
import json

2 - Configure the API Key by setting the SS_API_KEY environment variable#

[2]:
import os
if "SS_API_KEY" not in os.environ:
    from getpass import getpass
    api_key = getpass('Enter your api key : ')
    os.environ["SS_API_KEY"] = api_key

3 - Define the area of interest (AOI), time of interest (TOI), output options#

AOIs can be read in directly as geojson files using the json library, or can be defined directly in the code.

You can download the Mont Blanc geojson here

[3]:
# Define the area of interest (AOI)
with open("../resources/aois/mont_blanc.geojson", mode="r") as file:
    aoi = json.load(file)

# Define the time range of interest (TOI)
start_date = "2022-07-13"
end_date = "2022-07-14"

# Get an instance of the SpaceSense Client object
client = Client(id="s2_intro_example")

# Enable to save data in local files
client.enable_local_output()

4 - Search S2#

[4]:
# Call the S2 search function, passing the AOI, and TOI
res_S2 = client.s2_search(aoi=aoi, start_date=start_date, end_date=end_date)
# Visualize the Pandas dataframe with the results
res_S2.dataframe
[4]:
id date tile valid_pixel_percentage platform relative_orbit_number product_id datetime swath_coverage_percentage no_data cloud_shadows vegetation not_vegetated water cloud_medium_probability cloud_high_probability thin_cirrus snow
0 S2A_31TGL_20220713_0_L2A 2022-07-13 31TGL 69.68 sentinel-2a 108 S2A_MSIL2A_20220713T103041_N0400_R108_T31TGL_2... 2022-07-13T10:38:34Z 99.0 0.0 0.23 2.50 53.55 0.86 0.05 0.09 0.0 29.25
1 S2A_32TLR_20220713_0_L2A 2022-07-13 32TLR 70.00 sentinel-2a 108 S2A_MSIL2A_20220713T103041_N0400_R108_T32TLR_2... 2022-07-13T10:38:31Z 100.0 0.0 0.41 2.49 53.51 0.82 0.10 0.16 0.0 29.33
2 S2A_31TGM_20220713_0_L2A 2022-07-13 31TGM 27.20 sentinel-2a 108 S2A_MSIL2A_20220713T103041_N0400_R108_T31TGM_2... 2022-07-13T10:38:19Z 31.0 0.0 0.00 6.59 70.43 0.73 0.00 0.00 0.0 12.26

Select just one S2 result#

[5]:
# Filter the S2 search result to only those that have a 100% swath coverage - Only one result in this case
res_S2.dataframe = res_S2.dataframe[res_S2.dataframe.swath_coverage_percentage == 100]
# Visualize the Pandas dataframe with the results
res_S2.dataframe
[5]:
id date tile valid_pixel_percentage platform relative_orbit_number product_id datetime swath_coverage_percentage no_data cloud_shadows vegetation not_vegetated water cloud_medium_probability cloud_high_probability thin_cirrus snow
1 S2A_32TLR_20220713_0_L2A 2022-07-13 32TLR 70.0 sentinel-2a 108 S2A_MSIL2A_20220713T103041_N0400_R108_T32TLR_2... 2022-07-13T10:38:31Z 100.0 0.0 0.41 2.49 53.51 0.82 0.1 0.16 0.0 29.33

5 - Select only certain bands of S2#

[6]:
# Select only the Blue, Green, and Red bands of S2
# Selecting individual bands fuses ONLY those bands into
# the fused result, in the specified order.
res_S2.output_bands = ["B02", "B03", "B04"]

6 - Obtain S2 image (Fuse)#

The result of the fusion is an Xarray Dataset. This dataset is simply a 3-dimensional array, with the dimensions of time, y (latitude), and x (longitude).

The data we are interested in, the reflectance values of the selected bands, is found in the Data Variables. This data can be selected, enhanced, and manipulated using any Xarray Dataset methods.

[7]:
# Call the core fusion function, passing our filtered S2 result
# This function obtains the result we selected in step 4, with the band selection
# specified in step 5
fusion = client.fuse([res_S2])
# Visualize the Pandas dataframe with the results
fusion.dataset
2022-09-14 14:15:42,988 INFO spacesense.core : created everything
[7]:
<xarray.Dataset>
Dimensions:  (time: 1, y: 624, x: 949)
Coordinates:
  * time     (time) datetime64[ns] 2022-07-13
  * y        (y) float32 45.91 45.91 45.91 45.91 ... 45.86 45.86 45.86 45.86
  * x        (x) float64 6.907 6.907 6.907 6.908 ... 6.992 6.992 6.992 6.992
Data variables:
    s2_B02   (time, y, x) float32 0.0 0.0 0.0 0.0 ... 0.1596 0.1596 0.146 0.1048
    s2_B03   (time, y, x) float32 0.0 0.0 0.0 0.0 ... 0.188 0.188 0.175 0.1228
    s2_B04   (time, y, x) float32 0.0 0.0 0.0 0.0 ... 0.1914 0.1758 0.1232
Attributes:
    crs:        +init=epsg:4326
    transform:  [ 8.98360017e-05  0.00000000e+00  6.90722067e+00  0.00000000e...
    res:        [8.98360017e-05 9.04414549e-05]
    ulx, uly:   [ 6.90722067 45.9145943 ]

7 - Visualize#

[8]:
# Function to normalize RGB band reflectance values
def norm(band):
    band_min, band_max = band.min(), band.max()
    return ((band - band_min)/(band_max - band_min))

# Select the date we want to visualize
ds = fusion.dataset.sel(time='2022-07-13')

# Normalize and brighten the R, G, and B bands
# The high albedo of the snow makes vegetation harder to see without brightening
brightness_factor = 3
blue = norm(ds.s2_B02) * brightness_factor
green = norm(ds.s2_B03) * brightness_factor
red = norm(ds.s2_B04) * brightness_factor
[9]:
# Using numpy, stack the RGB bands into a single object, and plot using matplotlib
rgb = np.dstack([red,green,blue])
plt.figure(figsize=(16,13))
plt.imshow(rgb)
2022-09-14 14:16:12,334 WARNING matplotlib.image : Clipping input data to the valid range for imshow with RGB data ([0..1] for floats or [0..255] for integers).
[9]:
<matplotlib.image.AxesImage at 0x7fc3914c0d50>
../_images/notebooks_1_intro_example_21_2.png