Local Flood Mapping

Local Flood Mapping#

In the context of this notebook we referred to “local flood mapping” as performing the computation on you own machine, as opposed to remote processing which will be explained in the next notebook.

We will begin by loading the flood module from the dask_flood_mapper. You could use the default Dask settings, but it is often good to fine tune te settings to you machine’s specifications. We can do this by setting the Dask scheduler through the Client of dask.distributed.

from importlib.resources import files

import hvplot.xarray  # noqa
import xarray as xr
from dask.distributed import Client
from dask_flood_mapper import flood

Here we set the Dask Scheduler with the Client, where we avoid inter-worker communication which is common for working with numpy and xarray in this case.

client = Client(processes=False, threads_per_worker=2, n_workers=1, memory_limit="12GB")
client

Client

Client-dce5c823-5bfe-11f0-88ac-6045bd4c942d

Connection method: Cluster object Cluster type: distributed.LocalCluster
Dashboard: http://10.1.0.247:8787/status

Cluster Info

No we are ready to map a flood. As an example we use here storm Babet which hit the Danish and Northern coast of Germany at the 20th of October 2023 Wikipedia. We target an area around Zingst at the Baltic coast of Northern Germany.

time_range = "2023-10-11/2023-10-25"
bbox = [12.3, 54.3, 13.1, 54.6]
fd = flood.decision(bbox=bbox, datetime=time_range).compute()
fd
sigma naught datacube processed
harmonic parameter datacube processed
projected local incidence angle processed
<xarray.DataArray 'reproject-7e5439c8f4ad45e9bac1d4d7f67c22b1' (time: 9,
                                                                latitude: 1232,
                                                                longitude: 3283)> Size: 291MB
array([[[nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ..., nan, nan, nan],
        [ 0.,  0.,  0., ..., nan, nan, nan],
        ...,
        [nan, nan,  0., ..., nan, nan, nan],
        [nan, nan,  0., ..., nan, nan, nan],
        [nan, nan,  0., ..., nan, nan, nan]],

       [[nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ...,  0., nan, nan],
        ...,
        [nan, nan, nan, ...,  0.,  0.,  0.],
        [nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ..., nan, nan, nan]],

       [[nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ...,  0., nan, nan],
        ...,
...
        ...,
        [nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ..., nan, nan, nan]],

       [[nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ..., nan, nan, nan],
        [ 0.,  0.,  0., ..., nan, nan, nan],
        ...,
        [nan, nan,  0., ..., nan, nan, nan],
        [nan, nan,  0., ..., nan, nan, nan],
        [nan, nan,  0., ..., nan, nan, nan]],

       [[nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ...,  0., nan, nan],
        ...,
        [nan, nan, nan, ...,  0.,  0.,  0.],
        [nan, nan, nan, ..., nan, nan, nan],
        [nan, nan, nan, ..., nan, nan, nan]]])
Coordinates:
  * time         (time) datetime64[ns] 72B 2023-10-11T05:33:18 ... 2023-10-25...
  * latitude     (latitude) float64 10kB 54.6 54.6 54.6 54.6 ... 54.3 54.3 54.3
  * longitude    (longitude) float64 26kB 12.3 12.3 12.3 12.3 ... 13.1 13.1 13.1
    spatial_ref  int64 8B 0

Since flood.decision does not make a distinction between Sentinel-1 observations over land or over sea, we need to mask pixels over water. For the example here we will load a mask distributed along with this package. But in general this step is left to the user’s own discretion.

data_text = files("dask_flood_mapper.data").joinpath("wcover.nc")
wcover = xr.open_dataarray(data_text, decode_coords="all")

Then we can mask water bodies, like so:

fd = fd.where(wcover != 80)

Now we are ready to view our results. We use here hvplot to create an animation of the flood’s extent over time.

fd.hvplot.image(
    x="longitude",
    y="latitude",
    rasterize=True,
    geo=True,
    tiles=True,
    project=True,
    cmap=["rgba(0, 0, 1, 0.1)", "darkred"],
    cticks=[(0, "non-flood"), (1, "flood")],
    frame_height=400,
)
client.close()