Relocate Assets
This guide continues from Create STAC Package. It starts after the package tutorial has already selected the OpenAerialMap Items, built the package, derived the HTTPS asset lock, and added the S3 alternates. The new work here is to relocate those locked assets into local storage, add local alternates to the STAC Items, and validate the local lock.
Run the commands in the same shell you used for the package tutorial so
$tmpdir remains available. If you are starting from a new shell, set tmpdir
to the temporary directory created in that tutorial.
Starting Point
Complete the package tutorial through Enrich The STAC Items first. At that point the OpenAerialMap sample has already done this:
- selected the two Austria Items from the
openaerialmapcollection; - built a package with the selected Items and four non-metadata asset rows;
- validated the original HTTPS asset metadata in the package asset lock;
- created an S3-shaped asset lock without copying bytes;
- enriched the STAC Items with
alternate.s3.hrefvalues.
The relocation flow starts from this structure:
$tmpdir/
openaerialmap-austria.pkg/
items.parquet
assets.lock.parquet
openaerialmap-austria.s3.assets.lock.parquet
openaerialmap-austria.enriched.items.parquet
Use the package asset lock as the authoritative source for relocation, and use the enriched items table as the STAC view that already contains S3 alternates.
Relocate Assets To Local Storage
Relocate bytes from the locked package hrefs into a local mirror:
mkdir -p "$tmpdir/local-assets"
stacpkg asset-lock from-parquet "$tmpdir/openaerialmap-austria.pkg/assets.lock.parquet" \
| stacpkg asset-lock relocate \
--source-prefix https://oin-hotosm-temp.s3.amazonaws.com/ \
--store-type file \
--key "$tmpdir/local-assets/" \
--max-workers 4 \
--memory-limit-bytes 512MiB \
--chunk-size-bytes 8MiB \
| stacpkg asset-lock to-parquet \
"$tmpdir/openaerialmap-austria.local.asset-lock.parquet"
echo "created $tmpdir/openaerialmap-austria.local.asset-lock.parquet"
Sample output:
created /tmp/stacpkg-openaerialmap-austria.ABC123/openaerialmap-austria.local.asset-lock.parquet
The relocated rows point at local files and carry relocated sizes:
| item_id | asset_key | store_type | key | size_bytes |
|---|---|---|---|---|
631ee6653cdf1c0006b63c5b |
thumbnail |
file |
/tmp/.../local-assets/631ee6653cdf1c0006b63c5b/thumbnail.png |
793014 |
631ee6653cdf1c0006b63c5b |
visual |
file |
/tmp/.../local-assets/631ee6653cdf1c0006b63c5b/visual.tif |
9913534 |
Enrich With Local Alternates
Add the relocated local hrefs as alternates, then promote them to primary hrefs in a temporary items table. This temporary table is only used to derive local file metadata:
stacpkg items from-parquet "$tmpdir/openaerialmap-austria.enriched.items.parquet" \
| stacpkg items add-alternate \
--asset-lock <(stacpkg asset-lock from-parquet \
"$tmpdir/openaerialmap-austria.local.asset-lock.parquet") \
--alternate-key original \
--alternate-name local \
| stacpkg items promote-alternate \
--alternate-key original \
--mode switch \
| stacpkg items to-parquet "$tmpdir/openaerialmap-austria.local-primary.items.parquet"
echo "created $tmpdir/openaerialmap-austria.local-primary.items.parquet"
Sample output:
created /tmp/stacpkg-openaerialmap-austria.ABC123/openaerialmap-austria.local-primary.items.parquet
Derive object metadata facts from the local files so local validation compares file-backend facts:
stacpkg items from-parquet "$tmpdir/openaerialmap-austria.local-primary.items.parquet" \
| stacpkg asset-lock derive \
| stacpkg asset-lock to-parquet "$tmpdir/openaerialmap-austria.local.assets.lock.parquet"
echo "created $tmpdir/openaerialmap-austria.local.assets.lock.parquet"
Sample output:
created /tmp/stacpkg-openaerialmap-austria.ABC123/openaerialmap-austria.local.assets.lock.parquet
Now enrich the original remote items table with local alternates as well:
stacpkg items from-parquet "$tmpdir/openaerialmap-austria.enriched.items.parquet" \
| stacpkg items enrich \
--asset-lock <(stacpkg asset-lock from-parquet \
"$tmpdir/openaerialmap-austria.local.assets.lock.parquet") \
--alternate-key local \
| stacpkg items to-parquet "$tmpdir/openaerialmap-austria.s3-local.items.parquet"
echo "created $tmpdir/openaerialmap-austria.s3-local.items.parquet"
Sample output:
created /tmp/stacpkg-openaerialmap-austria.ABC123/openaerialmap-austria.s3-local.items.parquet
The first thumbnail now has remote primary access plus S3 and local alternates:
{
"href": "https://oin-hotosm-temp.s3.amazonaws.com/631ee60c3cdf1c0006b63c56/0/631ee60c3cdf1c0006b63c57.png",
"alternate": {
"s3": {
"href": "s3://oin-hotosm-temp/631ee60c3cdf1c0006b63c56/0/631ee60c3cdf1c0006b63c57.png"
},
"local": {
"href": "file:///tmp/stacpkg-openaerialmap-austria.ABC123/local-assets/631ee6653cdf1c0006b63c5b/thumbnail.png"
}
}
}
Validate Remote And Local
The package tutorial already created the dry-run S3 lock. Validate it with unsigned public S3 access when you want to compare the remote alternate lock with the relocated local lock:
export AWS_SKIP_SIGNATURE=true
export AWS_EC2_METADATA_DISABLED=true
export AWS_DEFAULT_REGION=us-east-1
stacpkg asset-lock from-parquet "$tmpdir/openaerialmap-austria.s3.assets.lock.parquet" \
| stacpkg asset-lock validate
Sample output:
{"asset_key":"thumbnail","errors":[],"item_id":"631ee6653cdf1c0006b63c5b","key":"631ee60c3cdf1c0006b63c56/0/631ee60c3cdf1c0006b63c57.png","store_container":"oin-hotosm-temp","store_endpoint_url":"https://s3.amazonaws.com","store_type":"s3","valid":true}
Validate the local file lock:
stacpkg asset-lock from-parquet "$tmpdir/openaerialmap-austria.local.assets.lock.parquet" \
| stacpkg asset-lock validate
Sample output:
{"asset_key":"thumbnail","errors":[],"item_id":"631ee6653cdf1c0006b63c5b","key":"/tmp/stacpkg-openaerialmap-austria.ABC123/local-assets/631ee6653cdf1c0006b63c5b/thumbnail.png","store_container":null,"store_type":"file","valid":true}
The remote validation checks the public S3 objects. The local validation checks
the relocated files under $tmpdir/local-assets.