CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-rioxarray

Geospatial xarray extension powered by rasterio for raster data manipulation and analysis

Pending
Overview
Eval results
Files

coordinate-systems.mddocs/

Coordinate Systems

Comprehensive coordinate reference system (CRS) management including setting, transforming, and reprojecting coordinate systems. These capabilities enable working with geospatial data across different projections and coordinate systems.

Capabilities

CRS Properties and Access

Get and set coordinate reference system information for DataArrays and Datasets.

@property
def crs(self) -> Optional[rasterio.crs.CRS]:
    """
    Retrieve projection from xarray Dataset or DataArray.
    
    Returns:
    rasterio.crs.CRS or None: The coordinate reference system
    """

Usage Examples

import rioxarray
import xarray as xr

# Open raster with CRS
da = rioxarray.open_rasterio('geo_file.tif')
print(da.rio.crs)  # <rasterio.crs.CRS object>

# Check if data has CRS
if da.rio.crs is not None:
    print(f"CRS: {da.rio.crs}")
else:
    print("No CRS defined")

# Get CRS string representation
print(da.rio.crs.to_string())  # 'EPSG:4326'

Setting CRS

Set coordinate reference system without modifying the underlying data coordinates.

def set_crs(
    self, 
    input_crs: Any, 
    inplace: bool = True
) -> Union[xarray.Dataset, xarray.DataArray]:
    """
    Set the CRS value for the Dataset/DataArray without modifying
    the dataset/data array.

    Parameters:
    - input_crs: CRS in various formats (EPSG code, PROJ string, CRS object, etc.)
    - inplace: If True, modify in place and return None (default: True)

    Returns:
    Dataset/DataArray with CRS set (if inplace=False)
    """

Usage Examples

import rioxarray

# Open data without CRS
da = rioxarray.open_rasterio('file_no_crs.tif')

# Set CRS using EPSG code
da.rio.set_crs('EPSG:4326')

# Set CRS using different formats
da.rio.set_crs(4326)  # EPSG integer
da.rio.set_crs('+proj=longlat +datum=WGS84')  # PROJ string
da.rio.set_crs({'init': 'epsg:4326'})  # Dictionary format

# Create new object with CRS (inplace=False)
da_with_crs = da.rio.set_crs('EPSG:3857', inplace=False)

Writing CRS to File

Write CRS information to dataset attributes for file output.

def write_crs(
    self,
    input_crs: Optional[Any] = None,
    grid_mapping_name: Optional[str] = None,
    inplace: bool = False
) -> Union[xarray.Dataset, xarray.DataArray]:
    """
    Write the CRS to the dataset as a coordinate variable.

    Parameters:
    - input_crs: CRS to write (uses current CRS if None)
    - grid_mapping_name: Name for grid mapping variable
    - inplace: If True, modify in place

    Returns:
    Dataset/DataArray with CRS written to attributes
    """

Usage Examples

import rioxarray

da = rioxarray.open_rasterio('file.tif')

# Write current CRS to attributes
da_with_attrs = da.rio.write_crs(inplace=False)

# Write specific CRS
da_with_attrs = da.rio.write_crs('EPSG:4326', inplace=False)

# Custom grid mapping name
da_with_attrs = da.rio.write_crs(
    grid_mapping_name='my_projection', 
    inplace=False
)

UTM CRS Estimation

Automatically estimate the appropriate UTM coordinate system based on data bounds.

def estimate_utm_crs(self, datum_name: str = "WGS 84") -> rasterio.crs.CRS:
    """
    Returns the estimated UTM CRS based on the bounds of the dataset.

    Parameters:
    - datum_name: Datum name for UTM CRS (default: "WGS 84")

    Returns:
    rasterio.crs.CRS: Estimated UTM CRS

    Raises:
    MissingCRS: If dataset has no CRS defined
    """

Usage Examples

import rioxarray

# Open geographic data (lat/lon)
da = rioxarray.open_rasterio('geographic_data.tif')  # EPSG:4326

# Estimate best UTM zone
utm_crs = da.rio.estimate_utm_crs()
print(utm_crs)  # UTM Zone 33N or similar

# Estimate with different datum
utm_crs = da.rio.estimate_utm_crs(datum_name="NAD83")

# Use estimated CRS for reprojection
reprojected = da.rio.reproject(utm_crs)

Transform Operations

Get and manipulate the affine transformation matrix that defines the pixel-to-coordinate mapping.

def transform(self, recalc: bool = False) -> rasterio.Affine:
    """
    Get the affine transformation matrix.

    Parameters:
    - recalc: Recalculate transform from coordinates (default: False)

    Returns:
    rasterio.Affine: The affine transformation matrix
    """

def write_transform(self, transform: Optional[rasterio.Affine] = None, inplace: bool = False):
    """
    Write the affine transform to the dataset.

    Parameters:
    - transform: Affine transform to write (uses current if None)
    - inplace: If True, modify in place

    Returns:
    Dataset/DataArray with transform written to attributes
    """

Usage Examples

import rioxarray
from rasterio.transform import from_bounds

da = rioxarray.open_rasterio('file.tif')

# Get current transform
transform = da.rio.transform()
print(transform)  # Affine transformation matrix

# Create custom transform
new_transform = from_bounds(-180, -90, 180, 90, 360, 180)

# Apply custom transform
da_transformed = da.rio.write_transform(new_transform, inplace=False)

Resolution Information

Get pixel resolution from the affine transformation matrix.

