跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

使用指南

应用样式、组合镶嵌,并在生产环境中运行 async-geotiff。

围绕应用最常组合的能力提供任务导向指南。

1 - 样式与波段计算

选择波段、拉伸数值、应用色带,并通过表达式生成派生波段。

Rust API 与示例服务的查询字符串使用同一个 TileStyle 模型。样式会在昂贵的 COG 读取和渲染工作之前完成校验。

常用配方

三波段自然色 RGB:

bidx=1&bidx=2&bidx=3&rescale=0,3000&rescale=0,3000&rescale=0,3000

单波段色带:

bidx=1&colormap_name=viridis&rescale=0,3000

百分位拉伸:

stretch=percent&pc=2,98

下采样使用 average,重投影使用 bilinear:

resampling=average&reproject=bilinear

拉伸行为

对于非 U8 数据,有效值域按以下优先级选择:

  1. 显式的 rescale=min,max
  2. 指定的 stretch 模式。
  3. 两者都不存在时使用 stretch=stddev&sigma=2.0

U8 RGB 保留 0–255 快速路径。数据统计优先来自内嵌 STATISTICS_* 标签;如果没有, 则采样最高概览层一次并缓存估算结果。

算术表达式

expression 生成一个派生输出波段,波段编号从 1 开始:

expression=(b5-b4)/(b5+b4)&rescale=-1,1&colormap_name=viridis

这个 NDVI 公式只适用于所选 COG 的第 5 波段为近红外、第 4 波段为红光的情况。库不会 根据波段编号推断光谱含义;使用前必须检查资产元数据并调整引用。预渲染的 STAC visual 资产也不会自动满足此示例。

放入 URL 时请对 /+ 进行百分号编码:

curl --output ndvi.png \
  'http://127.0.0.1:8080/tiles/WebMercatorQuad/0/0/0.png?expression=(b5-b4)%2F(b5%2Bb4)&rescale=-1,1&colormap_name=viridis'

语法支持有限十进制数、括号、二元 +-*/ 和一元负号。乘除优先于 加减,不支持科学计数法。

expression 不能与 bidxcolor_formula 同时使用,并且最多接受一个 rescale。nodata 输入、除零和其他非有限结果会变为透明像元。输入上限为 4096 字节、256 个 token 和 128 层嵌套。

颜色公式

支持的 rio-color 子集按从左到右的顺序应用:

  • gamma
  • sigmoidal
  • saturation

例如:

color_formula=gamma RGB 1.5

放入 URL 查询字符串时需要对空格编码。

2 - 镶嵌与 STAC

从 MosaicJSON、STAC 或自定义数据源渲染重叠 COG 资产。

默认启用的 mosaic Cargo feature 提供 MosaicTilerMosaicSource trait; 不需要镶嵌的应用可以关闭默认 features。由于这也会关闭 proj,仍需通用 CRS 转换时 请使用 --no-default-features --features proj。数据源将瓦片坐标映射为资产列表; tiler 打开并重投影这些资产,归并重叠像元,然后统一渲染合成结果。

MosaicJSON

运行内嵌示例,或传入一个 MosaicJSON 文件:

cargo run --example mosaic_json
cargo run --example mosaic_json -- /path/to/mosaic.json

解析器支持 MosaicJSON 0.0.3。其 quadkey 索引定义在 WebMercatorQuad 中; 将 MosaicJSON 数据源用于 WorldCRS84Quad 会返回查询错误。

在进程启动时把示例服务连接到文件:

ASYNC_GEOTIFF_MOSAIC=/path/to/mosaic.json \
  cargo run --release --example serve

镶嵌瓦片随后可通过 /mosaic/tiles/... 获取。

像元选择

策略行为
First第一个有效像元获胜;瓦片被完全覆盖后可提前停止。
Highest对全部资产的第一个输出波段逐像元取最大值。
Lowest对全部资产的第一个输出波段逐像元取最小值。
Mean对有效样本流式求均值,内存不随资产数量增长。
Median对有效样本求中位数,完成前需要保留所有参与图像。

“第一个输出波段”在内部索引中是 0;面向用户的 bidx 仍然从 1 开始。

MosaicConfig 默认每批并发处理 8 个资产,每个 MosaicTiler 的 reader 池最多保留 256 个已打开 reader,并把每张请求瓦片的资产数硬限制为 64。超过上限时,tiler 会 记录 warning,并按数据源提供的顺序保留前 N 个资产。三个限制都通过 builder 配置:

use std::sync::Arc;

use async_geotiff::io::block_cache::BlockCache;
use async_geotiff::io::cache::CacheConfig;
use async_geotiff::mosaic::{HttpAccessPolicy, MosaicConfig, MosaicTiler};

let cache = Arc::new(BlockCache::new(CacheConfig::default()));
let config = MosaicConfig {
    chunk_size: 4,
    reader_capacity: 64,
    max_assets_per_tile: 32,
};
let mosaic = MosaicTiler::builder(source)
    .config(config)
    .block_cache(Arc::clone(&cache))
    .http_policy(HttpAccessPolicy::strict())
    .build();

对于不可信或低缩放级别的索引,应保留资产上限以避免请求放大。如果截断会影响视觉 正确性,数据源必须提供确定性的资产顺序。

STAC 示例

启用 stac 并提供全部三个启动配置:

