跳转到主要内容

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

返回本页常规视图.

文档

了解架构、运行示例、集成库,并查询准确的行为说明。

请选择与你当前目标一致的阅读路径:

1 - 项目概览

了解 async-geotiff 的职责边界以及数据如何在系统中流动。

从这里开始了解项目定位、架构与有意保留的边界。

1.1 - 什么是 async-geotiff?

项目目标、支持的数据类型以及有意保留的边界。

async-geotiff 是一个 Rust 库,用于把云优化 GeoTIFF(COG)转换为带样式的 XYZ 地图瓦片。它只读取生成目标瓦片所需的字节范围,解码原生 TIFF 块,按需 重投影,应用渲染样式,最后编码输出。

核心能力

  • 通过 HTTPS 或调用方配置的 object_store 后端异步访问 COG。
  • 在一个按字节限制的共享缓存中保存解码后的原生 TIFF 块。
  • 支持 WebMercatorQuad(EPSG:3857)和 WorldCRS84Quad(EPSG:4326)。
  • 支持 U8、U16、I16、U32、I32、F32 和 F64 源像元。
  • 支持 nearest、bilinear、cubic、cubic-spline、Lanczos 和 average 重采样。
  • 支持拉伸、色带、RGB 合成、颜色公式和算术波段计算。
  • 默认输出 PNG,并可通过 feature 启用无损 WebP。
  • 使用 MosaicJSON、STAC 或自定义数据源组合多资产镶嵌。

有意保留的边界

不依赖 GDAL 运行时。 TIFF I/O 使用 async-tiff 和 object_store。 默认的 proj feature 仅在非内置快速路径的坐标转换中使用系统 libproj。

库中不包含 Web 框架。 Axum HTTP 层以及 MapLibre、OpenLayers、Leaflet 查看器位于 examples/。应用可以直接使用 CogReader、Tiler 或 MosaicTiler,无需引入 Axum。

不管理凭据。 使用 S3、GCS、MinIO 或其他对象存储时,由应用完成认证配置, 再把可用的 store 传给库。

不绑定可观测性后端。 crate 发出 tracing span 并公开缓存统计;应用自行选择 OpenTelemetry、Prometheus、日志或其他导出方式。

说明

完全位于数据集或投影有效范围之外的瓦片返回 Ok(None);示例 HTTP 服务将其映射为 204 No Content。

1.2 - 架构

跟踪一次瓦片请求如何从 HTTP 或库调用变为编码后的字节。

库将异步范围 I/O 与 CPU 密集型的解码、重投影、渲染和编码工作分离。应用只需组合 自己需要的公共层。

flowchart LR
    Client[HTTP 客户端或 Rust 调用方] --> Style[TileStyle]
    Client --> Tiler[Tiler]
    Tiler --> Grid[TileMatrixSet]
    Tiler --> Reader[CogReader]
    Reader --> Store[object_store / HTTP 范围读取]
    Reader <--> Cache[共享 BlockCache]
    Reader --> CPU[CpuLimiter + spawn_blocking]
    CPU --> Warp[重投影与重采样]
    Warp --> Render[拉伸 / 色带 / 合成]
    Style --> Render
    Render --> Encode[PNG / lossless WebP]
    Encode --> Result[Option&lt;Bytes&gt;]
    Mosaic[MosaicTiler] --> ReaderPool[ReaderPool]
    ReaderPool --> Reader
    Mosaic --> Render

主要组件

组件职责
CogReader打开 COG,读取元数据和概览层,选择并拼接原生块,以及采样点或窗口。
BlockCache在统一字节预算下跨 reader 共享解码块,并合并并发冷读取。
Tiler规划瓦片、选择概览层、读取源窗口、按需重投影并输出编码字节。
TileStyle校验 Raster Style JSON/Q3,并绑定已支持的渲染能力。
MosaicTiler查找资产、通过池打开 reader、重投影各资产、合并重叠像元并统一渲染。
CpuLimiter限制跨 reader 与 tiler 的 CPU 密集型阻塞任务。

瓦片数据流

  1. TileCoord 在受支持的 TileMatrixSet 中定位目标瓦片。
  2. Tiler 计算目标边界并检查其是否与源数据集相交。
  3. 根据目标地面分辨率选择合适的概览层。
  4. CogReader 通过范围请求加载缺失的原生块,并复用缓存命中。
  5. 同 CRS 使用仿射快速路径;跨 CRS 使用反向重投影。EPSG:4326 与 EPSG:3857 之间有闭式快速路径,其他组合需要 proj feature。
  6. 源 nodata 在插值前排除。Raster Style 管线计算输出通道,再应用固定范围拉伸、 Gamma、颜色映射与 opacity,最后编码为 PNG 或无损 WebP。元数据 scale/offset 校准暂不支持,请求时返回错误。

并发模型

Tokio 负责异步元数据与字节范围 I/O。解码、拼接、重投影、镶嵌归并、渲染和编码 通过受信号量限制的 spawn_blocking 运行。应用可以把一个 Arc<BlockCache> 注入 单 COG 与 mosaic reader,避免解码缓存预算倍增;也可以在非 mosaic 的 CogReader/Tiler 之间注入同一个 CpuLimiter。当前 MosaicTiler 使用自己的内部 limiter,无法加入该 permit 预算,因此混合流量没有自动的进程级 CPU 上限。

2 - 快速开始

安装依赖、运行示例服务,并通过库渲染一张瓦片。

按照最短路径,从全新检出运行到一张可见的地图瓦片。

2.1 - 环境要求

Rust、系统库和可选的文档工具链要求。

