This is the multi-page printable view of this section. .
Overview
Start here for the project model, architecture, and deliberate boundaries.
1 - What is async-geotiff?
async-geotiff is a Rust library for turning Cloud-Optimized GeoTIFFs (COGs)
into styled XYZ map tiles. It reads only the byte ranges needed for a tile,
decodes native TIFF blocks, optionally reprojects them, applies a rendering
style, and encodes the result.
Core capabilities
- Async COG access over HTTPS or any caller-configured
object_storebackend. - Shared, byte-bounded caching of decoded native TIFF blocks.
WebMercatorQuad(EPSG:3857) andWorldCRS84Quad(EPSG:4326) tile grids.- U8, U16, I16, U32, I32, F32, and F64 source pixels.
- Nearest, bilinear, cubic, cubic-spline, Lanczos, and average resampling.
- Rescaling, colormaps, RGB composition, color formulas, and arithmetic band math.
- PNG output, plus feature-gated WebP and JPEG output.
- Multi-asset mosaics backed by MosaicJSON, STAC, or a custom source.
What the library deliberately does not own
No GDAL runtime. TIFF I/O uses async-tiff and object_store. The default
proj feature uses the system libproj library only for coordinate
transformations that do not have a built-in fast path.
No web framework in the library. The Axum HTTP layer and MapLibre,
OpenLayers, and Leaflet viewers live under examples/. Applications can use
CogReader, Tiler, or MosaicTiler without inheriting Axum.
No credentials manager. When opening S3, GCS, MinIO, or another object store, the application configures authentication on the store and passes the ready object to the library.
No telemetry backend. The crate emits tracing spans and exposes cache
statistics. The application decides whether to export them to OpenTelemetry,
Prometheus, logs, or another system.
A tile fully outside the dataset or projection domain returns Ok(None).
The example HTTP server maps that result to 204 No Content.
2 - Architecture
The library separates asynchronous range I/O from CPU-heavy decode, warp, render, and encode work. Applications compose the public layers they need.
flowchart LR
Client[HTTP client or Rust caller] --> Style[TileStyle]
Client --> Tiler[Tiler]
Tiler --> Grid[TileMatrixSet]
Tiler --> Reader[CogReader]
Reader --> Store[object_store / HTTP range reads]
Reader <--> Cache[Shared BlockCache]
Reader --> CPU[CpuLimiter + spawn_blocking]
CPU --> Warp[Warp and resampling]
Warp --> Render[Rescale / colormap / composite]
Style --> Render
Render --> Encode[PNG / WebP / JPEG]
Encode --> Result[Option<Bytes>]
Mosaic[MosaicTiler] --> ReaderPool[ReaderPool]
ReaderPool --> Reader
Mosaic --> RenderMain components
| Component | Responsibility |
|---|---|
CogReader | Open a COG, read metadata and overviews, select and stitch native blocks, and sample points or windows. |
BlockCache | Share decoded native blocks across readers under one byte budget; coalesce concurrent cold fetches. |
Tiler | Plan a tile, choose an overview, read the source window, warp when required, and render encoded bytes. |
TileStyle | Parse and validate titiler-style query parameters before rendering. |
MosaicTiler | Find assets, open readers through a pool, warp each asset, reduce overlapping pixels, and render once. |
CpuLimiter | Bound CPU-heavy blocking work across readers and tilers. |
Tile data flow
TileCoordidentifies a tile in a supported TileMatrixSet.Tilercomputes the destination bounds and checks whether they intersect the source dataset.- It selects an overview whose ground resolution is appropriate for the requested tile.
CogReaderloads missing native blocks through range requests and reuses cached blocks where possible.- Same-CRS tiles use an affine fast path. Cross-CRS tiles use an inverse warp;
EPSG:4326 ↔ EPSG:3857 has a closed-form fast path, while other pairs require
the
projfeature. - The render pipeline applies nodata, scaling, optional band math, rescaling, colormaps or RGB composition, and the requested output encoder.
Concurrency model
Tokio drives asynchronous metadata and byte-range I/O. Decode, stitch, warp,
reduction, render, and encode jobs run through spawn_blocking behind a
semaphore. Applications can inject one Arc<BlockCache> across single-COG and
mosaic readers to avoid multiplying decoded-cache budgets. They can also inject
one CpuLimiter across non-mosaic CogReader/Tiler instances. Current
MosaicTiler uses its own internal limiter and cannot join that permit budget,
so mixed traffic has no automatic process-wide CPU cap.