1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
"""
Core convention methods for rioxarray.
"""
from typing import Optional, Union
import rasterio.crs
import xarray
from affine import Affine
from rioxarray._convention._base import ConventionProtocol
from rioxarray._convention.cf import CFConvention
from rioxarray._convention.zarr import ZarrConvention
from rioxarray._options import CONVENTION, get_option
from rioxarray.crs import crs_from_user_input
from rioxarray.enum import Convention
# Convention classes mapped by Convention enum
_CONVENTION_MODULES: dict[Convention, ConventionProtocol] = {
Convention.CF: CFConvention, # type: ignore[dict-item]
Convention.ZARR: ZarrConvention, # type: ignore[dict-item]
}
def _get_convention(convention: Convention | None) -> ConventionProtocol:
"""
Get the convention module for writing.
Parameters
----------
convention : Convention enum value or None
The convention to use. If None, uses the global default.
Returns
-------
ConventionProtocol
The module implementing the convention
"""
if convention is None:
convention = get_option(CONVENTION) or Convention.CF
convention = Convention(convention)
return _CONVENTION_MODULES[convention]
def read_crs_auto(
obj: Union[xarray.Dataset, xarray.DataArray],
**kwargs,
) -> Optional[rasterio.crs.CRS]:
"""
Auto-detect and read CRS by trying convention readers.
If a convention is set globally via set_options(), that convention
is tried first for better performance. Then other conventions are
tried as fallback.
Parameters
----------
obj : xarray.Dataset or xarray.DataArray
Object to read CRS from
**kwargs
Convention-specific parameters (e.g., grid_mapping for CF)
Returns
-------
rasterio.crs.CRS or None
CRS object, or None if not found in any convention
"""
# Try the configured convention first (if set)
configured_convention = get_option(CONVENTION)
if configured_convention is not None:
result = _CONVENTION_MODULES[configured_convention].read_crs(obj, **kwargs)
if result is not None:
return result
# Try all other conventions
for conv_enum, convention in _CONVENTION_MODULES.items():
if conv_enum == configured_convention:
continue # Already tried this one
result = convention.read_crs(obj, **kwargs)
if result is not None:
return result
# Legacy fallback: look in attrs for 'crs' (not part of any convention)
try:
return crs_from_user_input(obj.attrs["crs"])
except KeyError:
pass
return None
def read_transform_auto(
obj: Union[xarray.Dataset, xarray.DataArray],
**kwargs,
) -> Optional[Affine]:
"""
Auto-detect and read transform by trying convention readers.
If a convention is set globally via set_options(), that convention
is tried first for better performance. Then other conventions are
tried as fallback.
Parameters
----------
obj : xarray.Dataset or xarray.DataArray
Object to read transform from
**kwargs
Convention-specific parameters (e.g., grid_mapping for CF)
Returns
-------
affine.Affine or None
Transform object, or None if not found in any convention
"""
# Try the configured convention first (if set)
configured_convention = get_option(CONVENTION)
if configured_convention is not None:
result = _CONVENTION_MODULES[configured_convention].read_transform(
obj, **kwargs
)
if result is not None:
return result
# Try all other conventions
for conv_enum, convention in _CONVENTION_MODULES.items():
if conv_enum == configured_convention:
continue # Already tried this one
result = convention.read_transform(obj, **kwargs)
if result is not None:
return result
# Legacy fallback: look in attrs for 'transform' (not part of any convention)
try:
return Affine(*obj.attrs["transform"][:6])
except KeyError:
pass
return None
def read_spatial_dimensions_auto(
obj: Union[xarray.Dataset, xarray.DataArray],
) -> Optional[tuple[str, str]]:
"""
Auto-detect and read spatial dimensions by trying convention readers.
If a convention is set globally via set_options(), that convention
is tried first for better performance. Then other conventions are
tried as fallback.
Parameters
----------
obj : xarray.Dataset or xarray.DataArray
Object to read spatial dimensions from
Returns
-------
tuple of (y_dim, x_dim) or None
Tuple of dimension names, or None if not found in any convention
"""
# Try the configured convention first (if set)
configured_convention = get_option(CONVENTION)
if configured_convention is not None:
result = _CONVENTION_MODULES[configured_convention].read_spatial_dimensions(obj)
if result is not None:
return result
# Try all other conventions
for conv_enum, convention in _CONVENTION_MODULES.items():
if conv_enum == configured_convention:
continue # Already tried this one
result = convention.read_spatial_dimensions(obj)
if result is not None:
return result
return None
|