库与示例

  • Rust 1.92 或更高版本,与 Cargo.toml 保持一致。
  • 默认 feature 集需要系统 libproj 9.x。
  • 从仓库开发时需要 Git。

macOS:

brew install proj

Debian 或 Ubuntu:

sudo apt install libproj-dev libsqlite3-dev libtiff-dev clang

其他平台请通过受支持的包管理器安装 libproj,或关闭默认 features。项目目前没有 提供 Windows 专用安装命令。

如果只需要同 CRS 瓦片或内置的 EPSG:4326 ↔ EPSG:3857 快速路径,可以关闭默认 features:

cargo build --no-default-features

文档站

website/ 下的 OINK 站点需要 Go 1.27 或更高版本,以及 Hugo Extended 0.165.0 或更高版本。Hugo 的版本输出中必须包含 extended:

go version
hugo version

库本身不依赖 Hugo 或 Go。

2.2 - 快速上手

运行示例服务并请求第一张渲染瓦片。

克隆并运行

git clone https://github.com/mapseekai/async-geotiff-rs.git
cd async-geotiff-rs
COG_URL='https://raw.githubusercontent.com/cogeotiff/rio-tiler/0b08b7f35a8b639cee2f35a0cb565034f7b55bfd/tests/fixtures/cog.tif'
cargo run --release --example serve -- "$COG_URL"

固定提交版本的 rio-tiler 测试文件约 800 KiB,是一个公开且支持 Range 的 COG, 适合首次运行验证。冒烟测试完成后再替换为自己的 COG。服务默认监听 127.0.0.1:8080,并在启动成功后打印查看器与瓦片 URL。

打开任一内置查看器:

查看器会自动居中到已打开的数据集,是最可靠的可视化冒烟测试。也可以直接请求全球 0 级瓦片:

curl --fail --output tile.png \
  'http://127.0.0.1:8080/tiles/WebMercatorQuad/0/0/0.png'

成功时会生成可用任意图像查看器打开的 PNG 文件。合法但完全位于源数据范围之外的 坐标返回 HTTP 204,而不是合成一张空白图片;遇到这种情况,请使用内置查看器在自动 计算的数据集中心和缩放级别请求范围内瓦片。

浏览本地文件

