stac-rs v0.10
stac-rs is a "hobby" project of mine. I put "hobby" in quotes because I've sunk quite a few tens (hundreds?) of hours into it because I think it might actually Be Useful™ in the real world in the not-to-distant future. I talked about it at FOSS4G-NA 2024, and afterwords discovered that at least one person is using it in production. So, I'm happy to announce the v0.10 release of the core crate, stac.
STAC v1.1.0 🎉
STAC v1.1.0 was released this month, and stac-rs is STAC v1.1.0 by default!
use stac::Item;
let item = Item::new("an-id");
assert_eq!(item.version.to_string(), "1.1.0");
You can migrate existing STAC objects from v1.0.0 to v1.1.0:
use stac::{Item, Migrate, Version};
let mut item: Item = stac::read("item-v1.0.0.json").unwrap();
let item = item.migrate(&Version::v1_1_0).unwrap();
assert_eq!(item.version, Version::v1_1_0);
This migration includes moving raster
and eo
bands information up to the new bands
structure, as described in the best practices.
Formats
With the advent of stac-geoparquet as a potential1 alternative storage format for STAC items, stac-rs now supports three formats:
- JSON
- Newline-delimited JSON (ndjson)
- stac-geoparquet
Each format provides methods to read and write its data either from a Read
or a Write
, or from Vec<u8>
or Bytes
:
use stac::{Item, Format, ItemCollection};
let item: Item = Format::json().from_path("item.json").unwrap();
let items: ItemCollection = Format::geoparquet().from_path("items.parquet").unwrap();
Format::ndjson().write("items.ndjson", items);
Object store
fsspec is a widely-used Python library that allows folks to use the same interface to open files from a variety of sources, including the local filesystem and cloud provider blob storage. object_store is the Rust equivalent, and stac v0.10 includes object_store support via some free functions:
use stac::Item;
let href = "s3://bucket/item.json";
let options = [("aws_access_key_id", "...")];
let item: Item = stac::io::get_opts(href, options).await.unwrap();
stac::io::put_opts(href, item, options).await.unwrap();
Other crates
Along with the stac release, we also released:
- stac-api v0.6.0, with
Client
andBlockingClient
for searching APIs - stac-validate v0.3.0, with a new async-first API
- stac-cli v0.4.0 to provide access to all this new functionality on the command line
Next steps
Now that I've got the core library updated, I'm going to spend some time on the Python bindings. Specifically, I've implemented (but not released) a request to add search capabilities to the Python API, particularly to enable writing the search directly to stac-geoparquet:
import stacrs
stacrs.search_to(
"items.parquet",
"https://landsatlook.usgs.gov/stac-server",
collections="landsat-c2l2-sr",
intersects={"type": "Point", "coordinates": [-105.119, 40.173]},
sortby="-properties.datetime",
max_items=1,
)
I'd like to release that, along with some better documentation on how to use the Python bindings and what alternatives you should use when stacrs isn't enough (i.e. pystac and pystac-client). I also need to do a write-up of my FOSS4G-NA 2024 talk to provide more narrative on how to use the CLI.
Get in touch
If you're using stac-rs, or you'd like to use it, get in touch! I'm on Bluesky, or ask anything in the Github Discussions. I think that Rust has a interesting, if niche, place to contribute to the geospatial community, both as a component of our shared open source infrastructure and as a performance-boosting layer for downstream data consumers.
The community is still figuring out how exactly stac-geoparquet will interact with the STAC specification. Some sticky points include the awkwardness of updating existing parquet files, and the additional burden on developers to maintain tooling for multiple formats. See the recent Cloud Native Geospatial blog post for more.