{ "cells": [ { "cell_type": "markdown", "id": "77a8342d-96a2-406a-96b9-f0fbb2ec08ab", "metadata": {}, "source": [ "# xdggs-dggrid4py: A xdggs plugin for IGEO7 DGGS\n", "\n", "`xdggs-dggrid4py` aims to provides IGEO7 DGGS indexing for xarray datasets through xdggs. It consists of 2 main functions:\n", "\n", "1. Easy access to IGEO7 indexed xarray datasets, including query the datasets with points in WGS84, or zone ID.\n", "2. Convert raster dataset in GeoTiff format to IGEO7 indexed xarray datasets\n", "\n", "## Converting a GeoTiff into an IGEO7 DGGS indexed xarray dataset\n", "There are many ways to convert a GeoTiff into a DGGS indexed dataset. The main idea is to assign a pixel with a DGGS zone ID.\n", "- Nearest zone centroid: Assign the pixel to the nearest zone centroid, measured by the CRS supported by the DGGS. For IGEO7 DGGS, it uses WGS84. \n", "- Zonal statistics: Assign pixels that are within a zone of the DGGS. \n", "- Weighted average: Overlay the DGGS zone's grid on the raster grid, then, for each zone, calculate the percentage of area overlapped with pixels as the weights. Finally, calculate the zone's value using the weights and raster value.\n", "\n", "### General steps of the nearest-neighbourhood method. \n", "\n", "This notebook demonstrates conversion using the nearest neighbourhood method with IGEO7 DGGS.\n", "\n", "1. The first step is to determine the refinement level to use. It affects the number of rows of the dataset after conversion.\n", " - For example, if the refinement level approximately matches the spatial resoultion (in square meters), then the expected number of rows in the resulting dataset should be roughly equal to the number of zones of the region being converted. But if a coarser refinement level is used, the number of rows in the converted result should equal the number of pixels. \n", "\n", "2. Then, generate the zone centroids together with ID that exist in the region of the GeoTiff\n", "\n", "3. Assign each pixel to the nearest zone by measuring the distance between the pixel and zone centroids.\n", "\n", "\n", "\n", "### Demonstration \n", "\n", "#### Install the package from `pypi` or install it from GitHub " ] }, { "cell_type": "code", "execution_count": null, "id": "f1f79c88-03fa-4619-b957-f2c80ec203eb", "metadata": {}, "outputs": [], "source": [ "# install it from pypi : \n", "# !pip install xdggs-dggrid4py\n", "# or install it from GitHub for the lastest commits.\n", "# pip install git+https://github.com/LandscapeGeoinformatics/xdggs-dggrid4py.git\n", "\n", "#At the time of preparing this notebook, a bug was found in dggrid4py (https://github.com/allixender/dggrid4py/issues/46) \n", "# that affect some functions of xdggs (e.g. `sel_lonlat`). It was fixed in the main branch, but has not yet been built into a release. \n", "# It needs to install the dggrid4py from git. \n", "#!pip uninstall -y dggrid4py \n", "#!pip install git+https://github.com/allixender/dggrid4py.git" ] }, { "cell_type": "markdown", "id": "b9fdf530-e9f9-449a-812d-6d2fef4fefdc", "metadata": {}, "source": [ "#### Import libraries" ] }, { "cell_type": "code", "execution_count": 1, "id": "50935bd5-b1a1-4c3a-b678-8ae23bb51042", "metadata": {}, "outputs": [], "source": [ "import xarray as xr\n", "import rioxarray as rio\n", "import os\n", "import warnings\n", "warnings.filterwarnings(\"ignore\")\n", "\n", "# xdggs-dggrid4py require both dggrid4py and DGGRID installed\n", "# export the path of DGGRID binary with the environment variable \"DGGRID_PATH\"\n", "os.environ['DGGRID_PATH']= \"/home/dick/micromamba/envs/xdggs/bin/dggrid\"" ] }, { "cell_type": "markdown", "id": "3572b4fb-3a71-4d4d-ae2b-340988b61611", "metadata": {}, "source": [ "#### Using rioxarray to load a GeoTiff into xarray dataset\n", "\n", "In this example, we use a sample collection prepared by the [Landscape and Geoinformatics Lab](https://landscape-geoinformatics.ut.ee/) of the University of Tartu, which is available on Zenodo.\n", "\n", "The collection consists of three GeoTiff files (DEM, TWI, Slope) located around Elva, Estonia. [](https://doi.org/10.5281/zenodo.18877265)" ] }, { "cell_type": "code", "execution_count": 2, "id": "c631bcf5-7747-4282-8cd2-5ff94c6fa891", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
<xarray.Dataset> Size: 8MB\n",
"Dimensions: (x: 1779, y: 1081)\n",
"Coordinates:\n",
" * x (x) float64 14kB 6.334e+05 6.335e+05 ... 6.512e+05 6.512e+05\n",
" * y (y) float64 9kB 6.468e+06 6.468e+06 ... 6.457e+06 6.457e+06\n",
" spatial_ref int64 8B 0\n",
"Data variables:\n",
" band_1 (y, x) float32 8MB ...\n",
"Attributes:\n",
" AREA_OR_POINT: Area<xarray.Dataset> Size: 23MB\n",
"Dimensions: (zone_id: 1923099)\n",
"Coordinates:\n",
" * zone_id (zone_id) int64 15MB 18804137500082175 ... 18669025747795967\n",
" spatial_ref int64 8B 0\n",
"Data variables:\n",
" band_1 (zone_id) float32 8MB 39.01 39.21 39.33 ... 109.7 110.0 110.2\n",
"Attributes:\n",
" AREA_OR_POINT: Area<xarray.Dataset> Size: 92kB\n",
"Dimensions: (zone_id: 7664)\n",
"Coordinates:\n",
" * zone_id (zone_id) int64 61kB 18667920867459071 ... 18805349754601471\n",
" spatial_ref int64 8B 0\n",
"Data variables:\n",
" band_1 (zone_id) float32 31kB 73.59 73.35 74.41 ... 68.39 68.5 68.68\n",
"Attributes:\n",
" AREA_OR_POINT: Area<xarray.Dataset> Size: 92kB\n",
"Dimensions: (cell_ids: 7664)\n",
"Coordinates:\n",
" * cell_ids (cell_ids) int64 61kB 18667920867459071 ... 18805349754601471\n",
" spatial_ref int64 8B 0\n",
"Data variables:\n",
" band_1 (cell_ids) float32 31kB dask.array<chunksize=(144,), meta=np.ndarray>\n",
"Indexes:\n",
" cell_ids IGEO7Index(level=11)\n",
"Attributes:\n",
" AREA_OR_POINT: Area<xarray.Dataset> Size: 44B\n",
"Dimensions: (cell_ids: 3)\n",
"Coordinates:\n",
" * cell_ids (cell_ids) int64 24B 18802036187332607 ... 18801924518182911\n",
" spatial_ref int64 8B 0\n",
"Data variables:\n",
" band_1 (cell_ids) float32 12B dask.array<chunksize=(3,), meta=np.ndarray>\n",
"Indexes:\n",
" cell_ids IGEO7Index(level=11)\n",
"Attributes:\n",
" AREA_OR_POINT: Area