Download and convert to Geopackage

This downloads SWOT Pixel Cloud products from hydroweb.next (API-Key necessary) based on a region and a period of interest. Then is extracts information contained in the area of interest for your study, stores everything in a Geopackage Database for future use. Geopackage is a convenient data storage format, based on SQL, and is compatible with QGIS.

Setting the region and period of interest

Using a geopackage layer, preliminary created with, e.g. QGIS, to limit data download and database

[12]:
from pixcdust.downloaders.hydroweb_next import PixCDownloader
import geopandas as gpd
from datetime import datetime
[13]:
# reading the area of interest
gdf_geom = gpd.read_file("../data/aoi.gpkg")

# Limiting time period
dates = (
    datetime(2023,4,6),
    datetime(2023,4,8),
)

Download

This will unfortunately lead to downloading many big files (that will be removed later). This is the only way right now, but the hydroweb.next team is working on improving that.

[3]:
pixcdownloader = PixCDownloader(
    gdf_geom,
    dates,
    verbose=1,
    path_download='/tmp/pixc',
    )
pixcdownloader.search_download()

Extraction

Now we have all necessary files, let us extract key variables within area of interest in a geopackage database. This geopackage format is quite efficient (though not the most efficient), and may easily be visualized in, e.g., QGIS We are using the same geodataframe to limit the data to the area of interest

[4]:
from pixcdust.converters.gpkg import Nc2GpkgConverter
from glob import glob
[5]:
# You can specify conditions on variables to filter data
conditions= {"sig0":{'operator': "gt", 'threshold': 20},  # sig0 > 20
             "classification":{'operator': "ge", 'threshold': 3},  # classification >= 3
            }

pixc = Nc2GpkgConverter(
            path_in = glob(pixcdownloader.path_download+'/*/*nc'),
            variables=['height', 'sig0', 'classification'],
            area_of_interest=gdf_geom,
            conditions=conditions
        )
pixc.database_from_nc(path_out="/tmp/pixc_gpkg.gpkg")
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 32.53it/s]
skipping layer 20230407_483_16_78L                             (already in geopackage /tmp/pixc_gpkg.gpkg)
skipping layer 20230406_482_16_78L                             (already in geopackage /tmp/pixc_gpkg.gpkg)

database has been succesfully created, we can remove the raw files

[6]:
# import shutil
# shutil.rmtree('/tmp/pixc')

Read the database

Previous steps are not necessary

Now we can open this database in a GeoDataFrame, load it in, e.g., QGIS, etc.

[7]:
from pixcdust.readers.gpkg import GpkgReader

# nb: you may specify
pixc_read = GpkgReader(
    "/tmp/pixc_gpkg.gpkg"
)
pixc_read.read()
pixc_read.data
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 10.67it/s]
[7]:
<xarray.Dataset> Size: 4MB
Dimensions:         (index: 49160)
Coordinates:
  * index           (index) int64 393kB 0 1 2 3 4 ... 49156 49157 49158 49159
Data variables:
    height          (index) float64 393kB 324.7 284.0 274.1 ... 165.7 170.7
    sig0            (index) float64 393kB 42.92 20.86 39.61 ... 24.67 22.21 28.0
    classification  (index) float64 393kB 6.0 3.0 3.0 3.0 ... 3.0 3.0 3.0 3.0
    geoid           (index) float64 393kB 49.44 49.44 49.42 ... 49.32 49.32
    latitude        (index) float64 393kB 43.52 43.52 43.54 ... 43.68 43.68
    longitude       (index) float64 393kB 1.462 1.459 1.459 ... 1.375 1.379
    wse             (index) float64 393kB 275.2 234.5 224.7 ... 116.4 121.3
    geometry        (index) geometry 393kB <class 'xarray.core.extension_arra...

Rasterization into H3 grid

[8]:
from pixcdust.converters.gpkg import GpkgDGGSProjecter
h3_grid = GpkgDGGSProjecter("/tmp/pixc_gpkg.gpkg", 10, path_out = '../data/h3_gpkg.gpkg', healpix=False) # True for healpix projection
h3_grid.compute_layers()
Layers: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:01<00:00,  1.42it/s]
[9]:
pixc_read = GpkgReader(
    '../data/h3_gpkg.gpkg'
)
pixc_read.read()
pixc_read.data
100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 2/2 [00:00<00:00, 98.45it/s]
[9]:
<xarray.Dataset> Size: 725kB
Dimensions:         (index: 11333)
Coordinates:
  * index           (index) int64 91kB 0 1 2 3 4 ... 11329 11330 11331 11332
Data variables:
    h3_10           (index) int64 91kB 622506101129773055 ... 622506153063612415
    height          (index) float64 91kB 221.2 237.3 242.0 ... 191.6 189.6 195.2
    sig0            (index) float64 91kB 25.33 20.98 36.63 ... 31.15 49.45 23.95
    classification  (index) float64 91kB 3.0 6.0 5.25 3.0 ... 3.0 3.0 3.0 3.0
    geoid           (index) float64 91kB 49.39 49.39 49.39 ... 49.33 49.33 49.33
    wse             (index) float64 91kB 171.8 187.9 192.6 ... 142.2 140.3 145.9
    geometry        (index) geometry 91kB <class 'xarray.core.extension_array...

Display on folium map

Though not the most straightforward and efficient compared to QGIS or other python solutions, this would allow you to dispaly your data in leaflet starting from a GeoDataFrame

[10]:
pixc_read.layers
[10]:
['20230407_483_16_78L_10__h3', '20230406_482_16_78L_10__h3']
[11]:
import folium
import branca.colormap as cmp

layer_h3 = pixc_read.read_single_layer('20230407_483_16_78L_10__h3')

# creating a colormap
linear = cmp.LinearColormap(
    ['blue', 'purple', 'orange', 'yellow'],
    vmin=layer_h3['wse'].min(),  # minimum wse value
    vmax=layer_h3['wse'].max(),  # maximum wse value
    caption='Water Surface Elevation (m)' #Caption for Color scale or Legend
)
# Initiating map
m = folium.Map([43.6, 1.43], zoom_start=12, tiles="cartodbpositron")

folium.GeoJson(
    layer_h3,
    style_function = lambda row:  {
        'fillColor': linear(row['properties']["wse"]),
        'weight': 0,          #how thick the border has to be
        'fillOpacity': 1
    },
).add_to(m)
linear.add_to(m)   #adds colorscale and legend
m
[11]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Enjoy !