Source code for earthkit.hydro.river_network._river_network

from io import BytesIO
from urllib.request import urlopen

import joblib

from earthkit.hydro._readers import (
    find_main_var,
    from_cama_nextxy,
    from_d8,
    from_grit,
    import_earthkit_or_prompt_install,
)
from earthkit.hydro._utils.coords import get_core_grid_dims
from earthkit.hydro._utils.readers import from_file
from earthkit.hydro._version import __version__ as ekh_version
from earthkit.hydro.data_structures._network import RiverNetwork

from ._cache import cache

# read in major version
# if dev version, try add +1 to major version
# i.e. 0.1.dev90+gfdf4e33.d20250107 -> 1
# i.e. 0.1.0 -> 0
ekh_version = (
    int(ekh_version.split(".")[0]) + 1
    if "dev" in ekh_version
    else int(ekh_version.split(".")[0])
)


[docs] @cache def create( path, river_network_format, source="file", use_cache=True, cache_dir=None, cache_fname="{ekh_version}_{hash}.joblib", cache_compression=1, ): """ Creates a river network from the given path, format, and source. Parameters ---------- path : str The path to the river network data. All common file formats are supported such as netCDF, GRIB, GeoTIFF, zarr, etc. river_network_format : str The format of the river network data. Supported formats are "precomputed", "cama", "pcr_d8", "esri_d8", "grit" and "merit_d8". source : str The source of the river network data. Default is `'file'`. For possible sources see: https://earthkit-data.readthedocs.io/en/latest/guide/sources.html. use_cache : bool, optional Whether to cache the loaded/created river network for quicker reloading. Default is True. cache_dir : str, optional Where to store the cached river networks. Default is None, which uses `tempfile.mkdtemp(suffix="_earthkit_hydro")`. cache_fname : str, optional A string template for the cache filename convention. cache_compression : int, optional A compression factor for the cached files. Returns ------- RiverNetwork The river network object created from the given data. """ if river_network_format == "precomputed": if source == "file": river_network_storage = joblib.load(path) elif source == "url": with urlopen(path) as response: river_network_storage = joblib.load(BytesIO(response.read())) else: raise ValueError( "Unsupported source for river network format" f"{river_network_format}: {source}." ) elif river_network_format == "cama": ekd = import_earthkit_or_prompt_install(river_network_format, source) data = ekd.from_source(source, path).to_xarray(mask_and_scale=False) x, y = data.nextx.values, data.nexty.values river_network_storage = from_cama_nextxy(x, y) coord1, coord2 = get_core_grid_dims(data) river_network_storage.coords = { coord1: data[coord1].values, coord2: data[coord2].values, } elif ( river_network_format == "pcr_d8" or river_network_format == "esri_d8" or river_network_format == "merit_d8" ): if path.endswith(".map"): data = from_file(path, mask=False) river_network_storage = from_d8( data, river_network_format=river_network_format ) # coords not available else: ekd = import_earthkit_or_prompt_install(river_network_format, source) data = ekd.from_source(source, path).to_xarray(mask_and_scale=False) coord1, coord2 = get_core_grid_dims(data) var_name = find_main_var(data) river_network_storage = from_d8( data[var_name].values, river_network_format=river_network_format ) river_network_storage.coords = { coord1: data[coord1].values, coord2: data[coord2].values, } elif river_network_format == "grit": assert path.endswith(".gpkg") river_network_storage = from_grit(path) else: raise ValueError(f"Unsupported river network format: {river_network_format}.") return RiverNetwork(river_network_storage)
[docs] def load( domain, river_network_version, data_source=( "https://sites.ecmwf.int/repository/earthkit-hydro/" "{ekh_version}/{domain}/{river_network_version}/river_network.joblib" ), *args, **kwargs, ): """ Load a precomputed river network from a named domain and river_network_version. Supported networks are as follows: +----------------------+-----------+---------------------+----------------------------+----------------+ | `domain` | `version` | Details | Note | Attribution | +======================+===========+=====================+============================+================+ | "efas" | "5" | 1arcmin European | | [1]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ | "efas" | "4" | 5km European | Smaller domain than v5 | [1]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ | "glofas" | "4" | 3arcmin global | 60° South to 90° North | [2]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ | "glofas" | "3" | 6arcmin global | 60° South to 90° North | [2]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ | "cama_01min" | "4" | 3arcmin global | | [3]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ | "cama_03min" | "4" | 3arcmin global | | [3]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ | "cama_05min" | "4" | 5arcmin global | | [3]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ | "cama_06min" | "4" | 6arcmin global | | [3]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ | "cama_15min" | "4" | 15arcmin global | | [3]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ | "hydrosheds_30sec" | "1" | 30arcsec global | 56° South to 84° North | [4]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ | "hydrosheds_05min" | "1" | 5arcmin global | 56° South to 84° North | [4]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ | "hydrosheds_06min" | "1" | 6arcmin global | 56° South to 84° North | [4]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ | "grit" | "1" | 30m global (vector) | segments network | [5]_ | +----------------------+-----------+---------------------+----------------------------+----------------+ Parameters ---------- domain : str The domain of the river network. river_network_version : str The version of the river network on the specified domain. data_source : str, optional The data source URL template for the river network. *args : tuple Additional positional arguments to pass to `create_river_network`. **kwargs : dict Additional keyword arguments to pass to `create_river_network`. Returns ------- RiverNetwork The loaded river network. References ---------- .. [1] Choulga, Margarita; Moschini, Francesca; Mazzetti, Cinzia; Grimaldi, Stefania; Disperati, Juliana; Beck, Hylke; Salamon, Peter; Prudhomme, Christel (2023): LISFLOOD static and parameter maps for Europe. European Commission, Joint Research Centre (JRC) [Dataset] PID: http://data.europa.eu/89h/f572c443-7466-4adf-87aa-c0847a169f23 .. [2] Choulga, Margarita; Moschini, Francesca; Mazzetti, Cinzia; Disperati, Juliana; Grimaldi, Stefania; Beck, Hylke; Salamon, Peter; Prudhomme, Christel (2023): LISFLOOD static and parameter maps for GloFAS. European Commission, Joint Research Centre (JRC) [Dataset] PID: http://data.europa.eu/89h/68050d73-9c06-499c-a441-dc5053cb0c86 .. [3] Yamazaki, Dai; Ikeshima, Daiki; Sosa, Jeison; Bates, Paul D.; Allen, George H.; Pavelsky, Tamlin M. (2019): MERIT Hydro: A high-resolution global hydrography map based on latest topography datasets. Water Resources Research, vol.55, pp.5053-5073, 2019, DOI: 10.1029/2019WR024873 .. [4] Lehner, Bernhard; Verdin, Kristine; Jarvis, Andy (2008): New global hydrography derived from spaceborne elevation data. Eos, Transactions, 89(10): 93-94. Data available at https://www.hydrosheds.org. .. [5] Wortmann, Michel; Slater, Louise; Hawker, Laurence; Liu, Yinxue; Neal, Jeffrey; Zhang, Boen; Schwenk, Jon; Allen, George H.; Ashworth, Philip; Boothroyd, Richard; Cloke, Hannah; Delorme, Pauline; Gebrechorkos, Solomon H.; Griffith, Helen; Leyland, Julian; McLelland, Stuart; Nicholas, Andrew P.; Sambrook-Smith, Gregory; Vahidi, Elham; Parsons, Daniel; Darby, Stephen E. (2025). Global River Topology (GRIT): A bifurcating river hydrography. Water Resources Research, 61(5), DOI: 10.1029/2024WR038308 """ try: uri = data_source.format( ekh_version=ekh_version, domain=domain, river_network_version=river_network_version, ) network = create(uri, "precomputed", "url", *args, **kwargs) except Exception: uri = data_source.format( ekh_version=ekh_version - 1, domain=domain, river_network_version=river_network_version, ) network = create(uri, "precomputed", "url", *args, **kwargs) return network
[docs] def available( data_source="https://sites.ecmwf.int/repository/earthkit-hydro/available.txt", ): """ Prints the available precomputed networks. Parameters ---------- data_source : str, optional Base URI to read available networks from. """ with urlopen(data_source) as response: html = response.read() print("Available precomputed networks are:\n", html.decode("utf-8"))