Fast and direct raster I/O for use with Numpy and SciPy
—
Comprehensive data type support with validation and conversion utilities. Rasterio provides standardized data types for raster operations and includes enumerations for algorithms and metadata.
Rasterio supports a comprehensive set of numeric data types compatible with NumPy and GDAL:
# Boolean type
bool_: numpy.dtype # Boolean values (True/False)
# Unsigned integer types
ubyte: numpy.dtype # Unsigned 8-bit integer (0-255)
uint8: numpy.dtype # Unsigned 8-bit integer (0-255)
uint16: numpy.dtype # Unsigned 16-bit integer (0-65535)
uint32: numpy.dtype # Unsigned 32-bit integer (0-4294967295)
uint64: numpy.dtype # Unsigned 64-bit integer
# Signed integer types
int8: numpy.dtype # Signed 8-bit integer (-128 to 127)
int16: numpy.dtype # Signed 16-bit integer (-32768 to 32767)
int32: numpy.dtype # Signed 32-bit integer (-2147483648 to 2147483647)
int64: numpy.dtype # Signed 64-bit integer
# Floating point types
float32: numpy.dtype # 32-bit floating point (single precision)
float64: numpy.dtype # 64-bit floating point (double precision)
# Complex number types
complex_: numpy.dtype # Complex number type
complex64: numpy.dtype # 64-bit complex (32-bit real + 32-bit imaginary)
complex128: numpy.dtype # 128-bit complex (64-bit real + 64-bit imaginary)Usage examples:
import rasterio.dtypes
import numpy as np
# Access rasterio data types
print(rasterio.dtypes.uint8) # <class 'numpy.uint8'>
print(rasterio.dtypes.float32) # <class 'numpy.float32'>
# Create arrays with specific types
data_uint8 = np.array([0, 127, 255], dtype=rasterio.dtypes.uint8)
data_float32 = np.array([0.0, 127.5, 255.9], dtype=rasterio.dtypes.float32)
# Use in dataset creation
profile = {
'driver': 'GTiff',
'dtype': rasterio.dtypes.uint16, # Use rasterio data type
'width': 100,
'height': 100,
'count': 1,
'crs': 'EPSG:4326'
}Functions for validating and working with data types in raster operations:
def check_dtype(dt):
"""
Validate data type compatibility with GDAL.
Parameters:
- dt (numpy.dtype or str): Data type to check
Returns:
bool: True if compatible with GDAL
"""
def get_minimum_dtype(values, have_nodata=False):
"""
Determine minimum required data type for values.
Parameters:
- values (array-like): Input values to analyze
- have_nodata (bool): Whether nodata value needs to be represented
Returns:
numpy.dtype: Minimum data type that can represent all values
"""
def validate_dtype(dataset, dtype):
"""
Validate data type for dataset operations.
Parameters:
- dataset (DatasetReader): Input dataset
- dtype (numpy.dtype): Target data type
Returns:
bool: True if conversion is valid
Raises:
ValueError: If dtype is incompatible
"""Usage examples:
from rasterio.dtypes import check_dtype, get_minimum_dtype, validate_dtype
import numpy as np
# Check data type compatibility
print(check_dtype('uint8')) # True
print(check_dtype('float32')) # True
print(check_dtype('object')) # False (not supported by GDAL)
# Determine minimum data type needed
values = [0, 127, 255]
min_dtype = get_minimum_dtype(values)
print(min_dtype) # uint8
# With negative values
values_signed = [-100, 0, 127]
min_dtype_signed = get_minimum_dtype(values_signed)
print(min_dtype_signed) # int16
# With nodata consideration
values_with_nodata = [0, 127, 254] # Need to reserve 255 for nodata
min_dtype_nodata = get_minimum_dtype(values_with_nodata, have_nodata=True)
print(min_dtype_nodata) # uint8 (255 available for nodata)
# Validate conversion
with rasterio.open('input.tif') as dataset:
# Check if we can convert to different data type
can_convert_uint8 = validate_dtype(dataset, 'uint8')
can_convert_float32 = validate_dtype(dataset, 'float32')Enumeration of resampling algorithms available for raster operations:
class Resampling(Enum):
"""Resampling algorithms for raster operations."""
nearest = 'nearest' # Nearest neighbor interpolation
bilinear = 'bilinear' # Bilinear interpolation
cubic = 'cubic' # Cubic convolution
cubic_spline = 'cubic_spline' # Cubic spline interpolation
lanczos = 'lanczos' # Lanczos windowed sinc interpolation
average = 'average' # Average of contributing pixels
mode = 'mode' # Most common value (mode)
gauss = 'gauss' # Gaussian kernel
max = 'max' # Maximum value
min = 'min' # Minimum value
med = 'med' # Median value
q1 = 'q1' # First quartile (25th percentile)
q3 = 'q3' # Third quartile (75th percentile)
sum = 'sum' # Sum of values
rms = 'rms' # Root mean squareEnumeration for color interpretation of raster bands:
class ColorInterp(Enum):
"""Color interpretation for raster bands."""
undefined = 'undefined' # Undefined interpretation
gray = 'gray' # Grayscale
palette = 'palette' # Palette/colormapped
red = 'red' # Red band of RGB
green = 'green' # Green band of RGB
blue = 'blue' # Blue band of RGB
alpha = 'alpha' # Alpha/transparency band
hue = 'hue' # Hue band of HSV
saturation = 'saturation' # Saturation band of HSV
lightness = 'lightness' # Lightness band of HSL
cyan = 'cyan' # Cyan band of CMYK
magenta = 'magenta' # Magenta band of CMYK
yellow = 'yellow' # Yellow band of CMYK
black = 'black' # Black band of CMYKEnumeration for mask flag values indicating pixel validity:
class MaskFlags(Enum):
"""Mask flag values for pixel validity."""
all_valid = 'all_valid' # All pixels valid
per_dataset = 'per_dataset' # Per-dataset mask
alpha = 'alpha' # Alpha band mask
nodata = 'nodata' # NoData maskEnumeration for photometric interpretation of imagery:
class PhotometricInterp(Enum):
"""Photometric interpretation values."""
miniswhite = 'miniswhite' # Minimum value is white
minisblack = 'minisblack' # Minimum value is black
rgb = 'rgb' # RGB color model
palette = 'palette' # Palette color model
mask = 'mask' # Transparency mask
separated = 'separated' # Color separations (CMYK)
ycbcr = 'ycbcr' # YCbCr color model
cielab = 'cielab' # CIE L*a*b* color model
icclab = 'icclab' # ICC L*a*b* color model
itulab = 'itulab' # ITU L*a*b* color modelUsage examples for enumerations:
from rasterio.enums import Resampling, ColorInterp, MaskFlags, PhotometricInterp
# Use resampling in operations
with rasterio.open('input.tif') as src:
# Read with resampling
data = src.read(
out_shape=(src.count, 500, 500), # Resample to 500x500
resampling=Resampling.cubic # High-quality interpolation
)
# Set color interpretation when writing
profile = {
'driver': 'GTiff',
'dtype': 'uint8',
'width': 100, 'height': 100, 'count': 3,
'photometric': PhotometricInterp.rgb.value
}
with rasterio.open('rgb_image.tif', 'w', **profile) as dst:
# Set individual band color interpretation
dst.colorinterp = [ColorInterp.red, ColorInterp.green, ColorInterp.blue]
# Write RGB data
dst.write(red_band, 1)
dst.write(green_band, 2)
dst.write(blue_band, 3)
# Check mask flags
with rasterio.open('dataset.tif') as src:
mask_flags = src.mask_flag_enums
has_nodata = MaskFlags.nodata in mask_flags
has_alpha = MaskFlags.alpha in mask_flagsCommon patterns for working with different data types:
# Convert between data types safely
def safe_convert(data, target_dtype, nodata_in=None, nodata_out=None):
"""Safely convert array to target data type."""
# Get data type info
target_info = np.iinfo(target_dtype) if np.issubdtype(target_dtype, np.integer) else np.finfo(target_dtype)
# Handle nodata values
if nodata_in is not None:
valid_mask = data != nodata_in
data = data[valid_mask]
# Clip to target range
if hasattr(target_info, 'min') and hasattr(target_info, 'max'):
data_clipped = np.clip(data, target_info.min, target_info.max)
else:
data_clipped = data
# Convert
converted = data_clipped.astype(target_dtype)
# Restore nodata
if nodata_in is not None and nodata_out is not None:
result = np.full_like(converted, nodata_out, dtype=target_dtype)
result[valid_mask] = converted
return result
return converted
# Scale data to different ranges
def scale_to_uint8(data, min_val=None, max_val=None):
"""Scale data to 0-255 range for uint8."""
if min_val is None:
min_val = data.min()
if max_val is None:
max_val = data.max()
# Scale to 0-1
scaled = (data - min_val) / (max_val - min_val)
# Scale to 0-255 and convert
return (scaled * 255).astype(np.uint8)
# Example usage
with rasterio.open('float_data.tif') as src:
float_data = src.read(1)
# Convert to uint8 for visualization
uint8_data = scale_to_uint8(float_data)
# Save as uint8
profile = src.profile.copy()
profile['dtype'] = 'uint8'
with rasterio.open('uint8_output.tif', 'w', **profile) as dst:
dst.write(uint8_data, 1)Install with Tessl CLI
npx tessl i tessl/pypi-rasterio