CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-rasterio

Fast and direct raster I/O for use with Numpy and SciPy

Pending
Overview
Eval results
Files

transformations.mddocs/

Transformations

Affine transformations for converting between pixel and geographic coordinates. Supports creating transforms from bounds, origins, ground control points, and provides coordinate conversion utilities.

Capabilities

Affine Transformation Matrix

The core transformation class from the affine library, integrated into rasterio for geospatial coordinate transformations.

class Affine:
    """6-parameter affine transformation matrix."""
    
    def __init__(self, a, b, c, d, e, f):
        """
        Initialize affine transformation.
        
        Parameters (coefficients for the transformation):
        - a (float): x-scale factor
        - b (float): x-shear factor  
        - c (float): x-translation
        - d (float): y-shear factor
        - e (float): y-scale factor
        - f (float): y-translation
        
        Transformation: x' = a*x + b*y + c, y' = d*x + e*y + f
        """
    
    # Properties
    a: float  # x-scale
    b: float  # x-shear
    c: float  # x-translation
    d: float  # y-shear
    e: float  # y-scale
    f: float  # y-translation
    
    @classmethod
    def identity(cls):
        """Create identity transformation."""
    
    @classmethod
    def translation(cls, x, y):
        """Create translation transformation."""
    
    @classmethod
    def scale(cls, x, y=None):
        """Create scaling transformation."""
    
    @classmethod
    def rotation(cls, angle):
        """Create rotation transformation."""
    
    def __mul__(self, other):
        """Compose with another transformation."""
    
    def __invert__(self):
        """Get inverse transformation."""
    
    def determinant(self):
        """Calculate transformation determinant."""
    
    def is_identity(self):
        """Test if identity transformation."""
    
    def is_conformal(self):
        """Test if conformal (preserves angles)."""
    
    def is_orthonormal(self):
        """Test if orthonormal (preserves distances and angles)."""
    
    def is_rectilinear(self):
        """Test if rectilinear (axes aligned)."""

Transform Creation Functions

Utilities for creating affine transformations from various geographic parameters.

def from_bounds(west, south, east, north, width, height):
    """
    Create transform from geographic bounds and raster dimensions.
    
    Parameters:
    - west (float): Left (minimum x) coordinate
    - south (float): Bottom (minimum y) coordinate  
    - east (float): Right (maximum x) coordinate
    - north (float): Top (maximum y) coordinate
    - width (int): Raster width in pixels
    - height (int): Raster height in pixels
    
    Returns:
    Affine: Transformation matrix
    """

def from_origin(west, north, xsize, ysize):
    """
    Create transform from origin point and pixel sizes.
    
    Parameters:
    - west (float): Left (minimum x) coordinate
    - north (float): Top (maximum y) coordinate
    - xsize (float): Pixel width (x-direction)
    - ysize (float): Pixel height (y-direction, usually negative)
    
    Returns:
    Affine: Transformation matrix
    """

def from_gcps(gcps):
    """
    Create transform from ground control points.
    
    Parameters:
    - gcps (sequence): Ground control points as (row, col, x, y) tuples
    
    Returns:
    Affine: Transformation matrix
    """

Usage examples:

from rasterio.transform import from_bounds, from_origin, Affine

# Create transform from bounds
transform = from_bounds(-180, -90, 180, 90, 360, 180)
print(transform)  # Affine(1.0, 0.0, -180.0, 0.0, -1.0, 90.0)

# Create transform from origin and pixel size
transform = from_origin(-180, 90, 1.0, -1.0)  # 1-degree pixels

# Create transform from ground control points
gcps = [
    (0, 0, -180, 90),      # top-left
    (0, 360, 180, 90),     # top-right  
    (180, 0, -180, -90),   # bottom-left
    (180, 360, 180, -90)   # bottom-right
]
transform = from_gcps(gcps)

# Manual transform creation
transform = Affine(1.0, 0.0, -180.0,  # x-scale, x-shear, x-offset
                   0.0, -1.0, 90.0)    # y-shear, y-scale, y-offset

Coordinate Conversion

Functions for converting between pixel and geographic coordinate systems.

def xy(transform, rows, cols, offset='center'):
    """
    Convert pixel coordinates to geographic coordinates.
    
    Parameters:
    - transform (Affine): Geospatial transformation
    - rows (array-like): Row coordinates (y-axis, 0-based)
    - cols (array-like): Column coordinates (x-axis, 0-based)
    - offset (str): Pixel offset ('center', 'ul', 'ur', 'll', 'lr')
    
    Returns:
    tuple: (x_coords, y_coords) in geographic space
    """