不传 URL 时,服务会发现 data/*.tif 和 data/*.tiff:

mkdir -p data
cp /path/to/example.tif data/
cargo run --release --example serve

查看器中会出现数据集切换器。

可选输出格式

PNG 始终可用。无损 WebP 需要显式启用:

cargo run --release --features webp --example serve -- \
  https://example.com/cog.tif

/formats 端点只返回当前二进制实际编译的编码器。

2.3 - 作为库使用

直接从 Rust 打开 COG 并渲染瓦片。

在应用中添加 crates.io 依赖:

cargo new async-geotiff-demo
cd async-geotiff-demo
[dependencies]
async-geotiff = "0.13.0"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

如果要避免系统 libproj,同时保留示例服务使用的 mosaic API,可以在依赖上设置 default-features = false, features = ["mosaic"];此时无法执行通用 CRS 转换。 本地开发时可用 path = "../async-geotiff-rs" 替换版本号,并按检出位置调整路径。

渲染一张瓦片

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_raster_query("version=3.0&type=pseudocolor&bidx=1&colormap_name=viridis&method=linear&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_raster_query 接受与示例 HTTP 服务相同的查询字符串,但不包含开头的 ?。 将示例保存为 src/main.rs,然后执行 cargo run。固定 URL 是一个支持 Range 的 小型测试 COG;确认集成成功后再替换为自己的数据。

点查询与地理范围

CogReader::point(x, y, &coord_crs, bidx) 返回最近像素的值,不执行渲染。坐标使用 coord_crs;影像外的点返回 None。波段从 1 开始编号,对应 read_window 输出的 波段;空选择按现有顺序返回全部输出波段。

没有独立 TIFF mask 时,首个 Alpha 样本会转为有效性 mask 并从输出波段中移除, 因此普通 RGBA 的点查询返回 RGB。有独立 mask 时,reader 保留原生波段并使用该 mask。无效像素返回 Some(PointValue { valid: false, .. }),不会被误判为波段 选择错误。Raster Style 渲染对 Alpha 源的独立限制仍然适用。

wgs84_bounds() 返回用于数据集统计的地理包络。投影足迹包含极点时,包络包括该 极点,经度范围为 [-180, 180]。包络可能包含影像之外的区域;实际覆盖仍应通过 像素查询或有效性 mask 判断。

低层 io::stats::Histogram::quantile 接受公开的 u64 分桶计数,在累计时避免 u64 溢出,也适用于直接构造的 histogram。100% 分位返回最后一个非空桶的上边界, 即使前面的计数非常大,也不会丢掉末尾的小计数桶;尾部空桶不参与该端点。 Raster Style 统计不使用这些嵌入式直方图。

共享内存与 CPU 预算

处理多个 COG 时,请创建一个块缓存,并为每个 reader 指定稳定且互不相同的源 ID:

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?;

共享同一缓存的 reader 共用默认 512 MiB 预算。源 ID 是缓存键的一部分,只有相同逻辑 COG 才应复用同一个 ID。

3 - 使用指南

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

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

3.1 - 样式与波段计算

使用 Raster Style 3.0 JSON 与 Q3 输入配置栅格样式。

样式输入使用 raster-style = "=0.4.0" SDK,协议版本为 3.0,需要 Rust 1.92。 SDK 负责结构和语义校验,适配器再检查本渲染器支持的能力。未知字段、重复单值参数和 未实现能力均报错。下列能力适用于 Tiler::tile 和 MosaicTiler::tile,不代表完整规范的后端认证。

Rust 输入

use async_geotiff::style::TileStyle;

let style = TileStyle::from_json(r#"{
  "version": "3.0",
  "extensions": ["https://mapseekai.github.io/raster-style/extensions/raster/tile/v1.0.0/schema.json"],
  "renderer": {"type": "pseudocolor", "bidx": [1], "colormap_name": "viridis"},
  "stretch": {"method": "linear", "rescale": [[0, 3000]]},
  "raster:tile": {"format": "png", "tilesize": 256}
}"#)?;

也可以使用 TileStyle::from_raster_query 解析原始 Q3 查询字符串,或用 TileStyle::from_raster_style(&RasterStyle) 接收 SDK 已校验对象。 RasterStyle 从 async_geotiff::style 导出。 style.raster_style_json() 返回规范化 JSON。修改样式时重新解析输入;直接覆盖 TileStyle 不暴露可变字段;format() / tilesize() 提供只读输出配置。

Tile 与 Mosaic 是独立版本扩展:在 extensions 声明精确的 Schema URL, 配置位于 raster:tile、raster:mosaic。Q3 使用 extensions 传输 URL 数组、 extension_fields 传输业务字段对象,均为百分号编码的 JSON。 推荐用 raster_style::encode_query 编码已校验的 SDK 文档。 校验不完整或声明第三方扩展的样式在执行前即被拒绝。

HTTP Q3 输入

单波段色带:

/tiles/WebMercatorQuad/0/0/0.png?version=3.0&type=pseudocolor&bidx=1&method=linear&rescale=0,3000&colormap_name=viridis

RGB 支持将一组范围广播到三个输出:

version=3.0&type=rgb&bidx=1&bidx=2&bidx=3&method=linear&rescale=0,3000

dataset、mode、_v 是示例服务上下文,不属于样式文档;TMS 和瓦片坐标仍在路径中。 服务保留原始查询片段,由 SDK 解码一次。+ 必须写成 %2B,空格写成 %20, 不要先 URL 解码再调用 from_raster_query。JSON 入口是 Rust API;示例 HTTP 服务使用 Q3 GET。 PNG 是默认编码。WebP 要启用 webp feature,声明 Tile 1.0.0 扩展,并配置 raster:tile: {format: "webp", lossless: true}, 并使用 .webp 路径;路径与样式格式必须一致。

拉伸与颜色

  • 支持 gray、rgb、pseudocolor、categorized、single_color。
  • method=none(含省略)对显示路径固定使用 [0,255],不会自动读取统计值。
  • method=linear 必须给出 rescale;RGB 接受一组广播范围或三组逐通道范围。
  • 显示路径支持 range_policy=clamp|transparent;透明策略在颜色处理前判断越界。
  • 命名色带使用项目固定依赖中的 colorous 256 项表:viridis、magma、inferno、plasma、cividis、turbo、greys。
  • 原生 colormap 精确值对象按数据值匹配;区间数组使用半开区间 [lo,hi),末区间也不包含上界。 pseudocolor 在显式拉伸或 Gamma 后转为 0–255 色表索引;categorized 始终按数据值精确匹配。
  • gray 支持 renderer_invert;single_color 的有效输入包括 0 和负数。
  • opacity 作用于输出 Alpha;最终 Alpha 为 0 时输出透明黑色。

categorized 只支持显式精确值表与 nearest,读取原始层,避免未经验证的概览改变类别。 普通数值样式支持现有 nearest、bilinear、cubic、cubic_spline、lanczos、average 核。 每个依赖波段分别重采样并传播有效性;源 Alpha 波段暂不支持,会在读取像元前报错。

cubic_spline 在整数像素中心仍会平滑数据。因此,请求瓦片网格与源网格精确对齐时 也会执行该核,直接瓦片渲染与 warp 路径保持相同重采样语义。Cubic、CubicSpline 和 Lanczos 对接近数值上限的有限 F64 常量也保持有效,不会因中间计算溢出而变透明。 实际非有限样本或无法表示的结果仍然无效。

统计拉伸与曲线

支持全部 7 种方法:none、linear、minmax、percentile、stddev、 histogram_equalization、curve。三个示例页均提供对应参数:

method=percentile&percentiles=2,98
method=stddev&stddev=2
method=histogram_equalization
method=curve&curves=[[[0,0],[128,0.5],[255,1]]]

百分位对排序样本做线性插值;标准差为总体标准差;直方图均衡使用经验 CDF,不使用分桶近似。 曲线点为 [数据值,归一化输出],支持一条广播曲线或三条 RGB 曲线。实际 Q3 URL 中需编码 JSON。

Tiler 与 MosaicTiler 在完整数据源足迹或固定 mosaic 源集合的联合足迹上,绑定 1024 × 1024、EPSG:4326 的共享统计网格。网格北向上,经纬度像元中心等距,覆盖及有效性 mask 从源继承;overview 根据各源完整范围和固定网格尺寸选择,与输出瓦片缩放级别无关。 统计网格重放相同的重采样、NoData、表达式、完整元组有效性与 mosaic 阶段。 不会改成当前瓦片统计,也不直接信任嵌入式 GDAL 汇总值。

省略 statistics 时使用 dataset/mosaic 范围、sample 精度、最多 1,000,000 个行优先等距网格位置。 statistics={"scope":"dataset","accuracy":"exact"} 遍历该绑定网格所有像元, 不表示遍历源数据原生分辨率的全部像元。无效采样丢弃且不补采;空统计输出透明;常量范围映射到 0.5。

统计结果跨瓦片共享,缓存绑定 reader 实例、顺序及完整规范化样式。统计计算、源读取和 median 保留输入 受现有 CPU/内存预算约束;选定 overview 的完整读取超过预算时明确报错。最多缓存两个统计计划。

quadkey_zoom=0 的 MosaicJSON 提供固定完整源集合。分区 MosaicJSON 的统计拉伸暂报错, 避免摊平索引后丢失覆盖范围和分区绘制顺序;瓦片始终使用索引选中的源。 自定义 MosaicSource 的 statistics_assets() 必须提供与瓦片选择语义一致的完整合成集合。 未绑定集合的动态 STAC、viewport 和外部 statistics.ref 暂报错。 低层 render(ImageData, ...) 不能自行推断完整数据范围;统计类方法通过 tiler 绑定后执行。

表达式

支持十进制数、括号、一元负号和四则运算,波段编号从 1 开始。RGB 可用 ; 分隔三个输出。

version=3.0&type=gray&expression=(b5-b4)%2F(b5%2Bb4)&method=linear&rescale=-1,1

该 NDVI 示例要求第 5 波段是近红外、第 4 波段是红光,使用前检查数据元信息。 表达式与 bidx 互斥,可与受支持的 Gamma 组合。无效源值、除零或非有限结果透明。 当前不支持函数、条件运算和科学计数法;SDK 与现有表达式解析器共同限制输入大小。

颜色公式

effects.color_formula 支持 Gamma,按数组顺序执行;Q3 示例:

version=3.0&type=gray&bidx=1&color_formula=gamma%20rgb%202

暂不支持外部统计快照、calibration(除 none)、index、color_mapping、源调色板、 mode 重采样、地形、第三方扩展、其他颜色操作、JPEG 与有损 WebP。请求这些能力会报错。

Mosaic

启用默认的 mosaic feature 后,JSON 中声明:

"raster:mosaic": {"pixel_selection": "highest", "stage": "after_channels", "rank_channel": 1}

在 extensions 声明官方 Mosaic 1.0.0 Schema URL。Q3 的 extensions 参数传输声明数组,extension_fields 传输包含 raster:mosaic 的对象;旧的镶嵌短参数不再接受。 支持 first、highest、lowest、mean、median,以及 before_channels / after_channels 两个阶段。 使用 mosaic.tile(coord, &style).await?,选择方法直接取自样式。 tile_with_options(coord, &style, &options) 提供请求取消和超时控制。

before_channels 的排序位置对应去重后按源波段号升序排列的依赖表;after_channels 对应输出通道顺序。rank_channel 从 1 开始,仅用于 highest/lowest。 所有分量有效的同源元组才参加合并;不会把不同源的通道拼成一组。Gamma、色表和 opacity 在合并后执行一次。源 Alpha 波段限制仍适用。

资产列表由 MosaicJSON、STAC 或自定义 MosaicSource 提供,保持在样式之外。 配置、资源限制与示例见镶嵌指南。

迁移

旧 from_query / from_pairs、ValidatedTileStyle、compile_validated、可变样式字段、 Stretch / ColourDefinition / Colour / lut_from_stops 与独立 mosaic selection 参数已移除。 统一使用 from_json / from_raster_query / from_raster_style。 TileStyle::default() 是显式灰度波段 1、固定 0–255 的新规范样式。 HTTP 请求必须包含 version=3.0&type=...,旧参数与未知字段返回错误。 三个查看器只生成 Q3,Opacity 由服务端应用一次;MapLibre 提供 mosaic 阶段和排序通道。

旧输入新输入
bidx=1&colormap_name=viridis&rescale=0,3000增加 version=3.0&type=pseudocolor&method=linear
RGB 的三组相同 rescale一组 rescale 即可广播,但需显式 type=rgb 和三个 bidx
不指定拉伸,对非 U8 自动 stddev新格式使用固定 [0,255];需调用方显式给定范围
连续 stops 数组 colormap不能直接复用;新格式原生数组是区间表,连续 color_mapping 尚未实现
stretch=percent&pc=2,98method=percentile&percentiles=2,98

3.2 - 镶嵌与 STAC

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

默认启用的 mosaic Cargo feature 提供 MosaicTiler 和 MosaicSource 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/... 获取。

Raster Style 3.0

let style = TileStyle::from_json(r#"{
  "version": "3.0",
  "extensions": ["https://mapseekai.github.io/raster-style/extensions/raster/mosaic/v1.0.0/schema.json"],
  "renderer": {"type": "rgb", "bidx": [3, 2, 1]},
  "stretch": {"method": "linear", "rescale": [[0, 3000]]},
  "raster:mosaic": {"pixel_selection": "highest", "stage": "before_channels", "rank_channel": 1}
}"#)?;
let tile = mosaic.tile(coord, &style).await?;

before_channels 先合并输入依赖,再执行表达式;after_channels 先逐源计算表达式, 再合并输出。上例的依赖表是 [1,2,3],因此 rank_channel=1 比较源波段 1; 改为 after_channels 后比较第一个输出,即源波段 3。并列保留源顺序靠前的完整元组。 mean/median 只对同一组完整有效元组逐通道求值,避免极值相加溢出。

Q3 请求示例:

/mosaic/tiles/WebMercatorQuad/0/0/0.png?version=3.0&type=rgb&bidx=3&bidx=2&bidx=1&method=linear&rescale=0,3000&extensions=%5B%22https%3A%2F%2Fmapseekai.github.io%2Fraster-style%2Fextensions%2Fraster%2Fmosaic%2Fv1.0.0%2Fschema.json%22%5D&extension_fields=%7B%22raster%3Amosaic%22%3A%7B%22pixel_selection%22%3A%22mean%22%2C%22stage%22%3A%22after_channels%22%7D%7D

MapLibre 的 Source 选择 mosaic 后可以配置阶段和排序通道。资产地址仍由服务端固定, JSON/Q3 不携带资产列表。新格式要求显式 mosaic 配置;源 Alpha 波段暂不支持,返回能力错误。 完整支持范围见样式指南。

像元选择

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

bidx 和 rank_channel 都从 1 开始;后者是合并阶段的通道位置。

MosaicConfig 默认每批并发处理 8 个资产,每个 MosaicTiler 的 reader 池最多保留 256 个已打开 reader,并把每张请求瓦片的资产数硬限制为 64。超过上限时返回错误, 不会截断资产后返回部分结果。三个限制都通过 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,
    ..Default::default()
};
let mosaic = MosaicTiler::builder(source)
    .config(config)
    .block_cache(Arc::clone(&cache))
    .http_policy(HttpAccessPolicy::strict())
    .build();

对于不可信或低缩放级别的索引,应保留资产上限以避免请求放大。数据源应提供确定性的资产顺序, 因为 first 和极值并列时依赖该顺序。Median 保留输入上限为 256 MiB,另受共享工作内存预算约束。

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 模式,无需猜测瓦片坐标即可验证目标集合。

自定义认证、代理或超时时,在调用 build() 前把配置好的 reqwest 0.11 ClientBuilder 传给 StacSource::with_http_client_builder。数据源保留这些配置, 并强制最多十次同源重定向;跨源跳转在发送凭据前被拒绝,传输错误不包含完整 URL。 已弃用的 with_http_client 现在会在 I/O 前报错,因为已构建客户端的重定向策略无法 覆盖。StacSource::new 的签名保持不变。

HTTP 资产策略

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

示例服务显式允许自身的 HTTP 主机名,供配置的镶嵌读取 /data 资产;其他主机使用 默认策略,不提供环境变量覆盖。接受不可信 mosaic 或 STAC 文档的服务应 自行构造 MosaicTiler,并像上例一样通过 builder 传入 strict()。

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

3.3 - 生产运行

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

共享一个缓存

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

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

默认瓦片入口共享最多准入 64 个请求的 RequestLimiter,以及独立于解码缓存、 用于活跃工作的 512 MiB WorkBudget,也可以注入自定义实例。这些计账上限不等于 严格 RSS 上限;仍需限制单瓦片资产扇出和调用方保留的输出,并用有代表性的负载确定 容器内存。默认值、内存竞争下的有界重试、取消和源快照说明见 运行限制与源一致性。

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

  • hits 与 misses
  • decoded 与 fetched
  • entries
  • resident_bytes

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

限制 CPU 工作

解码、拼接、重投影、镶嵌归并、渲染与编码都是 CPU 密集型工作。它们通过受 CpuLimiter 限制的 spawn_blocking 运行。非 mosaic CogReader 与 Tiler 接受 调用方提供的 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::tile 和 CogReader::read_window 会发出 tracing span。需要 OTLP trace 时, 在应用中连接 tracing-opentelemetry layer;库本身有意不依赖 OpenTelemetry。

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

保护远程访问

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

3.4 - 运行限制与源一致性

工作内存、请求准入、取消和固定对象快照的契约。

工作内存与缓存

默认 reader、tiler 和 mosaic pool 共享 WorkBudget::global() 的 512 MiB 活跃工作预算。WorkBudget::new(bytes) 创建独立预算;通过 ReaderConfig::work_budget、Tiler::with_work_budget 和 MosaicTiler::builder(...).work_budget(...) 注入同一个实例,才能共享应用上限。 used_bytes()、peak_bytes() 和 limit_bytes() 提供计账数据。

低层预留失败立即返回 AgError::ResourceLimit。公开 tile、warp、mosaic 请求会先 退出失败的一轮,再等待独占准入,最多重试一次;等待和重试都计入原 deadline。 单个请求本身超预算时仍失败。直接调用 CogReader 不提供这种请求级重试。 阻塞任务和受管理的响应缓冲区会保留预留,直到最后一个持有者释放。

这不是操作系统 RSS 上限。解码缓存、调用方持有的完成图像、分配器、TLS 和应用自身 分配另有生命周期。通过 CacheConfig::max_bytes 限制缓存,并限制输出保留数量。

Reader 设置默认值
源窗口像素16 × 1024 × 1024
窗口字节/压缩抓取批次256 MiB
每窗口块数4096
单块声明的解码字节64 MiB
打开时累计元数据8 MiB
IFD 数量256
每 IFD 条目4096
并发前台窗口8

使用 ReaderConfig::default() 并明确覆盖字段。超限、算术溢出和非法元数据在相应 抓取/分配前失败。后台预取即时尝试获取预算,前台占用时跳过。内置解码器检查 未压缩、Deflate/OldDeflate、LZW、ZSTD 和 JPEG 输出形状;调用方自行提供的解码器 仍由调用方负责。

请求准入与取消

默认共享 RequestLimiter 准入 64 个瓦片请求,超出立即返回 AgError::Overloaded。 使用 Tiler::with_request_limiter 或 MosaicTilerBuilder::request_limiter 共享自定义实例;mosaic 内部资产任务不会再次占用请求名额。

默认 timeout 为 30 秒,包含 I/O 和 permit 等待。TilerConfig、MosaicConfig 提供 max_in_flight_requests 与 request_timeout,构造时可使用 ..Default::default()。tile_with_options 和单源 warp_tile_with_options 接受含单次 timeout、RequestCancellation 的 RequestOptions。 cancel() 返回 AgError::Cancelled;超时返回 AgError::DeadlineExceeded。

取消会停止后续阶段并丢弃待完成的 I/O,但不会抢占已执行的 CPU 指令,也不会强制 终止远端处理。仍在运行的阻塞任务保留准入和内存计账,直至结束。直接打开 reader 发生在 tile 请求之外,需要包含打开时间时,应由应用增加外层 timeout。

示例服务将 ASYNC_GEOTIFF_MAX_IN_FLIGHT_REQUESTS 与 ASYNC_GEOTIFF_REQUEST_TIMEOUT_MS 传到默认 COG、本地懒加载、MosaicJSON 和 STAC 入口,HTTP deadline 包含数据集查找/打开;增大设置后不会残留固定的 64 请求或 30 秒总 deadline。传输层连接/读取 timeout 独立。单 COG 支持 ASYNC_GEOTIFF_PREFETCH_RING,mosaic reader 默认不预取。

HTTP mosaic 错误标签移除 URL userinfo、query 和 fragment;对象存储 key 保持原语义。

Mosaic 顺序与波段

MosaicJSON 去重保留资产列表中的首次出现顺序。前缀查找按 quadkey 字典序遍历, 保留各列表顺序。样式的 raster:mosaic 设置 pixel_selection、stage 和从 1 开始的 rank_channel。before_channels 使用按波段号排序并去重的源依赖; after_channels 使用计算后的输出通道。整个 tuple 有效才能参与,Highest/Lowest 保留获胜资产的完整 tuple,同值时按资产顺序决定。

源依赖分别 warp,避免无关波段的 nodata 影响插值。Gamma、色带和透明度在归并后 执行一次。仅支持 calibration none;旧 unscale 参数已移除。warp_tile 返回紧凑依赖或计算通道,不再返回全部源波段。

固定对象快照

受管理的 open_http 和 open_object_store 默认使用 SnapshotPolicy::RequireValidator,需要 strong ETag 或不可变对象版本。 条件读取和缓存身份将元数据与像素固定到同一快照;源发生变化时返回错误,避免 混合版本。支持版本的存储可继续提供固定的旧版本,本地受管理打开也提供 validator。

不透明 ObjectReader 无法提供底层条件请求,因此 .open(reader) 要求显式设置 .snapshot_policy(SnapshotPolicy::AssumeImmutable)。这由调用方保证源不可变, 不是库验证出的快照一致性。

一致性依赖真实 validator 和后端原子写入契约,无法检测复用旧 validator 的字节 变更或违反契约的原地文件写入。没有自动刷新:直接 reader 应重新打开;mosaic 可用 invalidate_source(key, source_id) 或新的源版本身份触发重开。已持有的 reader Arc 仍指向原快照;旧版本不可获取时,其未缓存读取会失败。

3.5 - 本地负载测量与基准

无需外部服务,复现有界延迟与峰值 RSS 测量。

这些工具从 Git 检出目录运行,支持 macOS 和 Linux;它们是开发工具,不会在应用 依赖本库时执行。先单独编译优化后的二进制,避免编译器内存混入测量:

cargo build --release --locked --example load_audit --features mosaic
python3 scripts/run_load_audit.py --samples 32 --concurrency 4

默认结果写入被 Git 忽略的 target/load-audit/results.json。可用 --output 设置其他路径,用 --concurrency 1 或 8 比较并发。采样限制为 4–128, 并发为 1–16;超过 120 秒会终止子进程。脚本只依赖 Python 标准库。

负载在临时 loopback HTTP 服务中提供 64×64 Deflate TIFF,带 32×32 overview、 三个波段、四个原生块和 nodata 角落,每个 GET 注入 2 ms 延迟。直接调用库的瓦片 API,输出 64×64 PNG;不需要凭据和公共数据,也不代表示例服务 HTTP 路由的端到端 性能。冷请求包含 reader/客户端/元数据,热请求复用 reader 和解码块;mosaic 使用三个独立 URL 的相同像素与 Mean reducer。吞吐包含批次屏障,不是开放到达率。

JSON 包含 nearest-rank P50/P95/P99、缓存计数、GET 数量、准备的响应字节、活跃 处理器、工作预算峰值,以及取消/deadline/准入拒绝/提前内存拒绝的观测。32 次 采样的 P99 是最大值,不能当成稳定的生产尾延迟。“响应字节”是服务端准备的数据, 不证明已送达取消的客户端;取消返回后仍可能有远端工作完成。

脚本记录 UTC、平台、CPU、Rust 版本、提交及工作区状态、二进制和 fixture 的 SHA256、CPU 时间及子进程的 wait4 ru_maxrss。macOS 返回字节,Linux 的 KiB 会换算为字节。RSS 是整个负载进程全程峰值,不是各场景峰值或进程树总量。

这些是单机有界合成测量,不证明生产容量、任意恶意编解码输入的内存上限或无限 请求流表现。fixture 可用 python3 tests/fixtures/generate.py 重建,Deflate 字节也受本地 zlib 版本影响。

重采样微基准

cargo bench --locked --bench resampler_bench

六组场景比较连续/跨步内存布局下带/不带 mask 的 Bilinear 采样,以及带/不带 mask 的 Average 降采样,测的是核本身成本,不是 HTTP 延迟或跨 CRS 流水线吞吐。 Criterion 只作为开发依赖,不会成为应用使用本库时的依赖。

4 - 参考手册

准确记录路由、参数、features、默认值和运行配置。

需要查询确切支持值和默认行为时,请使用本节。

4.1 - 示例 HTTP API

路由、瓦片路径、样式参数与响应行为。

HTTP API 属于 examples/serve.rs,不会进入库本身的依赖表面。

路由

方法与路径用途
GET /tiles/{tms}/{z}/{x}/{y}.{ext}从选中的单个 COG 渲染瓦片。
GET /mosaic/tiles/{tms}/{z}/{x}/{y}.{ext}从配置的 mosaic 或 STAC 数据源渲染瓦片。
GET /datasets列出 data/ 下发现的 TIFF 文件。
GET /cache/stats返回解码块缓存统计。
GET /formats返回当前服务编译支持的输出格式。
GET /bounds返回示例查看器使用的边界。
GET、HEAD /data/{name}通过范围请求提供本地 TIFF。

支持的 TMS 名称是 WebMercatorQuad 和 WorldCRS84Quad。扩展名支持 png, 以及 feature 控制的无损 webp。

Raster Style Q3

两条瓦片路由只接受完整 Q3:version=3.0&type=...。未知字段、旧格式和未实现能力报错。 dataset、mode、_v 是独立请求上下文,不能重复;资产地址不属于样式。

参数是否可重复含义
version / type否3.0 与 gray/rgb/pseudocolor/categorized/single_color。
bidx是从 1 开始的源波段索引,RGB 恰好三个。
expression否灰度一个表达式;RGB 三个分号分隔的表达式;与 bidx 互斥。
method / rescale范围可重复none、linear、minmax、percentile、stddev、histogram_equalization、curve;参数与共享统计网格见样式指南。
colormap_name / colormap否伪彩色色表;原生色表是精确值或半开区间。
nodata否有限数值或 nan。
color_formula否已支持 Gamma 操作,按顺序应用。
opacity否0–1,默认 1。
resampling / reproject否nearest、bilinear、cubic、cubic_spline、lanczos、average。
extensions否精确版本 Schema URL 的 JSON 数组,需百分号编码。
extension_fields否包含 raster:tile、raster:mosaic 的 JSON 对象,需百分号编码。

raster:tile 支持 tilesize(64、128、256、512、1024)、format(png, 或带 lossless: true 的 webp);格式必须与路径一致。raster:mosaic 必须提供 pixel_selection、stage,highest/lowest 还可提供 rank_channel。 在 extensions 声明对应的 Tile 1.0.0 或 Mosaic 1.0.0 Schema URL。旧的瓦片与镶嵌短参数一律拒绝。

原始 Q3 中 + 必须编码为 %2B;不能先解码后直接拼接。样式语义与限制见样式指南。

响应

  • 200 OK 返回编码后的图像字节。
  • 204 No Content 表示坐标有效,但完全位于数据集或投影有效范围之外。
  • 无效样式值与格式错误的坐标会返回客户端错误,底层保留结构化库错误。

默认输出尺寸为 256×256,以兼容更多 XYZ 客户端。

4.2 - Cargo features

编译期能力及其依赖影响。
Feature默认作用
proj是通过系统 libproj 启用通用 CRS 转换。
mosaic是启用 MosaicTiler、MosaicSource、MosaicJSON 和异步资产扇出。
webp否通过 image 启用无损 WebP 编码。
jpeg否启用底层 JPEG 编码器;Raster Style 样式请求暂不支持 JPEG。
stac否添加 STAC 客户端,并隐含启用 mosaic。
perf-tracing否发出更详细的内部耗时事件。
tokio-console否启用 Tokio Console,并隐含启用 perf-tracing。

示例:

# 默认:投影 + 镶嵌 + PNG
cargo build --release

# 不包含通用 PROJ 与镶嵌的最小库
cargo build --release --no-default-features

# 包含全部图像格式的示例服务
cargo run --release --example serve --features webp

# STAC 镶嵌示例
cargo run --release --example serve --features stac

# 完整验证面
cargo test --all-features --locked

serve、mosaic_source 和 mosaic_json 示例要求启用 mosaic。PNG 始终可用。

4.3 - 示例服务配置

内置 Axum 服务接受的环境变量。

以下变量配置 cargo run --example serve。它们是示例服务约定,不是库的全局配置。

变量默认值含义
ASYNC_GEOTIFF_BIND127.0.0.1:8080HTTP 服务监听地址。
ASYNC_GEOTIFF_BLOCK_CACHE_MB512共享解码块缓存容量(MiB),必须为正数。
ASYNC_GEOTIFF_MAX_DECODE_TASKS可用并行度最大并发解码/拼接 CPU 任务数,必须为正数。
ASYNC_GEOTIFF_MAX_TILE_TASKS可用并行度最大并发重投影/渲染 CPU 任务数,必须为正数。
ASYNC_GEOTIFF_MAX_IN_FLIGHT_REQUESTS64瓦片请求共享准入上限,必须为正数。
ASYNC_GEOTIFF_REQUEST_TIMEOUT_MS30000含数据集查找/打开的瓦片请求超时,单位毫秒,必须为正数。
ASYNC_GEOTIFF_PREFETCH_RING1默认/本地单 COG reader 的原生块预取圈数;0 为关闭。
ASYNC_GEOTIFF_SLOW_TILE_MS未设置超过此正整数毫秒阈值时发出慢瓦片警告。
ASYNC_GEOTIFF_MOSAIC未设置启动时加载的 MosaicJSON 文件路径。
ASYNC_GEOTIFF_STAC_URL未设置固定 STAC API URL;需要 stac 及后两个变量。
ASYNC_GEOTIFF_STAC_COLLECTION未设置固定 STAC collection ID。
ASYNC_GEOTIFF_STAC_ASSET_KEY未设置固定 STAC COG 资产 key。
ASYNC_GEOTIFF_TOKIO_CONSOLE关闭使用 tokio-console 编译时,以 1、true、yes 或 on 启用 Tokio Console。
RUST_LOGasync_geotiff=debug,warn示例服务的标准 tracing 过滤器。

ASYNC_GEOTIFF_MOSAIC 与 STAC 配置互斥;三个 STAC 变量必须一起提供。

解码与瓦片任务变量用于调优单 COG 工作,但不构成一个进程级 CPU 上限:命令行默认 COG 使用独立 limiter;延迟选择的本地数据集共享一个取两者较大值的 limiter;mosaic 拥有自己的 limiter。示例服务没有为 max_assets_per_tile 等 MosaicConfig 字段 提供环境变量。

请求准入与超时配置同时作用于命令行默认 COG、延迟加载的 ?dataset=、MosaicJSON 和 STAC 瓦片。这些路径共享配置后的库准入 limiter;HTTP 请求取消后仍在运行的 CPU 工作也受其约束。调高 HTTP 配置时,库层配置同步生效,不再额外保留固定的 64 请求准入 上限或 30 秒总请求时限。传输层连接/读取超时仍独立生效。超额请求返回 503,超时请求返回 504。

这些错误类型也会在 Mosaic 资产打开和 TIFF 错误包装后保留:请求超时、取消和超载 分别返回 504、408 和 503;普通 HTTP 资产错误仍使用脱敏后的诊断信息。

预取配置对两种单 COG 入口均生效。Mosaic 资产 reader 保留原有的零预取默认值, 服务没有提供 Mosaic 预取配置。

HTTP Mosaic 资产错误的诊断标签不包含 URL 用户名/密码、查询串或 fragment。 Store backend 的对象 key 保持既有语义。源凭据保留在服务端配置中;瓦片调用者无需 提供原始资产 URL。

示例

ASYNC_GEOTIFF_BIND=0.0.0.0:8080 \
ASYNC_GEOTIFF_BLOCK_CACHE_MB=1024 \
ASYNC_GEOTIFF_MAX_DECODE_TASKS=8 \
ASYNC_GEOTIFF_MAX_TILE_TASKS=8 \
ASYNC_GEOTIFF_PREFETCH_RING=0 \
ASYNC_GEOTIFF_SLOW_TILE_MS=500 \
RUST_LOG=async_geotiff=info \
  cargo run --release --example serve -- https://example.com/cog.tif

无效数值会使进程在启动时失败,而不会被静默修正。

4.4 - 版本发布与 crates.io

async-geotiff 的打包范围、验证和发布步骤。

包名是 async-geotiff,Rust 导入名是 async_geotiff。0.13.0 为首次 crates.io 分发做准备;旧 GitHub Release 仍提供源码包。GitHub 仓库公开并不会自动发布 crate, Cargo 会单独上传 .crate 归档。

打包范围

Cargo.toml 明确列出包含内容:核心源码、examples 及 HTML 查看器、tests 和小型 可重建 fixture、重采样基准、Cargo 清单、README、变更日志和 MIT 许可 全文。测试与 fixture 一起保留,因为单元测试和示例会嵌入 fixture 字节。 website、脚本、Agent 指令、本地影像和生成报告不进入注册表包。

benches/resampler_bench.rs 有六组有效的重采样核对照,因此保留。 scripts/run_load_audit.py 测量本地有界延迟和峰值 RSS,在 Git 中保留,默认结果 写入忽略的 target/load-audit/。历史审查与机器实测可在截至 7170204 的 Git 历史中查阅,不再放在当前源代码树中。复现见本地负载测量。

发布前验证

更新 Cargo.toml、Cargo.lock、变更日志和中英文网站。按 AGENTS.md 跑五组 feature 的全目标与文档测试,以及 viewer 和严格 Hugo 构建,然后检查实际注册表包:

cargo +stable package --list --locked
cargo +stable publish --dry-run --locked

归档位于 target/package/。提交前本地预览可加 --allow-dirty,正式发布不加。 docs.rs 构建关闭默认 feature,避免要求原生 PROJ,同时生成 mosaic、STAC 和编码器 文档;应用使用本库时仍有正常的默认 feature。

发布

验证后提交发布改动,推送与版本号一致的标签:

git tag v0.13.0
git push origin main v0.13.0

Release workflow 会校验标签、安装原生构建依赖、运行测试、验证归档,并把归档 附到 GitHub Release。成功后将同一提交的文档部署到 Cloudflare Pages。 单独推送标签不会上传 crates.io。

上传注册表需要已验证邮箱的 crates.io 账号和有权发布该 crate 的 token:

cargo login
cargo +stable publish --locked

也可以设置仓库 secret CARGO_REGISTRY_TOKEN,在 GitHub Actions 的 Release workflow 选择对应的版本标签并勾选 publish_to_crates_io。它会重新验证再上传。 不要把 token 放进命令参数、日志或提交文件。

已发布版本不能覆盖,应在上传前核实归档和版本号。详见 Cargo 发布指南。

从 0.12 升级

Raster Style 保持 SDK 0.4.0/协议 3.0/Q3。自定义 STAC 客户端应把已构建客户端的 with_http_client 改成 with_http_client_builder,传入配置好的 reqwest 0.11 ClientBuilder;旧入口返回错误。认证与重定向契约见镶嵌指南。 此版本还修正独立 mask 网格、极区覆盖、Alpha 点查询、精确网格 CubicSpline、极端 有限值重采样、histogram 计数及示例服务配置传递。