Cloud Optimized GeoTIFF (COG) Creation Plugin for Rasterio
rio-cogeo is a Rasterio plugin that streamlines the creation and validation of Cloud Optimized GeoTIFF (COG) files. It intelligently handles critical COG specifications, including internal tiling, overview generation, and metadata ordering, ensuring geospatial data is optimized for efficient cloud storage and rapid web-based access. The library is actively maintained with consistent releases, serving as a vital tool in modern geospatial data pipelines.
Common errors
-
ERROR 1: blocksize exceeds raster width (or height)
cause This error typically occurs with very small input GeoTIFFs (e.g., some JPEG2000 preview files) where the internal block size defined in the source raster is larger than the actual band dimensions (width or height).fixFor such small rasters, consider using `rasterio.shutil.copy` directly without `rio-cogeo`, or if using `rio-cogeo` via the API, manually set a smaller `blocksize` in `dst_profile['blockxsize']` and `dst_profile['blockysize']` (e.g., 256 or 128) for the output. -
Command 'rio cogeo' not found (or similar CLI execution error)
cause The `rio` command-line interface is part of `rasterio`, and `cogeo` is a subcommand added by `rio-cogeo`. This error indicates that either `rasterio` or `rio-cogeo` is not installed, or the environment's `PATH` does not include the location of the `rio` executable.fixEnsure both `rasterio` and `rio-cogeo` are installed in your active Python environment: `pip install rasterio rio-cogeo`. If in a virtual environment, ensure it is activated. -
ERROR 1: Freezing Dataset, not enough space for overviews.
cause This error occurs when `rio-cogeo` attempts to create internal overviews or otherwise reorganize the GeoTIFF structure, but the output file system (or memory if processing in-memory) does not have sufficient contiguous space for the operation.fixIf working with large files, ensure you have ample free disk space in the output directory. If using `in_memory=True` (programmatically), you may be running out of RAM. Try setting `in_memory=False` or reducing the number of overview levels.
Warnings
- breaking Python 3.10 support was removed in rio-cogeo version 7.0.0. Users on Python 3.10 must upgrade their Python environment to 3.11 or newer.
- gotcha Using internal nodata values with lossy compression profiles (e.g., `jpeg`, `webp`) is generally not recommended as it can lead to unexpected visual artifacts or data loss around nodata regions. Internal masking or using an alpha band is often a more robust approach for lossy formats.
- gotcha When using the `--web-optimized` option without a nodata value, an alpha band, or an internal mask in the input dataset, the output COG may contain padded areas filled with black (0) data. This can lead to larger file sizes than expected.
- gotcha The `rio_cogeo.cog_translate` function or `rio cogeo create` CLI command might produce output raster pixel values that differ from the input if `ColorInterp` metadata is incorrectly defined or if lossy compression is applied and comparisons are made at overview resolutions (which are resampled).
Install
-
pip install rio-cogeo
Imports
- cog_translate
from rio_cogeo.cogeo import cog_translate
- cog_profiles
from rio_cogeo.profiles import cog_profiles
- cog_validate
from rio_cogeo.cogeo import cog_validate
Quickstart
# Create a dummy GeoTIFF for demonstration
import rasterio
import numpy as np
from rasterio.transform import from_bounds
width, height = 1000, 1000
transform = from_bounds(-10, 40, 10, 60, width, height)
with rasterio.open(
'input.tif',
'w',
driver='GTiff',
height=height,
width=width,
count=1,
dtype=np.uint8,
crs='EPSG:4326',
transform=transform,
) as dst:
dst.write(np.zeros((height, width), dtype=np.uint8), 1)
print("Created input.tif")
# --- Using rio-cogeo CLI ---
# Create a COG with DEFLATE compression (default profile)
# This command is run from the shell, not directly in Python
# import os
# os.system("rio cogeo create input.tif output_deflate.tif")
# print("Created output_deflate.tif")
# Create a COG with JPEG profile, add internal mask, and select first 3 bands
# os.system("rio cogeo create input.tif output_jpeg.tif -b 1 --add-mask --cog-profile jpeg")
# print("Created output_jpeg.tif")
# Validate a COG
# os.system("rio cogeo validate output_deflate.tif")
# print("Validated output_deflate.tif")
# Example of programmatic COG creation
from rasterio.io import MemoryFile
from rio_cogeo.cogeo import cog_translate
from rio_cogeo.profiles import cog_profiles
# Use a local file path for input
src_path = 'input.tif'
output_path_programmatic = 'output_programmatic.tif'
dst_profile = cog_profiles.get("deflate")
with rasterio.open(src_path) as src_dataset:
cog_translate(
src_path,
output_path_programmatic,
dst_profile,
config=dict(GDAL_NUM_THREADS='ALL_CPUS', GDAL_TIFF_OVR_BLOCKSIZE='128'),
overview_resampling='nearest',
web_optimized=False,
in_memory=False,
quiet=True,
# For real usage, consider `dst_kwargs` for profile overrides or `resampling` for overviews
)
print(f"Created {output_path_programmatic} programmatically.")
# Clean up dummy files
import os
os.remove('input.tif')
os.remove('output_programmatic.tif')
# os.remove('output_deflate.tif') # Uncomment if running CLI examples
# os.remove('output_jpeg.tif') # Uncomment if running CLI examples