def rowcol(transform, xs, ys, op=math.floor, precision=None):
    """
    Convert geographic coordinates to pixel coordinates.
    
    Parameters:
    - transform (Affine): Geospatial transformation
    - xs (array-like): X coordinates in geographic space
    - ys (array-like): Y coordinates in geographic space
    - op (callable): Rounding operation (math.floor, math.ceil, round)
    - precision (int): Decimal places for rounding
    
    Returns:
    tuple: (rows, cols) in pixel space
    """

Usage examples:

import rasterio
from rasterio.transform import xy, rowcol
import numpy as np

# Load dataset with transform
with rasterio.open('example.tif') as dataset:
    transform = dataset.transform
    
    # Convert pixel coordinates to geographic
    rows, cols = np.array([100, 200]), np.array([150, 250])
    x_coords, y_coords = xy(transform, rows, cols)
    print(f"Geographic coords: {list(zip(x_coords, y_coords))}")
    
    # Convert geographic coordinates to pixels
    x_geo, y_geo = [-120.5, -119.8], [45.2, 44.9]
    pixel_rows, pixel_cols = rowcol(transform, x_geo, y_geo)
    print(f"Pixel coords: {list(zip(pixel_rows, pixel_cols))}")
    
    # Different pixel offset options
    x_center, y_center = xy(transform, [100], [150], offset='center')
    x_corner, y_corner = xy(transform, [100], [150], offset='ul')  # upper-left

Bounds and Array Operations

Utilities for calculating bounds and working with transformed arrays.

def array_bounds(height, width, transform):
    """
    Calculate geographic bounds of raster array.
    
    Parameters:
    - height (int): Array height in pixels
    - width (int): Array width in pixels
    - transform (Affine): Geospatial transformation
    
    Returns:
    BoundingBox: Geographic bounds (west, south, east, north)
    """

def guard_transform(transform):
    """
    Validate transformation matrix.
    
    Parameters:
    - transform (Affine): Transformation to validate
    
    Returns:
    Affine: Validated transformation
    
    Raises:
    TransformError: If transform is invalid
    """

Usage examples:

from rasterio.transform import array_bounds, guard_transform

# Calculate bounds from array dimensions
height, width = 1000, 2000
transform = from_bounds(-180, -90, 180, 90, width, height)
bounds = array_bounds(height, width, transform)
print(f"Bounds: {bounds}")  # BoundingBox(left=-180, bottom=-90, right=180, top=90)

# Validate transformation
try:
    valid_transform = guard_transform(transform)
except TransformError as e:
    print(f"Invalid transform: {e}")

Specialized Transformations

Advanced transformation operations for specific use cases.

def tasseledcap(array, coeffs):
    """
    Apply Tasseled Cap transformation to multispectral data.
    
    Parameters:
    - array (numpy.ndarray): Input multispectral array
    - coeffs (numpy.ndarray): Transformation coefficients
    
    Returns:
    numpy.ndarray: Transformed array
    """

Usage example:

# Landsat Tasseled Cap transformation
landsat_coeffs = np.array([
    [0.3037, 0.2793, 0.4743, 0.5585, 0.5082, 0.1863],  # Brightness
    [-0.2848, -0.2435, -0.5436, 0.7243, 0.0840, -0.1800], # Greenness  
    [0.1509, 0.1973, 0.3279, 0.3406, -0.7112, -0.4572]    # Wetness
])

# Apply transformation to 6-band Landsat data
transformed = tasseledcap(landsat_bands, landsat_coeffs)

Transform Error Handling

Transformation operations can raise specific exceptions for invalid matrices or operations:

class TransformError(RasterioError):
    """Transformation related errors."""

Common error scenarios:

from rasterio.errors import TransformError

try:
    # Invalid transformation matrix (zero determinant)
    invalid_transform = Affine(0, 0, 0, 0, 0, 0)
    guard_transform(invalid_transform)
except TransformError as e:
    print(f"Invalid transform: {e}")

# Check transform validity
if transform.determinant() == 0:
    raise TransformError("Singular transformation matrix")

Install with Tessl CLI

npx tessl i tessl/pypi-rasterio

docs

cli.md

crs.md

data-types.md

dataset-io.md

features.md

index.md

processing.md

transformations.md

windowing.md

tile.json