# Library usage

> Open a COG and render a tile directly from Rust.

---

LLMS index: [llms.txt](/llms.txt)

---

The repository currently sets `publish = false`, so another local project uses
a path dependency while developing. Create the application next to the clone,
then replace the relative path if your directories differ:

```bash
# Starting inside the async-geotiff-rs checkout:
cd ..
cargo new async-geotiff-demo
cd async-geotiff-demo
```

```toml
[dependencies]
async-geotiff = { path = "../async-geotiff-rs" }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
```

To avoid the system `libproj` dependency while retaining the mosaic APIs used
by the example server, set `default-features = false, features = ["mosaic"]` on
the path dependency. General CRS transformations will then be unavailable.

## Render one tile {#render-one-tile}

```rust
use std::sync::Arc;

use async_geotiff::io::cog::CogReader;
use async_geotiff::style::TileStyle;
use async_geotiff::tiler::Tiler;
use async_geotiff::tms::{TileCoord, TileMatrixSet};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let url = "https://raw.githubusercontent.com/cogeotiff/rio-tiler/0b08b7f35a8b639cee2f35a0cb565034f7b55bfd/tests/fixtures/cog.tif";
    let reader = Arc::new(
        CogReader::builder()
            .source_id(url)
            .open_http(url)
            .await?,
    );
    let tiler = Tiler::new(reader);
    let style = TileStyle::from_query("colormap_name=viridis&rescale=0,3000")?;
    let coord = TileCoord {
        tms: TileMatrixSet::WebMercatorQuad,
        z: 0,
        x: 0,
        y: 0,
    };

    if let Some(bytes) = tiler.tile(coord, &style).await? {
        std::fs::write("tile.png", bytes)?;
    } else {
        eprintln!("tile is outside the dataset or projection domain");
    }
    Ok(())
}
```

`TileStyle::from_query` accepts the same query string used by the example HTTP
server, without the leading `?`. Save the example as `src/main.rs`, then run
`cargo run`. The pinned URL is a small, range-capable test COG; replace it
after verifying the integration.

## Share memory and CPU budgets {#shared-budgets}

For multiple COGs, create one block cache and give every reader a stable,
distinct source ID:

```rust
use std::sync::Arc;

use async_geotiff::io::block_cache::BlockCache;
use async_geotiff::io::cache::CacheConfig;
use async_geotiff::io::cog::CogReader;

let cache = Arc::new(BlockCache::new(CacheConfig::default()));

let first = CogReader::builder()
    .source_id("scene-a")
    .block_cache(Arc::clone(&cache))
    .open_http("https://example.com/a.tif")
    .await?;

let second = CogReader::builder()
    .source_id("scene-b")
    .block_cache(Arc::clone(&cache))
    .open_http("https://example.com/b.tif")
    .await?;
```

Readers with the same cache share its default 512 MiB budget. The source ID is
part of the cache key: reuse it only for the same logical COG.