ASYNC_GEOTIFF_STAC_URL=https://earth-search.aws.element84.com/v1 \
ASYNC_GEOTIFF_STAC_COLLECTION=sentinel-2-l2a \
ASYNC_GEOTIFF_STAC_ASSET_KEY=visual \
  cargo run --release --example serve --features stac

API、集合与资产 key 在进程启动时固定。HTTP 查询参数无法把示例变成任意 STAC 或 COG 代理。

启动后打开 http://127.0.0.1:8080/maplibre。配置 STAC 时,MapLibre 查看器默认 选择 mosaic 模式,无需猜测瓦片坐标即可验证目标集合。

HTTP 资产策略

默认策略允许公网和私网 HTTP(S) 资产,但阻止 loopback、link-local 和云元数据地址。 对于完全不可信的文档,请使用 HttpAccessPolicy::strict():它要求 HTTPS,并额外阻止 私有地址范围。permissive() 只应服务于运维方完全控制的资产列表。

示例服务使用默认策略,不提供环境变量覆盖。接受不可信 mosaic 或 STAC 文档的服务应 自行构造 MosaicTiler,并像上例一样通过 builder 传入 strict()

镶嵌错误和日志会隐藏预签名 URL 的查询字符串。 访问策略是 URL 解析防护,不是完整的出站代理沙箱。应用仍需负责客户端超时、重定向 策略、出站防火墙、文档大小限制,以及自己在库外增加的日志。

3 - 生产运行

配置缓存、限制 CPU、保护远程资产并导出可观测性数据。

共享一个缓存

解码块缓存的默认预算是 512 MiB。拥有多个 reader 的服务应把同一个 Arc<BlockCache> 注入全部 reader 和 mosaic,并为每个不同 COG 使用稳定的源 ID, 避免缓存键冲突。

这个预算只覆盖缓存中常驻的解码块,不等于进程总 RSS。飞行中的压缩字节、解码和 重投影缓冲区、编码响应、reader 元数据与 mosaic reducer 状态会额外占用内存;其中 Median 会保留全部参与图像直到归并完成。

库不会实施全局请求并发限制,因此不能仅根据缓存容量推导严格 RSS 上限。应在服务或 网关限制并发瓦片请求,保持单瓦片资产扇出有界,并使用包含最大允许源窗口与输出瓦片 尺寸的压力测试来确定容器内存。

通过 BlockCache::stats() 可观察:

  • hitsmisses
  • decodedfetched
  • entries
  • resident_bytes

可进一步计算命中率、fetch/decode 放大比,以及常驻字节占配置预算的比例。

限制 CPU 工作

解码、拼接、重投影、镶嵌归并、渲染与编码都是 CPU 密集型工作。它们通过受 CpuLimiter 限制的 spawn_blocking 运行。非 mosaic CogReaderTiler 接受 调用方提供的 limiter;MosaicTiler 在资产与最终渲染之间共享一个内部 limiter, 但不能接入非 mosaic limiter。默认值取主机可用并行度,并把 0 修正为至少一个 permit。

Tiler::new 会复用其 reader 携带的 limiter:

use std::sync::Arc;

use async_geotiff::CpuLimiter;
use async_geotiff::io::cog::CogReader;
use async_geotiff::tiler::Tiler;

let cpu = CpuLimiter::new(8);
let reader = Arc::new(
    CogReader::builder()
        .source_id("scene-a")
        .cpu_limiter(cpu.clone())
        .open_http("https://example.com/a.tif")
        .await?,
);
let tiler = Tiler::new(reader);

示例服务的 CPU 计数方式取决于数据路径。命令行默认 COG 使用相互独立的 reader 解码 与 tiler 渲染 limiter,两阶段可以重叠;延迟选择的本地数据集复用一个 AppState limiter,其大小取两项配置中的较大值;MosaicTiler 还拥有自己的共享 limiter。因此 两个环境变量是组件调优项,不是通用的进程级 CPU 上限。需要单一上限时,应在库级别把 同一个 CpuLimiter 注入所有支持注入的非 mosaic reader 与 tiler。

当前 MosaicTiler 拥有内部共享 limiter,但 builder 不支持注入非 mosaic 路径的 limiter。因此,目前不支持对混合 mosaic 与单 COG 流量设置严格的数值型 CPU-job 上限。库外请求并发限制只能提供粗粒度背压,并不等同于共享 permit 预算。

不要在没有测量时主动降低瓦片并发。过小的限制会给每次瓦片请求增加排队时间;应先 观察 P95 延迟与 CPU 竞争。

调整访问模式

  • 多数据集服务或大范围平移/缩放场景可增加缓存容量。
  • 读取延迟敏感时优先使用 ZSTD 压缩 COG,而不是 DEFLATE。
  • 示例服务默认预取一圈原生块;不希望产生额外对象存储 GET 时,设置 ASYNC_GEOTIFF_PREFETCH_RING=0
  • 对不可信索引保持 MosaicConfig::max_assets_per_tile 有界。

导出 trace 与指标

Tiler::tileCogReader::read_window 会发出 tracing span。需要 OTLP trace 时, 在应用中连接 tracing-opentelemetry layer;库本身有意不依赖 OpenTelemetry。

在 HTTP 或应用边界记录请求量、延迟、错误量以及 Ok(None) 比例;另行轮询缓存统计, 观察内存与远程读取行为。

保护远程访问

当 mosaic 或 STAC 文档不可信时使用严格的 HttpAccessPolicy。凭据应配置在 object_store 实例上,而不是嵌入资产标识。应用边界也应避免记录原始预签名 URL。