def resolution(self, recalc: bool = False) -> tuple[float, float]:
    """
    Determine the resolution of the grid.
    If the transformation has rotation, the sign of the resolution is lost.

    Parameters:
    - recalc: Recalculate resolution from coordinates (default: False)

    Returns:
    tuple[float, float]: (x_resolution, y_resolution)
    """

Usage Examples

import rioxarray

da = rioxarray.open_rasterio('file.tif')

# Get pixel resolution
x_res, y_res = da.rio.resolution()
print(f"X resolution: {x_res}, Y resolution: {y_res}")

# Recalculate from coordinates
x_res, y_res = da.rio.resolution(recalc=True)

Bounds Operations

Get spatial bounds and transform bounds between coordinate systems.

def bounds(self, recalc: bool = False) -> tuple[float, float, float, float]:
    """
    Get the spatial bounds of the dataset.

    Parameters:
    - recalc: Recalculate bounds from coordinates (default: False)

    Returns:
    tuple: (left, bottom, right, top) bounds
    """

def transform_bounds(
    self, 
    dst_crs: Any, 
    *, 
    densify_pts: int = 21, 
    recalc: bool = False
) -> tuple[float, float, float, float]:
    """
    Transform bounds from src_crs to dst_crs.

    Parameters:
    - dst_crs: Destination CRS
    - densify_pts: Number of points to use for densification (default: 21)
    - recalc: Recalculate source bounds (default: False)

    Returns:
    tuple: Transformed (left, bottom, right, top) bounds
    """

Usage Examples

import rioxarray

da = rioxarray.open_rasterio('file.tif')  # UTM coordinates

# Get current bounds
left, bottom, right, top = da.rio.bounds()
print(f"Bounds: {left}, {bottom}, {right}, {top}")

# Transform bounds to geographic coordinates
geo_bounds = da.rio.transform_bounds('EPSG:4326')
print(f"Geographic bounds: {geo_bounds}")

# Transform with more densification points
detailed_bounds = da.rio.transform_bounds('EPSG:4326', densify_pts=50)

Grid Mapping Operations

Write grid mapping information for CF-compliant NetCDF files.

def write_grid_mapping(
    self,
    grid_mapping_name: Optional[str] = None,
    inplace: bool = False
) -> Union[xarray.Dataset, xarray.DataArray]:
    """
    Write the grid mapping to the dataset.

    Parameters:
    - grid_mapping_name: Name for the grid mapping variable
    - inplace: If True, modify in place

    Returns:
    Dataset/DataArray with grid mapping written
    """

def write_coordinate_system(self, inplace: bool = False):
    """
    Write the coordinate system information to the dataset.

    Parameters:
    - inplace: If True, modify in place

    Returns:
    Dataset/DataArray with coordinate system information
    """

Usage Examples

import rioxarray

da = rioxarray.open_rasterio('projected_data.tif')

# Write grid mapping for CF compliance
cf_da = da.rio.write_grid_mapping(inplace=False)

# Write complete coordinate system
coord_da = da.rio.write_coordinate_system(inplace=False)

# Save as CF-compliant NetCDF
cf_da.to_netcdf('cf_compliant.nc')

CRS Utility Functions

Helper functions for working with coordinate reference systems.

def crs_from_user_input(crs_input: Any) -> rasterio.crs.CRS:
    """
    Return a rasterio.crs.CRS from user input.
    
    Handles various CRS input formats and transitions between GDAL versions.

    Parameters:
    - crs_input: CRS in various formats

    Returns:
    rasterio.crs.CRS: Standardized CRS object
    """

Usage Examples

from rioxarray.crs import crs_from_user_input

# Convert various CRS formats to standard CRS object
crs1 = crs_from_user_input('EPSG:4326')
crs2 = crs_from_user_input(4326)
crs3 = crs_from_user_input('+proj=longlat +datum=WGS84')
crs4 = crs_from_user_input({'init': 'epsg:4326'})

# All return equivalent rasterio.crs.CRS objects
print(crs1 == crs2 == crs3 == crs4)  # True

Common CRS Operations

CRS Validation and Conversion

import rioxarray

da = rioxarray.open_rasterio('data.tif')

# Check if CRS is geographic (lat/lon)
is_geographic = da.rio.crs.is_geographic
print(f"Is geographic: {is_geographic}")

# Check if CRS is projected
is_projected = da.rio.crs.is_projected  
print(f"Is projected: {is_projected}")

# Get CRS as different formats
epsg_code = da.rio.crs.to_epsg()  # EPSG integer or None
proj_string = da.rio.crs.to_proj4()  # PROJ.4 string
wkt = da.rio.crs.to_wkt()  # Well-Known Text

Working with Different CRS Formats

import rioxarray

da = rioxarray.open_rasterio('file.tif')

# Set CRS using various input formats
da.rio.set_crs('EPSG:4326')  # EPSG string
da.rio.set_crs(4326)  # EPSG integer  
da.rio.set_crs('+proj=utm +zone=33 +datum=WGS84')  # PROJ string
da.rio.set_crs({'init': 'epsg:32633'})  # Dictionary

# Use with CRS objects
from rasterio.crs import CRS
crs_obj = CRS.from_epsg(4326)
da.rio.set_crs(crs_obj)

Install with Tessl CLI

npx tessl i tessl/pypi-rioxarray

docs

config-utilities.md

coordinate-systems.md

data-management.md

index.md

io-operations.md

spatial-operations.md

tile.json