{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Coordinate Reference System Management" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "xarray \"... is particularly tailored to working with netCDF files, which were the source of xarray’s data model...\" (http://xarray.pydata.org).\n", "\n", "For netCDF files, the GIS community uses CF conventions (http://cfconventions.org/).\n", "\n", "Additionally, GDAL also supports these attributes:\n", "\n", "- spatial_ref (Well Known Text)\n", "- GeoTransform (GeoTransform array)\n", "\n", "References:\n", "\n", "- Esri: https://pro.arcgis.com/en/pro-app/latest/help/data/multidimensional/spatial-reference-for-netcdf-data.htm\n", "- GDAL: https://gdal.org/drivers/raster/netcdf.html#georeference\n", "- pyproj: https://pyproj4.github.io/pyproj/stable/build_crs_cf.html\n", "\n", "Operations on xarray objects can cause data loss. Due to this, rioxarray writes and expects the spatial reference information to exist in the coordinates." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Conventions\n", "\n", "rioxarray supports multiple conventions for storing geospatial metadata. The convention system provides a flexible way to read and write CRS and transform information.\n", "\n", "### Supported Conventions\n", "\n", "- **CF (Climate and Forecasts)**: The default convention, using `grid_mapping` coordinates with attributes like `spatial_ref`, `crs_wkt`, and `GeoTransform`. This is the standard for netCDF files in the geospatial community.\n", "\n", "### How Conventions Work\n", "\n", "- **Reading**: If a convention is set globally, that convention is tried **first** for better performance. If not found, other conventions are tried as fallback. This allows you to optimize reads when you know the data format.\n", "- **Writing**: Uses the global `convention` setting (default: CF) or a per-method `convention` parameter.\n", "\n", "### Setting the Convention\n", "\n", "You can set the convention globally using `set_options()`:\n", "\n", "```python\n", "from rioxarray import set_options\n", "from rioxarray.enum import Convention\n", "\n", "# Set globally - reads will try CF first, writes will use CF\n", "set_options(convention=Convention.CF)\n", "\n", "# Or use as a context manager\n", "with set_options(convention=Convention.CF):\n", " # CF convention is tried first when reading\n", " crs = data.rio.crs\n", " # CF convention is used for writing\n", " data.rio.write_crs(\"EPSG:4326\", inplace=True)\n", "```\n", "\n", "Or specify the convention per-method (for writing only):\n", "\n", "```python\n", "from rioxarray.enum import Convention\n", "\n", "data.rio.write_crs(\"EPSG:4326\", convention=Convention.CF, inplace=True)\n", "```\n", "\n", "#### API Documentation\n", "\n", "- [rioxarray.set_options](../rioxarray.rst#rioxarray.set_options)\n", "- [rioxarray.enum.Convention](../rioxarray.rst#rioxarray.enum.Convention)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Accessing the CRS object" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you have opened a dataset and the Coordinate Reference System (CRS) can be determined, you can access it via the `rio.crs` accessor.\n", "\n", "#### Search order for the CRS (DataArray and Dataset):\n", "1. Look in `encoding` of your data array for the `grid_mapping` coordinate name.\n", " Inside the `grid_mapping` coordinate first look for `spatial_ref` then `crs_wkt` and lastly the CF grid mapping attributes.\n", " This is in line with the Climate and Forecast (CF) conventions for storing the CRS as well as GDAL netCDF conventions.\n", "2. Look in the `crs` attribute and load in the CRS from there. This is for backwards compatibility with `xarray.open_rasterio`, which is deprecated since version 0.20.0. We recommend using `rioxarray.open_rasterio` instead.\n", "\n", "The value for the `crs` is anything accepted by `rasterio.crs.CRS.from_user_input()`\n", "\n", "#### Search order for the CRS for Dataset:\n", "If the CRS is not found using the search methods above, it also searches the `data_vars` and uses the\n", "first valid CRS found.\n", "\n", "#### decode_coords=\"all\"\n", "\n", "If you use one of xarray's open methods such as ``xarray.open_dataset`` to load netCDF files\n", "with the default engine, it is recommended to use `decode_coords=\"all\"`. This will load the grid mapping\n", "variable into coordinates for compatibility with rioxarray.\n", "\n", "#### API Documentation\n", "\n", "- [rio.write_crs()](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.write_crs)\n", "- [rio.crs](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.crs)\n", "- [rio.estimate_utm_crs()](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.estimate_utm_crs)\n", "- [rio.set_spatial_dims()](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.set_spatial_dims)\n", "- [rio.write_coordinate_system()](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.write_coordinate_system)\n", "- [rio.write_transform()](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.write_transform)\n", "- [rio.transform()](../rioxarray.rst#rioxarray.rioxarray.XRasterBase.transform)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import rioxarray # activate the rio accessor\n", "import xarray\n", "from affine import Affine" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rds = xarray.open_dataset(\"../../test/test_data/input/PLANET_SCOPE_3D.nc\", decode_coords=\"all\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'units': 'DN', 'nodata': 0.0}" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rds.green.attrs" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
<xarray.DataArray 'spatial_ref' ()>\n",
"array(0)\n",
"Coordinates:\n",
" spatial_ref int64 0\n",
"Attributes:\n",
" spatial_ref: PROJCS["WGS 84 / UTM zone 22S",GEOGCS["WGS 84",DATUM["WGS_1...array(0)
array(0)
<xarray.DataArray 'spatial_ref' ()>\n",
"array(0)\n",
"Coordinates:\n",
" spatial_ref int64 0\n",
"Attributes:\n",
" crs_wkt: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["...\n",
" semi_major_axis: 6378137.0\n",
" semi_minor_axis: 6356752.314245179\n",
" inverse_flattening: 298.257223563\n",
" reference_ellipsoid_name: WGS 84\n",
" longitude_of_prime_meridian: 0.0\n",
" prime_meridian_name: Greenwich\n",
" geographic_crs_name: WGS 84\n",
" grid_mapping_name: latitude_longitude\n",
" spatial_ref: GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["...array(0)
array(0)