From a3ac8db3106a16372639b0151b19bd886aba519b Mon Sep 17 00:00:00 2001 From: Pete Gadomski Date: Fri, 7 Jun 2024 13:09:30 -0600 Subject: [PATCH] --wip-- [skip ci] --- convert.py | 8 + scripts/requirements.in | 2 +- scripts/requirements.txt | 4 +- stac-arrow/README.md | 11 +- stac-arrow/data/naip.json | 1147 +++++++++++++++++++--------------- stac-arrow/data/naip.parquet | Bin 31869 -> 34625 bytes stac-arrow/src/lib.rs | 35 +- stac-arrow/src/read.rs | 70 ++- stac-cli/src/args.rs | 11 +- 9 files changed, 748 insertions(+), 540 deletions(-) create mode 100644 convert.py diff --git a/convert.py b/convert.py new file mode 100644 index 000000000..710e76277 --- /dev/null +++ b/convert.py @@ -0,0 +1,8 @@ +import json + +import stac_geoparquet + +with open("stac-arrow/data/naip.json") as f: + items = json.load(f)["features"] +dataframe = stac_geoparquet.to_geodataframe(items) +dataframe.to_parquet("stac-arrow/data/naip.parquet") diff --git a/scripts/requirements.in b/scripts/requirements.in index b2a4a2686..af51f6548 100644 --- a/scripts/requirements.in +++ b/scripts/requirements.in @@ -1,2 +1,2 @@ stac-api-validator -stac-geoparquet +stac-geoparquet<0.5 # v0.5 uses geoparquet 1.1, but geoarrow-rs is geoparquet 1.0 diff --git a/scripts/requirements.txt b/scripts/requirements.txt index f7740f15f..46e147d9e 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -13,8 +13,6 @@ certifi==2024.6.2 # stac-api-validator charset-normalizer==3.3.2 # via requests -ciso8601==2.3.1 - # via stac-geoparquet click==8.1.7 # via # click-plugins @@ -114,7 +112,7 @@ stac-api-validator==0.6.2 # via -r scripts/requirements.in stac-check==1.3.3 # via stac-api-validator -stac-geoparquet==0.5.1 +stac-geoparquet==0.4.1 # via -r scripts/requirements.in stac-validator==3.3.2 # via diff --git a/stac-arrow/README.md b/stac-arrow/README.md index eed0001cc..464b61196 100644 --- a/stac-arrow/README.md +++ b/stac-arrow/README.md @@ -24,17 +24,10 @@ Reading from a [geoparquet](https://geoparquet.org/) file: ```rust use std::fs::File; -use parquet::arrow::arrow_reader::ParquetRecordBatchReaderBuilder; let file = File::open("data/naip.parquet").unwrap(); -let reader = ParquetRecordBatchReaderBuilder::try_new(file) - .unwrap() - .build() - .unwrap(); -let mut items = Vec::new(); -for result in reader { - items.extend(stac_arrow::record_batch_to_items(result.unwrap()).unwrap()); -} +let geo_table = geoarrow::io::parquet::read_geoparquet(file, Default::default()).unwrap(); +let items = stac_arrow::geo_table_to_items(geo_table).unwrap(); assert_eq!(items.len(), 5); ``` diff --git a/stac-arrow/data/naip.json b/stac-arrow/data/naip.json index c735ae935..912d71375 100644 --- a/stac-arrow/data/naip.json +++ b/stac-arrow/data/naip.json @@ -1,775 +1,922 @@ { + "type": "FeatureCollection", "features": [ { "type": "Feature", "stac_version": "1.0.0", - "stac_extensions": [ - "https://stac-extensions.github.io/eo/v1.0.0/schema.json", - "https://stac-extensions.github.io/projection/v1.0.0/schema.json" - ], - "id": "ok_m_3409901_nw_14_1_20100425", + "id": "co_m_4010556_sw_13_060_20210726", + "properties": { + "naip:state": "co", + "naip:year": "2021", + "gsd": 0.6, + "proj:epsg": 26913, + "proj:shape": [ + 12240, + 9550 + ], + "proj:bbox": [ + 489150, + 4441434, + 494880, + 4448778 + ], + "proj:transform": [ + 0.6, + 0, + 489150, + 0, + -0.6, + 4448778, + 0, + 0, + 1 + ], + "proj:centroid": { + "lat": 40.15627, + "lon": -105.09376 + }, + "grid:code": "DOQQ-4010556SW", + "storage:platform": "AWS", + "storage:region": "us-west-2", + "storage:requester_pays": true, + "earthsearch:payload_id": "roda-naip/workflow-naip-to-stac/822e68e82dcceee9e6b95dd1e0835ab3", + "datetime": "2021-07-26T16:00:00Z", + "processing:software": { + "naip-to-stac": "2023.05.22" + }, + "created": "2023-05-24T16:08:51.161Z", + "updated": "2023-05-24T16:08:51.161Z" + }, "geometry": { "type": "Polygon", "coordinates": [ [ [ - -99.933454, - 34.934815 + -105.06009, + 40.123208 ], [ - -99.93423, - 35.00323 + -105.060148, + 40.189374 ], [ - -100.004084, - 35.002673 + -105.127462, + 40.18932 ], [ - -100.00325, - 34.934259 + -105.127338, + 40.123154 ], [ - -99.933454, - 34.934815 + -105.06009, + 40.123208 ] ] ] }, - "bbox": [ - -100.004084, - 34.934259, - -99.933454, - 35.00323 - ], - "properties": { - "datetime": "2010-04-25T00:00:00Z", - "stac_version": "1.0.0", - "gsd": 1.0, - "naip:year": "2010", - "proj:bbox": [ - 408377.0, - 3866212.0, - 414752.0, - 3873800.0 - ], - "proj:epsg": 26914, - "naip:state": "ok", - "proj:shape": [ - 7588, - 6375 - ], - "proj:transform": [ - 1.0, - 0.0, - 408377.0, - 0.0, - -1.0, - 3873800.0, - 0.0, - 0.0, - 1.0 - ] - }, "links": [ { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip", - "rel": "collection", + "rel": "self", + "type": "application/geo+json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip/items/co_m_4010556_sw_13_060_20210726" + }, + { + "rel": "canonical", + "href": "s3://earthsearch-data/naip/co/2021/co_m_4010556_sw_13_060_20210726/co_m_4010556_sw_13_060_20210726.json", "type": "application/json" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip", "rel": "parent", - "type": "application/json" + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/", - "rel": "root", - "type": "application/json" + "rel": "collection", + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip/items/ok_m_3409901_nw_14_1_20100425", - "rel": "self", - "type": "application/geo+json" + "rel": "root", + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1" }, { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/map?collection=naip&item=ok_m_3409901_nw_14_1_20100425", - "rel": "preview", - "type": "text/html", - "title": "Map of item" + "rel": "thumbnail", + "href": "https://earth-search.aws.element84.com/v1/collections/naip/items/co_m_4010556_sw_13_060_20210726/thumbnail" } ], "assets": { - "rendered_preview": { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/preview.png?collection=naip&item=ok_m_3409901_nw_14_1_20100425&assets=image&asset_bidx=image%7C1%2C2%2C3", - "title": "Rendered preview", - "type": "image/png", - "roles": [ - "overview" - ], - "rel": "preview" - }, - "thumbnail": { - "href": "https://naipeuwest.blob.core.windows.net/naip/v002/ok/2010/ok_100cm_2010/34099/m_3409901_nw_14_1_20100425.200.jpg", - "title": "Thumbnail", - "type": "image/jpeg", - "roles": [ - "thumbnail" - ] - }, - "tilejson": { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/tilejson.json?collection=naip&item=ok_m_3409901_nw_14_1_20100425&assets=image&asset_bidx=image%7C1%2C2%2C3", - "title": "TileJSON with default rendering", - "type": "application/json", - "roles": [ - "tiles" - ] - }, "image": { - "href": "https://naipeuwest.blob.core.windows.net/naip/v002/ok/2010/ok_100cm_2010/34099/m_3409901_nw_14_1_20100425.tif", - "title": "RGBIR COG tile", + "href": "s3://naip-analytic/co/2021/60cm/rgbir_cog/40105/56/m_4010556_sw_13_060_20210726.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", - "roles": [ - "data" - ], + "title": "RGBIR COG tile", "eo:bands": [ { - "common_name": "red", - "name": "Red" + "name": "Red", + "common_name": "red" }, { - "common_name": "green", - "name": "Green" + "name": "Green", + "common_name": "green" }, { - "common_name": "blue", - "name": "Blue" + "name": "Blue", + "common_name": "blue" }, { + "name": "NIR", "common_name": "nir", - "description": "near-infrared", - "name": "NIR" + "description": "near-infrared" } + ], + "raster:bands": [ + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 0.6, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 0.6, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 0.6, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 0.6, + "unit": "none" + } + ], + "roles": [ + "data" + ] + }, + "metadata": { + "href": "s3://naip-analytic/co/2021/60cm/fgdc/40105/m_4010556_sw_13_060_20210726_20211115.xml", + "type": "application/xml", + "title": "FGDC Metadata", + "roles": [ + "metadata" ] } }, + "bbox": [ + -105.127462, + 40.123154, + -105.06009, + 40.189374 + ], + "stac_extensions": [ + "https://stac-extensions.github.io/projection/v1.0.0/schema.json", + "https://stac-extensions.github.io/processing/v1.1.0/schema.json", + "https://stac-extensions.github.io/raster/v1.1.0/schema.json", + "https://stac-extensions.github.io/storage/v1.0.0/schema.json", + "https://stac-extensions.github.io/grid/v1.0.0/schema.json", + "https://stac-extensions.github.io/eo/v1.0.0/schema.json" + ], "collection": "naip" }, { "type": "Feature", "stac_version": "1.0.0", - "stac_extensions": [ - "https://stac-extensions.github.io/eo/v1.0.0/schema.json", - "https://stac-extensions.github.io/projection/v1.0.0/schema.json" - ], - "id": "ok_m_3409901_se_14_1_20100425", + "id": "co_m_4010556_sw_13_060_20190803_20191121", + "properties": { + "naip:state": "co", + "naip:year": "2019", + "gsd": 0.6, + "proj:epsg": 26913, + "proj:shape": [ + 12240, + 9550 + ], + "proj:bbox": [ + 489150, + 4441434, + 494880, + 4448778 + ], + "proj:transform": [ + 0.6, + 0, + 489150, + 0, + -0.6, + 4448778, + 0, + 0, + 1 + ], + "proj:centroid": { + "lat": 40.15627, + "lon": -105.09376 + }, + "grid:code": "DOQQ-4010556SW", + "storage:platform": "AWS", + "storage:region": "us-west-2", + "storage:requester_pays": true, + "earthsearch:payload_id": "roda-naip/workflow-naip-to-stac/04cf941135a3751ebe5e6f4195504c7d", + "datetime": "2019-08-03T16:00:00Z", + "processing:software": { + "naip-to-stac": "2023.05.22" + }, + "created": "2023-03-06T19:50:21.748Z", + "updated": "2023-05-24T19:32:32.578Z" + }, "geometry": { "type": "Polygon", "coordinates": [ [ [ - -99.871005, - 34.872311 + -105.06009, + 40.123208 ], [ - -99.871728, - 34.940702 + -105.060148, + 40.189374 ], [ - -99.94153, - 34.940181 + -105.127462, + 40.18932 ], [ - -99.94075, - 34.871792 + -105.127338, + 40.123154 ], [ - -99.871005, - 34.872311 + -105.06009, + 40.123208 ] ] ] }, - "bbox": [ - -99.94153, - 34.871792, - -99.871005, - 34.940702 - ], - "properties": { - "datetime": "2010-04-25T00:00:00Z", - "stac_version": "1.0.0", - "gsd": 1.0, - "naip:year": "2010", - "proj:bbox": [ - 414020.0, - 3859229.0, - 420395.0, - 3866814.0 - ], - "proj:epsg": 26914, - "naip:state": "ok", - "proj:shape": [ - 7585, - 6375 - ], - "proj:transform": [ - 1.0, - 0.0, - 414020.0, - 0.0, - -1.0, - 3866814.0, - 0.0, - 0.0, - 1.0 - ] - }, "links": [ { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip", - "rel": "collection", + "rel": "self", + "type": "application/geo+json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip/items/co_m_4010556_sw_13_060_20190803_20191121" + }, + { + "rel": "canonical", + "href": "s3://earthsearch-data/naip/co/2019/co_m_4010556_sw_13_060_20190803_20191121/co_m_4010556_sw_13_060_20190803_20191121.json", "type": "application/json" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip", "rel": "parent", - "type": "application/json" + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/", - "rel": "root", - "type": "application/json" + "rel": "collection", + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip/items/ok_m_3409901_se_14_1_20100425", - "rel": "self", - "type": "application/geo+json" + "rel": "root", + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1" }, { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/map?collection=naip&item=ok_m_3409901_se_14_1_20100425", - "rel": "preview", - "type": "text/html", - "title": "Map of item" + "rel": "thumbnail", + "href": "https://earth-search.aws.element84.com/v1/collections/naip/items/co_m_4010556_sw_13_060_20190803_20191121/thumbnail" } ], "assets": { - "rendered_preview": { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/preview.png?collection=naip&item=ok_m_3409901_se_14_1_20100425&assets=image&asset_bidx=image%7C1%2C2%2C3", - "title": "Rendered preview", - "type": "image/png", - "roles": [ - "overview" - ], - "rel": "preview" - }, "image": { - "href": "https://naipeuwest.blob.core.windows.net/naip/v002/ok/2010/ok_100cm_2010/34099/m_3409901_se_14_1_20100425.tif", - "title": "RGBIR COG tile", + "href": "s3://naip-analytic/co/2019/60cm/rgbir_cog/40105/m_4010556_sw_13_060_20190803.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", - "roles": [ - "data" - ], + "title": "RGBIR COG tile", "eo:bands": [ { - "common_name": "red", - "name": "Red" + "name": "Red", + "common_name": "red" }, { - "common_name": "green", - "name": "Green" + "name": "Green", + "common_name": "green" }, { - "common_name": "blue", - "name": "Blue" + "name": "Blue", + "common_name": "blue" }, { + "name": "NIR", "common_name": "nir", - "description": "near-infrared", - "name": "NIR" + "description": "near-infrared" } - ] - }, - "thumbnail": { - "href": "https://naipeuwest.blob.core.windows.net/naip/v002/ok/2010/ok_100cm_2010/34099/m_3409901_se_14_1_20100425.200.jpg", - "title": "Thumbnail", - "type": "image/jpeg", + ], + "raster:bands": [ + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 0.6, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 0.6, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 0.6, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 0.6, + "unit": "none" + } + ], "roles": [ - "thumbnail" + "data" ] }, - "tilejson": { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/tilejson.json?collection=naip&item=ok_m_3409901_se_14_1_20100425&assets=image&asset_bidx=image%7C1%2C2%2C3", - "title": "TileJSON with default rendering", - "type": "application/json", + "metadata": { + "href": "s3://naip-analytic/co/2019/60cm/fgdc/40105/m_4010556_sw_13_060_20190803.txt", + "type": "text/plain", + "title": "FGDC Metadata", "roles": [ - "tiles" + "metadata" ] } }, + "bbox": [ + -105.127462, + 40.123154, + -105.06009, + 40.189374 + ], + "stac_extensions": [ + "https://stac-extensions.github.io/eo/v1.0.0/schema.json", + "https://stac-extensions.github.io/grid/v1.0.0/schema.json", + "https://stac-extensions.github.io/processing/v1.1.0/schema.json", + "https://stac-extensions.github.io/storage/v1.0.0/schema.json", + "https://stac-extensions.github.io/projection/v1.0.0/schema.json", + "https://stac-extensions.github.io/raster/v1.1.0/schema.json" + ], "collection": "naip" }, { "type": "Feature", "stac_version": "1.0.0", - "stac_extensions": [ - "https://stac-extensions.github.io/eo/v1.0.0/schema.json", - "https://stac-extensions.github.io/projection/v1.0.0/schema.json" - ], - "id": "ok_m_3409901_sw_14_1_20100425", + "id": "co_m_4010556_sw_13_1_20170827_20171017", + "properties": { + "naip:state": "co", + "naip:year": "2017", + "gsd": 1, + "proj:epsg": 26913, + "proj:shape": [ + 7568, + 5954 + ], + "proj:bbox": [ + 489038, + 4441322, + 494992, + 4448890 + ], + "proj:transform": [ + 1, + 0, + 489038, + 0, + -1, + 4448890, + 0, + 0, + 1 + ], + "proj:centroid": { + "lat": 40.15627, + "lon": -105.09376 + }, + "grid:code": "DOQQ-4010556SW", + "storage:platform": "AWS", + "storage:region": "us-west-2", + "storage:requester_pays": true, + "earthsearch:payload_id": "roda-naip/workflow-naip-to-stac/1387d98166b9397db5f05cb02523c076", + "datetime": "2017-08-27T16:00:00Z", + "processing:software": { + "naip-to-stac": "2023.05.22" + }, + "created": "2023-03-06T19:50:04.158Z", + "updated": "2023-05-24T19:56:41.061Z" + }, "geometry": { "type": "Polygon", "coordinates": [ [ [ - -99.933458, - 34.872317 + -105.058774, + 40.1222 ], [ - -99.934233, - 34.940733 + -105.058833, + 40.190384 ], [ - -100.004078, - 34.940176 + -105.128779, + 40.190327 ], [ - -100.003245, - 34.871761 + -105.128651, + 40.122143 ], [ - -99.933458, - 34.872317 + -105.058774, + 40.1222 ] ] ] }, - "bbox": [ - -100.004078, - 34.871761, - -99.933458, - 34.940733 - ], - "properties": { - "datetime": "2010-04-25T00:00:00Z", - "stac_version": "1.0.0", - "gsd": 1.0, - "naip:year": "2010", - "proj:bbox": [ - 408308.0, - 3859281.0, - 414687.0, - 3866869.0 - ], - "proj:epsg": 26914, - "naip:state": "ok", - "proj:shape": [ - 7588, - 6379 - ], - "proj:transform": [ - 1.0, - 0.0, - 408308.0, - 0.0, - -1.0, - 3866869.0, - 0.0, - 0.0, - 1.0 - ] - }, "links": [ { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip", - "rel": "collection", + "rel": "self", + "type": "application/geo+json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip/items/co_m_4010556_sw_13_1_20170827_20171017" + }, + { + "rel": "canonical", + "href": "s3://earthsearch-data/naip/co/2017/co_m_4010556_sw_13_1_20170827_20171017/co_m_4010556_sw_13_1_20170827_20171017.json", "type": "application/json" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip", "rel": "parent", - "type": "application/json" + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/", - "rel": "root", - "type": "application/json" + "rel": "collection", + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip/items/ok_m_3409901_sw_14_1_20100425", - "rel": "self", - "type": "application/geo+json" + "rel": "root", + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1" }, { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/map?collection=naip&item=ok_m_3409901_sw_14_1_20100425", - "rel": "preview", - "type": "text/html", - "title": "Map of item" + "rel": "thumbnail", + "href": "https://earth-search.aws.element84.com/v1/collections/naip/items/co_m_4010556_sw_13_1_20170827_20171017/thumbnail" } ], "assets": { - "rendered_preview": { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/preview.png?collection=naip&item=ok_m_3409901_sw_14_1_20100425&assets=image&asset_bidx=image%7C1%2C2%2C3", - "title": "Rendered preview", - "type": "image/png", - "roles": [ - "overview" - ], - "rel": "preview" - }, - "tilejson": { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/tilejson.json?collection=naip&item=ok_m_3409901_sw_14_1_20100425&assets=image&asset_bidx=image%7C1%2C2%2C3", - "title": "TileJSON with default rendering", - "type": "application/json", - "roles": [ - "tiles" - ] - }, - "thumbnail": { - "href": "https://naipeuwest.blob.core.windows.net/naip/v002/ok/2010/ok_100cm_2010/34099/m_3409901_sw_14_1_20100425.200.jpg", - "title": "Thumbnail", - "type": "image/jpeg", - "roles": [ - "thumbnail" - ] - }, "image": { - "href": "https://naipeuwest.blob.core.windows.net/naip/v002/ok/2010/ok_100cm_2010/34099/m_3409901_sw_14_1_20100425.tif", - "title": "RGBIR COG tile", + "href": "s3://naip-analytic/co/2017/100cm/rgbir_cog/40105/m_4010556_sw_13_1_20170827.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", - "roles": [ - "data" - ], + "title": "RGBIR COG tile", "eo:bands": [ { - "common_name": "red", - "name": "Red" + "name": "Red", + "common_name": "red" }, { - "common_name": "green", - "name": "Green" + "name": "Green", + "common_name": "green" }, { - "common_name": "blue", - "name": "Blue" + "name": "Blue", + "common_name": "blue" }, { + "name": "NIR", "common_name": "nir", - "description": "near-infrared", - "name": "NIR" + "description": "near-infrared" } + ], + "raster:bands": [ + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 1, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 1, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 1, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 1, + "unit": "none" + } + ], + "roles": [ + "data" + ] + }, + "metadata": { + "href": "s3://naip-analytic/co/2017/100cm/fgdc/40105/m_4010556_sw_13_1_20170827.txt", + "type": "text/plain", + "title": "FGDC Metadata", + "roles": [ + "metadata" ] } }, + "bbox": [ + -105.128779, + 40.122143, + -105.058774, + 40.190384 + ], + "stac_extensions": [ + "https://stac-extensions.github.io/processing/v1.1.0/schema.json", + "https://stac-extensions.github.io/storage/v1.0.0/schema.json", + "https://stac-extensions.github.io/raster/v1.1.0/schema.json", + "https://stac-extensions.github.io/grid/v1.0.0/schema.json", + "https://stac-extensions.github.io/projection/v1.0.0/schema.json", + "https://stac-extensions.github.io/eo/v1.0.0/schema.json" + ], "collection": "naip" }, { "type": "Feature", "stac_version": "1.0.0", - "stac_extensions": [ - "https://stac-extensions.github.io/eo/v1.0.0/schema.json", - "https://stac-extensions.github.io/projection/v1.0.0/schema.json" - ], - "id": "ok_m_3409902_ne_14_1_20100425", + "id": "co_m_4010556_sw_13_1_20150825_20151102", + "properties": { + "naip:state": "co", + "naip:year": "2015", + "gsd": 1, + "proj:epsg": 26913, + "proj:shape": [ + 7570, + 5960 + ], + "proj:bbox": [ + 489030, + 4441320, + 494990, + 4448890 + ], + "proj:transform": [ + 1, + 0, + 489030, + 0, + -1, + 4448890, + 0, + 0, + 1 + ], + "proj:centroid": { + "lat": 40.15626, + "lon": -105.09382 + }, + "grid:code": "DOQQ-4010556SW", + "storage:platform": "AWS", + "storage:region": "us-west-2", + "storage:requester_pays": true, + "earthsearch:payload_id": "roda-naip/workflow-naip-to-stac/b9124378adf4423beb52cd8026140794", + "datetime": "2015-08-25T16:00:00Z", + "processing:software": { + "naip-to-stac": "2023.05.22" + }, + "created": "2023-03-06T19:49:26.704Z", + "updated": "2023-05-24T20:13:51.321Z" + }, "geometry": { "type": "Polygon", "coordinates": [ [ [ - -99.746106, - 34.934802 + -105.058798, + 40.122182 ], [ - -99.746725, - 35.003131 + -105.058857, + 40.190384 ], [ - -99.816441, - 35.002682 + -105.128873, + 40.190327 ], [ - -99.815763, - 34.934355 + -105.128745, + 40.122125 ], [ - -99.746106, - 34.934802 + -105.058798, + 40.122182 ] ] ] }, - "bbox": [ - -99.816441, - 34.934355, - -99.746106, - 35.003131 - ], - "properties": { - "datetime": "2010-04-25T00:00:00Z", - "stac_version": "1.0.0", - "gsd": 1.0, - "naip:year": "2010", - "proj:bbox": [ - 425500.0, - 3866067.0, - 431862.0, - 3873645.0 - ], - "proj:epsg": 26914, - "naip:state": "ok", - "proj:shape": [ - 7578, - 6362 - ], - "proj:transform": [ - 1.0, - 0.0, - 425500.0, - 0.0, - -1.0, - 3873645.0, - 0.0, - 0.0, - 1.0 - ] - }, "links": [ { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip", - "rel": "collection", + "rel": "self", + "type": "application/geo+json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip/items/co_m_4010556_sw_13_1_20150825_20151102" + }, + { + "rel": "canonical", + "href": "s3://earthsearch-data/naip/co/2015/co_m_4010556_sw_13_1_20150825_20151102/co_m_4010556_sw_13_1_20150825_20151102.json", "type": "application/json" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip", "rel": "parent", - "type": "application/json" + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/", - "rel": "root", - "type": "application/json" + "rel": "collection", + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip/items/ok_m_3409902_ne_14_1_20100425", - "rel": "self", - "type": "application/geo+json" + "rel": "root", + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1" }, { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/map?collection=naip&item=ok_m_3409902_ne_14_1_20100425", - "rel": "preview", - "type": "text/html", - "title": "Map of item" + "rel": "thumbnail", + "href": "https://earth-search.aws.element84.com/v1/collections/naip/items/co_m_4010556_sw_13_1_20150825_20151102/thumbnail" } ], "assets": { - "rendered_preview": { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/preview.png?collection=naip&item=ok_m_3409902_ne_14_1_20100425&assets=image&asset_bidx=image%7C1%2C2%2C3", - "title": "Rendered preview", - "type": "image/png", - "roles": [ - "overview" - ], - "rel": "preview" - }, "image": { - "href": "https://naipeuwest.blob.core.windows.net/naip/v002/ok/2010/ok_100cm_2010/34099/m_3409902_ne_14_1_20100425.tif", - "title": "RGBIR COG tile", + "href": "s3://naip-analytic/co/2015/100cm/rgbir_cog/40105/m_4010556_sw_13_1_20150825.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", - "roles": [ - "data" - ], + "title": "RGBIR COG tile", "eo:bands": [ { - "common_name": "red", - "name": "Red" + "name": "Red", + "common_name": "red" }, { - "common_name": "green", - "name": "Green" + "name": "Green", + "common_name": "green" }, { - "common_name": "blue", - "name": "Blue" + "name": "Blue", + "common_name": "blue" }, { + "name": "NIR", "common_name": "nir", - "description": "near-infrared", - "name": "NIR" + "description": "near-infrared" } - ] - }, - "tilejson": { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/tilejson.json?collection=naip&item=ok_m_3409902_ne_14_1_20100425&assets=image&asset_bidx=image%7C1%2C2%2C3", - "title": "TileJSON with default rendering", - "type": "application/json", + ], + "raster:bands": [ + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 1, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 1, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 1, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 1, + "unit": "none" + } + ], "roles": [ - "tiles" + "data" ] }, - "thumbnail": { - "href": "https://naipeuwest.blob.core.windows.net/naip/v002/ok/2010/ok_100cm_2010/34099/m_3409902_ne_14_1_20100425.200.jpg", - "title": "Thumbnail", - "type": "image/jpeg", + "metadata": { + "href": "s3://naip-analytic/co/2015/100cm/fgdc/40105/m_4010556_sw_13_1_20150825.txt", + "type": "text/plain", + "title": "FGDC Metadata", "roles": [ - "thumbnail" + "metadata" ] } }, + "bbox": [ + -105.128873, + 40.122125, + -105.058798, + 40.190384 + ], + "stac_extensions": [ + "https://stac-extensions.github.io/grid/v1.0.0/schema.json", + "https://stac-extensions.github.io/storage/v1.0.0/schema.json", + "https://stac-extensions.github.io/raster/v1.1.0/schema.json", + "https://stac-extensions.github.io/processing/v1.1.0/schema.json", + "https://stac-extensions.github.io/projection/v1.0.0/schema.json", + "https://stac-extensions.github.io/eo/v1.0.0/schema.json" + ], "collection": "naip" }, { "type": "Feature", "stac_version": "1.0.0", - "stac_extensions": [ - "https://stac-extensions.github.io/eo/v1.0.0/schema.json", - "https://stac-extensions.github.io/projection/v1.0.0/schema.json" - ], - "id": "ok_m_3409902_nw_14_1_20100425", + "id": "co_m_4010556_sw_13_1_20130716_20131119", + "properties": { + "naip:state": "co", + "naip:year": "2013", + "gsd": 1, + "proj:epsg": 26913, + "proj:shape": [ + 7544, + 5932 + ], + "proj:bbox": [ + 489049, + 4441332, + 494981, + 4448876 + ], + "proj:transform": [ + 1, + 0, + 489049, + 0, + -1, + 4448876, + 0, + 0, + 1 + ], + "proj:centroid": { + "lat": 40.15625, + "lon": -105.09376 + }, + "grid:code": "DOQQ-4010556SW", + "storage:platform": "AWS", + "storage:region": "us-west-2", + "storage:requester_pays": true, + "earthsearch:payload_id": "roda-naip/workflow-naip-to-stac/a9621fa695da26ffcb51d48b78c271d4", + "datetime": "2013-07-16T16:00:00Z", + "processing:software": { + "naip-to-stac": "2023.05.22" + }, + "created": "2023-03-06T19:48:59.447Z", + "updated": "2023-05-24T18:32:19.402Z" + }, "geometry": { "type": "Polygon", "coordinates": [ [ [ - -99.808552, - 34.934809 + -105.058903, + 40.12229 ], [ - -99.809224, - 35.003163 + -105.058962, + 40.190258 ], [ - -99.878982, - 35.002678 + -105.12865, + 40.190201 ], [ - -99.878252, - 34.934325 + -105.128522, + 40.122233 ], [ - -99.808552, - 34.934809 + -105.058903, + 40.12229 ] ] ] }, - "bbox": [ - -99.878982, - 34.934325, - -99.808552, - 35.003163 - ], - "properties": { - "datetime": "2010-04-25T00:00:00Z", - "stac_version": "1.0.0", - "gsd": 1.0, - "naip:year": "2010", - "proj:bbox": [ - 419793.0, - 3866112.0, - 426159.0, - 3873693.0 - ], - "proj:epsg": 26914, - "naip:state": "ok", - "proj:shape": [ - 7581, - 6366 - ], - "proj:transform": [ - 1.0, - 0.0, - 419793.0, - 0.0, - -1.0, - 3873693.0, - 0.0, - 0.0, - 1.0 - ] - }, "links": [ { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip", - "rel": "collection", + "rel": "self", + "type": "application/geo+json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip/items/co_m_4010556_sw_13_1_20130716_20131119" + }, + { + "rel": "canonical", + "href": "s3://earthsearch-data/naip/co/2013/co_m_4010556_sw_13_1_20130716_20131119/co_m_4010556_sw_13_1_20130716_20131119.json", "type": "application/json" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip", "rel": "parent", - "type": "application/json" + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/", - "rel": "root", - "type": "application/json" + "rel": "collection", + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1/collections/naip" }, { - "href": "https://planetarycomputer.microsoft.com/api/stac/v1/collections/naip/items/ok_m_3409902_nw_14_1_20100425", - "rel": "self", - "type": "application/geo+json" + "rel": "root", + "type": "application/json", + "href": "https://earth-search.aws.element84.com/v1" }, { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/map?collection=naip&item=ok_m_3409902_nw_14_1_20100425", - "rel": "preview", - "type": "text/html", - "title": "Map of item" + "rel": "thumbnail", + "href": "https://earth-search.aws.element84.com/v1/collections/naip/items/co_m_4010556_sw_13_1_20130716_20131119/thumbnail" } ], "assets": { - "thumbnail": { - "href": "https://naipeuwest.blob.core.windows.net/naip/v002/ok/2010/ok_100cm_2010/34099/m_3409902_nw_14_1_20100425.200.jpg", - "title": "Thumbnail", - "type": "image/jpeg", - "roles": [ - "thumbnail" - ] - }, "image": { - "href": "https://naipeuwest.blob.core.windows.net/naip/v002/ok/2010/ok_100cm_2010/34099/m_3409902_nw_14_1_20100425.tif", - "title": "RGBIR COG tile", + "href": "s3://naip-analytic/co/2013/100cm/rgbir_cog/40105/m_4010556_sw_13_1_20130716.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", - "roles": [ - "data" - ], + "title": "RGBIR COG tile", "eo:bands": [ { - "common_name": "red", - "name": "Red" + "name": "Red", + "common_name": "red" }, { - "common_name": "green", - "name": "Green" + "name": "Green", + "common_name": "green" }, { - "common_name": "blue", - "name": "Blue" + "name": "Blue", + "common_name": "blue" }, { + "name": "NIR", "common_name": "nir", - "description": "near-infrared", - "name": "NIR" + "description": "near-infrared" } - ] - }, - "tilejson": { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/tilejson.json?collection=naip&item=ok_m_3409902_nw_14_1_20100425&assets=image&asset_bidx=image%7C1%2C2%2C3", - "title": "TileJSON with default rendering", - "type": "application/json", + ], + "raster:bands": [ + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 1, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 1, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 1, + "unit": "none" + }, + { + "nodata": 0, + "data_type": "uint8", + "spatial_resolution": 1, + "unit": "none" + } + ], "roles": [ - "tiles" + "data" ] }, - "rendered_preview": { - "href": "https://planetarycomputer.microsoft.com/api/data/v1/item/preview.png?collection=naip&item=ok_m_3409902_nw_14_1_20100425&assets=image&asset_bidx=image%7C1%2C2%2C3", - "title": "Rendered preview", - "type": "image/png", + "metadata": { + "href": "s3://naip-analytic/co/2013/100cm/fgdc/40105/m_4010556_sw_13_1_20130716.txt", + "type": "text/plain", + "title": "FGDC Metadata", "roles": [ - "overview" - ], - "rel": "preview" + "metadata" + ] } }, + "bbox": [ + -105.12865, + 40.122233, + -105.058903, + 40.190258 + ], + "stac_extensions": [ + "https://stac-extensions.github.io/processing/v1.1.0/schema.json", + "https://stac-extensions.github.io/storage/v1.0.0/schema.json", + "https://stac-extensions.github.io/eo/v1.0.0/schema.json", + "https://stac-extensions.github.io/raster/v1.1.0/schema.json", + "https://stac-extensions.github.io/grid/v1.0.0/schema.json", + "https://stac-extensions.github.io/projection/v1.0.0/schema.json" + ], "collection": "naip" } ], - "type": "FeatureCollection" + "links": [], + "numberReturned": 5 } \ No newline at end of file diff --git a/stac-arrow/data/naip.parquet b/stac-arrow/data/naip.parquet index e54d47a2e59330eb21c3d47977f8707542251f3f..d63113bc0c348c875fde945fb4ff50e42296b1b8 100644 GIT binary patch literal 34625 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 literal 31869 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 Result> { - Reader::new().read::(record_batch) +pub fn geo_table_to_items(geo_table: GeoTable) -> Result> { + Reader::new().read::(geo_table) } /// Reads record batches into items. @@ -47,6 +41,29 @@ impl Reader { Reader {} } + /// Reads a [GeoTable] into a vector of items. + /// + /// # Examples + /// + /// ``` + /// use std::fs::File; + /// use stac_arrow::Reader; + /// + /// let file = File::open("data/naip.parquet").unwrap(); + /// let geo_table = geoarrow::io::parquet::read_geoparquet(file, Default::default()).unwrap(); + /// let reader = Reader::new(); + /// let items = reader.read::(geo_table).unwrap(); + /// assert_eq!(items.len(), 5); + /// ``` + pub fn read(&self, geo_table: GeoTable) -> Result> { + let mut items = Vec::with_capacity(geo_table.len()); + let (_, record_batches, _) = geo_table.into_inner(); + for record_batch in record_batches { + items.extend(self.record_batch_to_items::(record_batch)?); + } + Ok(items) + } + /// Reads items from a record batch. /// /// # Examples @@ -64,12 +81,15 @@ impl Reader { /// let mut items = Vec::new(); /// let reader = Reader::new(); /// for result in parquet_reader { - /// items.extend(reader.read::(result.unwrap()).unwrap()); + /// items.extend(reader.record_batch_to_items::(result.unwrap()).unwrap()); /// } /// assert_eq!(items.len(), 5); /// ``` #[allow(deprecated)] // We find that `record_batches_to_json_rows` is faster than serializing-then-deserializing with `Writer` - pub fn read(&self, mut record_batch: RecordBatch) -> Result> { + pub fn record_batch_to_items( + &self, + mut record_batch: RecordBatch, + ) -> Result> { let index = record_batch.schema().index_of("geometry")?; let geometry = record_batch.remove_column(index); let geometry = geometry @@ -96,6 +116,7 @@ impl Reader { #[cfg(test)] mod tests { + use super::Reader; use parquet::arrow::arrow_reader::ParquetRecordBatchReaderBuilder; use stac_validate::Validate; use std::fs::File; @@ -103,17 +124,22 @@ mod tests { #[test] fn record_batch_to_items() { let file = File::open("data/naip.parquet").unwrap(); - let mut reader = ParquetRecordBatchReaderBuilder::try_new(file) + let mut parquet_reader = ParquetRecordBatchReaderBuilder::try_new(file) .unwrap() .build() .unwrap(); - let items = reader + let reader = Reader::new(); + let items = parquet_reader .next() - .map(|result| super::record_batch_to_items(result.unwrap()).unwrap()) + .map(|result| { + reader + .record_batch_to_items::(result.unwrap()) + .unwrap() + }) .unwrap(); assert_eq!(items.len(), 5); for item in items { - assert_eq!(item.extensions.len(), 2); + assert_eq!(item.extensions.len(), 6); assert!(item.geometry.is_some()); assert!(item.bbox.is_some()); assert!(!item.links.is_empty()); @@ -122,4 +148,12 @@ mod tests { item.validate().unwrap(); } } + + #[test] + fn geo_table_to_items() { + let file = File::open("data/naip.parquet").unwrap(); + let geo_table = geoarrow::io::parquet::read_geoparquet(file, Default::default()).unwrap(); + let items = super::geo_table_to_items(geo_table).unwrap(); + assert_eq!(items.len(), 5); + } } diff --git a/stac-cli/src/args.rs b/stac-cli/src/args.rs index 24f151b32..f37f45ae1 100644 --- a/stac-cli/src/args.rs +++ b/stac-cli/src/args.rs @@ -1,7 +1,5 @@ use crate::{Error, Format, Result, Subcommand}; use clap::Parser; -#[cfg(feature = "parquet")] -use parquet::arrow::arrow_reader::ParquetRecordBatchReaderBuilder; use serde::Serialize; use serde_json::json; use stac::{item::Builder, Asset, Value}; @@ -363,17 +361,14 @@ impl Args { } #[cfg(feature = "parquet")] Format::GeoParquet => { - let reader = if let Some(href) = href { + let geo_table = if let Some(href) = href { let file = File::open(href)?; - ParquetRecordBatchReaderBuilder::try_new(file)?.build()? + geoarrow::io::parquet::read_geoparquet(file, Default::default())? } else { // FIXME unimplemented!() }; - let mut items = Vec::new(); - for result in reader { - items.extend(stac_arrow::record_batch_to_items(result?)?); - } + let items = stac_arrow::geo_table_to_items(geo_table)?; Ok(Value::ItemCollection(items.into())) } }