st2berry
st2berry

Reputation: 33

Extracting All Sentinel-2 L2A Bands as GeoTIFF via SentinelHub API?

I want to extract a dataset from Sentinel-2, using the access provided by SentinelHub. Till now I have the following code, which is derived from this documentation, and in which basically there are 5 main things specified:

pip install ipywidgets

import datetime
import os
import getpass
import random
import shutil

import matplotlib.pyplot as plt
import numpy as np
from PIL import Image, ImageEnhance, ImageFilter

from sentinelhub import (
    SHConfig,
    CRS,
    BBox,
    DataCollection,
    DownloadRequest,
    MimeType,
    MosaickingOrder,
    SentinelHubDownloadClient,
    SentinelHubRequest,
    bbox_to_dimensions,
)

from utils import plot_image

config = SHConfig()
config.sh_client_id = getpass.getpass("Enter your SentinelHub client id")
config.sh_client_secret = getpass.getpass("Enter your SentinelHub client secret")
config.sh_token_url = "https://identity.dataspace.copernicus.eu/auth/realms/CDSE/protocol/openid-connect/token"
config.sh_base_url = "https://sh.dataspace.copernicus.eu"

def get_true_color_request(time_interval, bbox, size, config):

    evalscript_true_color = """
    //VERSION=3

    function setup() {
        return {
            input: [{
                bands: ["B02", "B03", "B04"]
            }],
            output: {
                bands: 3
            }
        };
    }

    function evaluatePixel(sample) {
        return [sample.B04, sample.B03, sample.B02];
    }
     """
    return SentinelHubRequest(
        evalscript=evalscript_true_color,
        input_data=[
            SentinelHubRequest.input_data(
                data_collection=DataCollection.SENTINEL2_L2A.define_from(
                    "s2l2a", service_url=config.sh_base_url
                ),
                time_interval=time_interval,
                mosaicking_order=MosaickingOrder.LEAST_CC
            )
        ],
        responses=[SentinelHubRequest.output_response("default", MimeType.PNG)],
        bbox=bbox,
        size=size,
        config=config,
    )

def processing(locations, config):
    resolution = 10 # Meters per pixel

    start = datetime.datetime(2016, 1, 1)
    end = datetime.datetime(2023, 12, 31)
    n_chunks = 16
    tdelta = (end - start) / n_chunks
    edges = [(start + i * tdelta).date().isoformat() for i in range(n_chunks)]
    slots = [(edges[i], edges[i + 1]) for i in range(len(edges) - 1)]

    brightness_factor = 2.5

    for loc_idx, coords in enumerate(locations):
        print(f"Processing location {loc_idx + 1}/{len(locations)}")

        bbox = BBox(bbox=coords, crs=CRS.WGS84)
        size = bbox_to_dimensions(bbox, resolution=resolution)

        list_of_requests = [
            get_true_color_request(slot, bbox, size, config)
            for slot in slots
        ]
        list_of_requests = [request.download_list[0] for request in list_of_requests]

        data = SentinelHubDownloadClient(config=config).download(
            list_of_requests, max_threads=5
        )

        for idx, image in enumerate(data):
            img = Image.fromarray(image, 'RGB')
            enhancer = ImageEnhance.Brightness(img)
            brightened_image = enhancer.enhance(brightness_factor)
            image_path = f'imagepath/_{loc_idx}_{idx}.png'
            brightened_image.save(image_path)

        print(f"Processing of location {loc_idx + 1}/{len(locations)} completed")

if __name__ == "__main__":
    locations = [
        (136.643143,34.762601,136.867676,34.943987),

    ]

    processing(locations, config)

I want to be able to have a GeoTiff output, where all bands of Sentinel-2 L2A will be displayed seperately, for further pre-processing, resampling and custom stacking.

How can I achieve that? Any help is appreciated.

Upvotes: 0

Views: 72

Answers (0)

Related Questions