🔧
Working with scientific data formats in GIS
  • 📔Intro notes
  • 😃"Good" HDF
  • 😁"Good" GRIB
  • 🧐"Not-so-good" NetCDF
  • ☕Reading Sentinel-3 data
Powered by GitBook
On this page
  • DATA source
  • SNAP
  • QGIS
  • Python
  • Read image data
  • Reproject
  • Check the output in QGIS

Reading Sentinel-3 data

Sentinel-3 data from Copernicus Open Access Hub could be easily read in SNAP.

Previous"Not-so-good" NetCDF

Last updated 2 years ago

DATA source

Sentinel-3 L1 EFR (OL_1_EFR) downloaded from .

SNAP

To open data: File > Import > Optical Sensors > Sentinel-3 >Sentinel-3. Select *.xml file

To visualize data: Window > New RGB window > Select one of the profiles

To export data: File > Export > GeoTIFF / BigTIFF. Click Subset... button, change the spatial subset and select at least 3 bands (e.g. 8-6-4 for RGB). Export file.

QGIS

Open the output file in QGIS. The georeferencing is wrong. Original *.nc files are not georeferenced either.

Python

Read image data

GDAL can read NetCDF files as arrays. We read all the bands and store them to dict with band names.

import numpy as np
from osgeo import gdal, osr
import xarray as xr
import matplotlib.pyplot as plt
from glob import glob
band_files = sorted(glob('Oa*radiance.nc'))
bands_dict = {}
for n, file in enumerate(band_files):
    band_ds = xr.open_dataset(file)
    band = band_ds[file.replace('.nc', '')].values
    bands_dict[str(n+1).zfill(2)] = band
plt.imshow(bands_dict['04'],
           cmap='gray',
           vmin=np.nanpercentile(bands_dict['04'], 2),
           vmax=np.nanpercentile(bands_dict['04'], 98))
plt.axis('off')
plt.colorbar();
rgb_array = np.stack([
    bands_dict['08'],
    bands_dict['06'],
    bands_dict['04']
], axis=2)

Sentinel-3 georeference info is stored in the geo_coordinates.nc file, which contains 2D latitude and longitude grids.

geo = xr.open_dataset('geo_coordinates.nc')
lon = geo.longitude.values
lat = geo.latitude.values

GCP object consists of list of geocoordinates with corresponding pixel coordinates

gcps = [] #empty list
num = 20 #number of points along one of the axes
for row in np.linspace(0, rgb_array.shape[0]-num, num):
    for col in np.linspace(0, rgb_array.shape[1]-num, num):
        row = int(row)
        col = int(col)
        gcp = gdal.GCP(lon[row, col], lat[row, col], 0, col, row)
        gcps.append(gcp)

Custom function for saving array to GeoTIFF

def save_file_multiband(input_array, out_file, gcps, epsg=4326 , no_data=-32768):
    
    """Save numpy array to multiband GTiff file"""
    
    driver = gdal.GetDriverByName('GTiff')
    
    sr = osr.SpatialReference()
    sr.ImportFromEPSG(epsg) #create projection reference from EPSG code
    
    dataset = driver.Create(out_file,
                        input_array.shape[1],
                        input_array.shape[0],
                        input_array.shape[2],
                        eType=gdal.GDT_Float32)
    
    for band in range(input_array.shape[2]):
        outband = dataset.GetRasterBand(band + 1)
        outband.SetNoDataValue(no_data)
        outband.WriteArray(input_array[:, :, band])
        
    dataset.SetGCPs(gcps, sr.ExportToWkt())        
    dataset = None
save_file_multiband(rgb_array,'S3_OLCI_2023-03-16_RGB.tif', gcps, epsg=4326, no_data=-32768)

Reproject

gdal.Warp('/mnt/c/DATA/DropIn/S3/S3_OLCI_{}_RGB_3031.tif'.format(date),
          '/mnt/c/DATA/DropIn/S3/S3_OLCI_{}_RGB.tif'.format(date),
          dstSRS='EPSG:3031')

Check the output in QGIS

The full notebook download is below. To run it, , savethe notebook to your working directory, and run jupyter notebook from this directory.

Every file is read as 2D array with no geotransformation.

You can see that the coordinates gradient is not parallel to the image sides. This means, that it is not possible to produce a GDAL line. For this case, we can create a GDAL GCP object to warp the image with it.

☕
geotransform
Copernicus Open Access Hub
set up conda environment
341KB
Sentinel3_NETCDF_exp.ipynb
SNAP window for data expoort
SNAP output in QGIS
The output is georeferenced correctly