From de26c3651cd5c1ac5d1bebafbb80d6f0d5abea1c Mon Sep 17 00:00:00 2001 From: David Bitner Date: Wed, 11 Aug 2021 12:12:37 -0500 Subject: [PATCH] CQL Search (#38) * bump version to 0.3.0 * Add option to skip incremental migration check to test scripts * Add SQL script to bypass pypgstac and directly reset / load pgstac sql and sample data * Add SQL to use CQL for search and to use cursor for paging through results * Split test files to match location of code each section is testing. Modify test data with ids that can be identified as testdata and to have attributes to test more filters * Adjust layout of items table to allow better use of partition pruning, start/end dates and updated properties * fix issue with quoting in sql generation, don't pregenerate all cursors --- pgstac.sql | 5 +- pypgstac/poetry.lock | 29 +- pypgstac/pypgstac/__init__.py | 2 +- pypgstac/pypgstac/load.py | 137 +- .../migrations/pgstac.0.2.9-0.3.0.sql | 1606 +++++++++++++++++ pypgstac/pypgstac/migrations/pgstac.0.3.0.sql | 1591 ++++++++++++++++ pypgstac/pyproject.toml | 3 +- scripts/bin/migra_funcs | 2 +- scripts/bin/testdb | 48 +- scripts/sql/resetdb.sql | 6 + scripts/stageversion | 3 - scripts/test | 20 +- sql/001_core.sql | 205 +-- sql/001a_jsonutils.sql | 138 ++ sql/001b_cursorutils.sql | 108 ++ sql/001s_stacutils.sql | 37 + sql/003_items.sql | 358 ++-- sql/004_search.sql | 1192 +++++++----- sql/999_version.sql | 2 +- test/pgtap.sql | 121 +- test/pgtap/001_core.sql | 18 + test/pgtap/001a_jsonutils.sql | 26 + test/pgtap/001b_cursorutils.sql | 5 + test/pgtap/001s_stacutils.sql | 5 + test/pgtap/002_collections.sql | 9 + test/pgtap/003_items.sql | 31 + test/pgtap/004_search.sql | 148 ++ test/pgtap/999_version.sql | 0 test/testdata/collections.ndjson | 2 +- test/testdata/items.ndjson | 200 +- 30 files changed, 5032 insertions(+), 1025 deletions(-) create mode 100644 pypgstac/pypgstac/migrations/pgstac.0.2.9-0.3.0.sql create mode 100644 pypgstac/pypgstac/migrations/pgstac.0.3.0.sql create mode 100644 scripts/sql/resetdb.sql create mode 100644 sql/001a_jsonutils.sql create mode 100644 sql/001b_cursorutils.sql create mode 100644 sql/001s_stacutils.sql create mode 100644 test/pgtap/001_core.sql create mode 100644 test/pgtap/001a_jsonutils.sql create mode 100644 test/pgtap/001b_cursorutils.sql create mode 100644 test/pgtap/001s_stacutils.sql create mode 100644 test/pgtap/002_collections.sql create mode 100644 test/pgtap/003_items.sql create mode 100644 test/pgtap/004_search.sql create mode 100644 test/pgtap/999_version.sql diff --git a/pgstac.sql b/pgstac.sql index 6b423951..09eaf7e6 100644 --- a/pgstac.sql +++ b/pgstac.sql @@ -1,7 +1,10 @@ BEGIN; \i sql/001_core.sql +\i sql/001a_jsonutils.sql +\i sql/001b_cursorutils.sql +\i sql/001s_stacutils.sql \i sql/002_collections.sql \i sql/003_items.sql \i sql/004_search.sql \i sql/999_version.sql -COMMIT; \ No newline at end of file +COMMIT; diff --git a/pypgstac/poetry.lock b/pypgstac/poetry.lock index 69e30cf5..36c49873 100644 --- a/pypgstac/poetry.lock +++ b/pypgstac/poetry.lock @@ -261,6 +261,17 @@ wcwidth = "*" checkqa-mypy = ["mypy (==v0.761)"] testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" + +[package.dependencies] +six = ">=1.5" + [[package]] name = "regex" version = "2021.7.6" @@ -269,6 +280,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + [[package]] name = "smart-open" version = "4.2.0" @@ -366,7 +385,7 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes [metadata] lock-version = "1.1" python-versions = ">=3.7" -content-hash = "ea3e7463d47e0f789fb6ab9ab1b50e487b6ff4614071f57c6a53705ef459c67e" +content-hash = "7608e31569c4651fbb6d423ebcf98a56591e3c3b6f48dc29cfdee0409ee18535" [metadata.files] appdirs = [ @@ -519,6 +538,10 @@ pytest = [ {file = "pytest-5.4.3-py3-none-any.whl", hash = "sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1"}, {file = "pytest-5.4.3.tar.gz", hash = "sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"}, ] +python-dateutil = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] regex = [ {file = "regex-2021.7.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e6a1e5ca97d411a461041d057348e578dc344ecd2add3555aedba3b408c9f874"}, {file = "regex-2021.7.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:6afe6a627888c9a6cfbb603d1d017ce204cebd589d66e0703309b8048c3b0854"}, @@ -562,6 +585,10 @@ regex = [ {file = "regex-2021.7.6-cp39-cp39-win_amd64.whl", hash = "sha256:4c9c3155fe74269f61e27617529b7f09552fbb12e44b1189cebbdb24294e6e1c"}, {file = "regex-2021.7.6.tar.gz", hash = "sha256:8394e266005f2d8c6f0bc6780001f7afa3ef81a7a2111fa35058ded6fce79e4d"}, ] +six = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] smart-open = [ {file = "smart_open-4.2.0.tar.gz", hash = "sha256:d9f5a0f173ccb9bbae528db5a3804f57145815774f77ef755b9b0f3b4b2a9dcb"}, ] diff --git a/pypgstac/pypgstac/__init__.py b/pypgstac/pypgstac/__init__.py index 150f0035..e0b8be88 100644 --- a/pypgstac/pypgstac/__init__.py +++ b/pypgstac/pypgstac/__init__.py @@ -1,2 +1,2 @@ """PyPGStac Version.""" -__version__ = "0.2.9" +__version__ = "0.3.0" diff --git a/pypgstac/pypgstac/load.py b/pypgstac/pypgstac/load.py index 192510ac..19617d54 100644 --- a/pypgstac/pypgstac/load.py +++ b/pypgstac/pypgstac/load.py @@ -109,19 +109,36 @@ async def copy(iter: T, table: tables, conn: asyncpg.Connection) -> None: """Directly use copy to load data.""" bytes_iter = aiter(iter) async with conn.transaction(): - await conn.copy_to_table( - table, - source=bytes_iter, - columns=["content"], - format="csv", - quote=chr(27), - delimiter=chr(31), - ) - await conn.execute( + if table == "collections": + await conn.execute( + """ + CREATE TEMP TABLE pgstactemp (content jsonb) + ON COMMIT DROP; """ - SELECT backfill_partitions(); - """ - ) + ) + await conn.copy_to_table( + "pgstactemp", + source=bytes_iter, + columns=["content"], + format="csv", + quote=chr(27), + delimiter=chr(31), + ) + await conn.execute( + """ + INSERT INTO collections (content) + SELECT content FROM pgstactemp; + """ + ) + if table == "items": + await conn.copy_to_table( + "items_staging", + source=bytes_iter, + columns=["content"], + format="csv", + quote=chr(27), + delimiter=chr(31), + ) async def copy_ignore_duplicates( @@ -130,56 +147,58 @@ async def copy_ignore_duplicates( """Load data first into a temp table to ignore duplicates.""" bytes_iter = aiter(iter) async with conn.transaction(): - await conn.execute( + if table == "collections": + await conn.execute( + """ + CREATE TEMP TABLE pgstactemp (content jsonb) + ON COMMIT DROP; """ - CREATE TEMP TABLE pgstactemp (content jsonb) - ON COMMIT DROP; - """ - ) - await conn.copy_to_table( - "pgstactemp", - source=bytes_iter, - columns=["content"], - format="csv", - quote=chr(27), - delimiter=chr(31), - ) - await conn.execute( + ) + await conn.copy_to_table( + "pgstactemp", + source=bytes_iter, + columns=["content"], + format="csv", + quote=chr(27), + delimiter=chr(31), + ) + await conn.execute( + """ + INSERT INTO collections (content) + SELECT content FROM pgstactemp + ON CONFLICT DO NOTHING; """ - SELECT make_partitions( - min((content->>'datetime')::timestamptz), - max((content->>'datetime')::timestamptz) - ) FROM pgstactemp; - """ - ) - await conn.execute( - f""" - INSERT INTO {table} (content) - SELECT content FROM pgstactemp - ON CONFLICT DO NOTHING; - """ - ) + ) + if table == "items": + await conn.copy_to_table( + "items_staging_ignore", + source=bytes_iter, + columns=["content"], + format="csv", + quote=chr(27), + delimiter=chr(31), + ) async def copy_upsert(iter: T, table: tables, conn: asyncpg.Connection) -> None: """Insert data into a temp table to be able merge data.""" bytes_iter = aiter(iter) async with conn.transaction(): - await conn.execute( - """ - CREATE TEMP TABLE pgstactemp (content jsonb) - ON COMMIT DROP; - """ - ) - await conn.copy_to_table( - "pgstactemp", - source=bytes_iter, - columns=["content"], - format="csv", - quote=chr(27), - delimiter=chr(31), - ) if table == "collections": + await conn.execute( + """ + CREATE TEMP TABLE pgstactemp (content jsonb) + ON COMMIT DROP; + """ + ) + await conn.copy_to_table( + "pgstactemp", + source=bytes_iter, + columns=["content"], + format="csv", + quote=chr(27), + delimiter=chr(31), + ) await conn.execute( """ INSERT INTO collections (content) @@ -190,11 +209,13 @@ async def copy_upsert(iter: T, table: tables, conn: asyncpg.Connection) -> None: """ ) if table == "items": - await conn.execute( - """ - SELECT upsert_item(content) - FROM pgstactemp; - """ + await conn.copy_to_table( + "items_staging_upsert", + source=bytes_iter, + columns=["content"], + format="csv", + quote=chr(27), + delimiter=chr(31), ) diff --git a/pypgstac/pypgstac/migrations/pgstac.0.2.9-0.3.0.sql b/pypgstac/pypgstac/migrations/pgstac.0.2.9-0.3.0.sql new file mode 100644 index 00000000..518a5fc0 --- /dev/null +++ b/pypgstac/pypgstac/migrations/pgstac.0.2.9-0.3.0.sql @@ -0,0 +1,1606 @@ +SET SEARCH_PATH to pgstac, public; +ALTER SCHEMA pgstac RENAME TO pgstac_bk; + +CREATE SCHEMA pgstac; + +ALTER TABLE pgstac_bk.migrations SET SCHEMA pgstac; +ALTER TABLE pgstac_bk.collections SET SCHEMA pgstac; + +CREATE OR REPLACE FUNCTION notice(VARIADIC text[]) RETURNS boolean AS $$ +DECLARE +debug boolean := current_setting('pgstac.debug', true); +BEGIN + IF debug THEN + RAISE NOTICE 'NOTICE FROM FUNC: % >>>>> %', concat_ws(' | ', $1), clock_timestamp(); + RETURN TRUE; + END IF; + RETURN FALSE; +END; +$$ LANGUAGE PLPGSQL; + +CREATE OR REPLACE FUNCTION empty_arr(ANYARRAY) RETURNS BOOLEAN AS $$ +SELECT CASE + WHEN $1 IS NULL THEN TRUE + WHEN cardinality($1)<1 THEN TRUE +ELSE FALSE +END; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION array_map_ident(_a text[]) + RETURNS text[] AS $$ + SELECT array_agg(quote_ident(v)) FROM unnest(_a) v; +$$ LANGUAGE sql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION array_map_literal(_a text[]) + RETURNS text[] AS $$ + SELECT array_agg(quote_literal(v)) FROM unnest(_a) v; +$$ LANGUAGE sql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION estimated_count(_where text) RETURNS bigint AS $$ +DECLARE +rec record; +rows bigint; +BEGIN + FOR rec in EXECUTE format( + $q$ + EXPLAIN SELECT 1 FROM items WHERE %s + $q$, + _where) + LOOP + rows := substring(rec."QUERY PLAN" FROM ' rows=([[:digit:]]+)'); + EXIT WHEN rows IS NOT NULL; + END LOOP; + + RETURN rows; +END; +$$ LANGUAGE PLPGSQL; +/* converts a jsonb text array to a pg text[] array */ +CREATE OR REPLACE FUNCTION textarr(_js jsonb) + RETURNS text[] AS $$ + SELECT + CASE jsonb_typeof(_js) + WHEN 'array' THEN ARRAY(SELECT jsonb_array_elements_text(_js)) + ELSE ARRAY[_js->>0] + END +; +$$ LANGUAGE sql IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION jsonb_paths (IN jdata jsonb, OUT path text[], OUT value jsonb) RETURNS +SETOF RECORD AS $$ +with recursive extract_all as +( + select + ARRAY[key]::text[] as path, + value + FROM jsonb_each(jdata) +union all + select + path || coalesce(obj_key, (arr_key- 1)::text), + coalesce(obj_value, arr_value) + from extract_all + left join lateral + jsonb_each(case jsonb_typeof(value) when 'object' then value end) + as o(obj_key, obj_value) + on jsonb_typeof(value) = 'object' + left join lateral + jsonb_array_elements(case jsonb_typeof(value) when 'array' then value end) + with ordinality as a(arr_value, arr_key) + on jsonb_typeof(value) = 'array' + where obj_key is not null or arr_key is not null +) +select * +from extract_all; +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION jsonb_obj_paths (IN jdata jsonb, OUT path text[], OUT value jsonb) RETURNS +SETOF RECORD AS $$ +with recursive extract_all as +( + select + ARRAY[key]::text[] as path, + value + FROM jsonb_each(jdata) +union all + select + path || obj_key, + obj_value + from extract_all + left join lateral + jsonb_each(case jsonb_typeof(value) when 'object' then value end) + as o(obj_key, obj_value) + on jsonb_typeof(value) = 'object' + where obj_key is not null +) +select * +from extract_all; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION jsonb_val_paths (IN jdata jsonb, OUT path text[], OUT value jsonb) RETURNS +SETOF RECORD AS $$ +SELECT * FROM jsonb_obj_paths(jdata) WHERE jsonb_typeof(value) not in ('object','array'); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION path_includes(IN path text[], IN includes text[]) RETURNS BOOLEAN AS $$ +WITH t AS (SELECT unnest(includes) i) +SELECT EXISTS ( + SELECT 1 FROM t WHERE path @> string_to_array(trim(i), '.') +); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION path_excludes(IN path text[], IN excludes text[]) RETURNS BOOLEAN AS $$ +WITH t AS (SELECT unnest(excludes) e) +SELECT NOT EXISTS ( + SELECT 1 FROM t WHERE path @> string_to_array(trim(e), '.') +); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION jsonb_obj_paths_filtered ( + IN jdata jsonb, + IN includes text[] DEFAULT ARRAY[]::text[], + IN excludes text[] DEFAULT ARRAY[]::text[], + OUT path text[], + OUT value jsonb +) RETURNS +SETOF RECORD AS $$ +SELECT path, value +FROM jsonb_obj_paths(jdata) +WHERE + CASE WHEN cardinality(includes) > 0 THEN path_includes(path, includes) ELSE TRUE END + AND + path_excludes(path, excludes) + +; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION filter_jsonb( + IN jdata jsonb, + IN includes text[] DEFAULT ARRAY[]::text[], + IN excludes text[] DEFAULT ARRAY[]::text[] +) RETURNS jsonb AS $$ +DECLARE +rec RECORD; +outj jsonb := '{}'::jsonb; +created_paths text[] := '{}'::text[]; +BEGIN + +IF empty_arr(includes) AND empty_arr(excludes) THEN +RAISE NOTICE 'no filter'; + RETURN jdata; +END IF; +FOR rec in +SELECT * FROM jsonb_obj_paths_filtered(jdata, includes, excludes) +WHERE jsonb_typeof(value) != 'object' +LOOP + IF array_length(rec.path,1)>1 THEN + FOR i IN 1..(array_length(rec.path,1)-1) LOOP + IF NOT array_to_string(rec.path[1:i],'.') = ANY (created_paths) THEN + outj := jsonb_set(outj, rec.path[1:i],'{}', true); + created_paths := created_paths || array_to_string(rec.path[1:i],'.'); + END IF; + END LOOP; + END IF; + outj := jsonb_set(outj, rec.path, rec.value, true); + created_paths := created_paths || array_to_string(rec.path,'.'); +END LOOP; +RETURN outj; +END; +$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION flip_jsonb_array(j jsonb) RETURNS jsonb AS $$ +SELECT jsonb_agg(value) FROM (SELECT value FROM jsonb_array_elements(j) WITH ORDINALITY ORDER BY ordinality DESC) as t; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; +/* Functions to create an iterable of cursors over partitions. */ +CREATE OR REPLACE FUNCTION create_cursor(q text) RETURNS refcursor AS $$ +DECLARE + curs refcursor; +BEGIN + OPEN curs FOR EXECUTE q; + RETURN curs; +END; +$$ LANGUAGE PLPGSQL; + +CREATE OR REPLACE FUNCTION partition_queries( + IN _where text DEFAULT 'TRUE', + IN _orderby text DEFAULT 'datetime DESC, id DESC' +) RETURNS SETOF text AS $$ +DECLARE + partition_query text; + query text; + p record; + cursors refcursor; +BEGIN +IF _orderby ILIKE 'datetime d%' THEN + partition_query := format($q$ + SELECT partition, tstzrange + FROM items_partitions + ORDER BY tstzrange DESC; + $q$); +ELSIF _orderby ILIKE 'datetime a%' THEN + partition_query := format($q$ + SELECT partition, tstzrange + FROM items_partitions + ORDER BY tstzrange ASC + ; + $q$); +ELSE + query := format($q$ + SELECT * FROM items + WHERE %s + ORDER BY %s + $q$, _where, _orderby + ); + + RETURN NEXT query; + RETURN; +END IF; +--RAISE NOTICE 'Partition Query: %', partition_query; +FOR p IN + EXECUTE partition_query +LOOP + query := format($q$ + SELECT * FROM items + WHERE datetime >= %L AND datetime < %L AND %s + ORDER BY %s + $q$, lower(p.tstzrange), upper(p.tstzrange), _where, _orderby + ); + --RAISE NOTICE 'query: %', query; + RETURN NEXT query; +END LOOP; +RETURN; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION partition_cursor( + IN _where text DEFAULT 'TRUE', + IN _orderby text DEFAULT 'datetime DESC, id DESC' +) RETURNS SETOF refcursor AS $$ +DECLARE + partition_query text; + query text; + p record; + cursors refcursor; +BEGIN +FOR query IN SELECT * FROM partion_queries(_where, _orderby) LOOP + RETURN NEXT create_cursor(query); +END LOOP; +RETURN; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION partition_count( + IN _where text DEFAULT 'TRUE' +) RETURNS bigint AS $$ +DECLARE + partition_query text; + query text; + p record; + subtotal bigint; + total bigint := 0; +BEGIN +partition_query := format($q$ + SELECT partition, tstzrange + FROM items_partitions + ORDER BY tstzrange DESC; +$q$); +RAISE NOTICE 'Partition Query: %', partition_query; +FOR p IN + EXECUTE partition_query +LOOP + query := format($q$ + SELECT count(*) FROM items + WHERE datetime BETWEEN %L AND %L AND %s + $q$, lower(p.tstzrange), upper(p.tstzrange), _where + ); + RAISE NOTICE 'Query %', query; + RAISE NOTICE 'Partition %, Count %, Total %',p.partition, subtotal, total; + EXECUTE query INTO subtotal; + total := subtotal + total; +END LOOP; +RETURN total; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; +/* looks for a geometry in a stac item first from geometry and falling back to bbox */ +CREATE OR REPLACE FUNCTION stac_geom(value jsonb) RETURNS geometry AS $$ +SELECT + CASE + WHEN value->>'geometry' IS NOT NULL THEN + ST_GeomFromGeoJSON(value->>'geometry') + WHEN value->>'bbox' IS NOT NULL THEN + ST_MakeEnvelope( + (value->'bbox'->>0)::float, + (value->'bbox'->>1)::float, + (value->'bbox'->>2)::float, + (value->'bbox'->>3)::float, + 4326 + ) + ELSE NULL + END as geometry +; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION stac_datetime(value jsonb) RETURNS timestamptz AS $$ +SELECT COALESCE( + (value->'properties'->>'datetime')::timestamptz, + (value->'properties'->>'start_datetime')::timestamptz +); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET TIMEZONE='UTC'; + +CREATE OR REPLACE FUNCTION stac_end_datetime(value jsonb) RETURNS timestamptz AS $$ +SELECT COALESCE( + (value->'properties'->>'datetime')::timestamptz, + (value->'properties'->>'end_datetime')::timestamptz +); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET TIMEZONE='UTC'; + + +CREATE OR REPLACE FUNCTION stac_daterange(value jsonb) RETURNS tstzrange AS $$ +SELECT tstzrange(stac_datetime(value),stac_end_datetime(value)); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET TIMEZONE='UTC'; +SET SEARCH_PATH TO pgstac, public; + +CREATE TABLE IF NOT EXISTS collections ( + id VARCHAR GENERATED ALWAYS AS (content->>'id') STORED PRIMARY KEY, + content JSONB +); + +CREATE OR REPLACE FUNCTION create_collection(data jsonb) RETURNS VOID AS $$ + INSERT INTO collections (content) + VALUES (data) + ; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION update_collection(data jsonb) RETURNS VOID AS $$ +DECLARE +out collections%ROWTYPE; +BEGIN + UPDATE collections SET content=data WHERE id = data->>'id' RETURNING * INTO STRICT out; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION upsert_collection(data jsonb) RETURNS VOID AS $$ + INSERT INTO collections (content) + VALUES (data) + ON CONFLICT (id) DO + UPDATE + SET content=EXCLUDED.content + ; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION delete_collection(_id text) RETURNS VOID AS $$ +DECLARE +out collections%ROWTYPE; +BEGIN + DELETE FROM collections WHERE id = _id RETURNING * INTO STRICT out; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + + +CREATE OR REPLACE FUNCTION get_collection(id text) RETURNS jsonb AS $$ +SELECT content FROM collections +WHERE id=$1 +; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION all_collections() RETURNS jsonb AS $$ +SELECT jsonb_agg(content) FROM collections; +; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac, public; +SET SEARCH_PATH TO pgstac, public; + +CREATE TABLE IF NOT EXISTS items ( + id text NOT NULL, + geometry geometry NOT NULL, + collection_id text NOT NULL, + datetime timestamptz NOT NULL, + end_datetime timestamptz NOT NULL, + properties jsonb NOT NULL, + content JSONB NOT NULL +) +PARTITION BY RANGE (datetime) +; + +CREATE OR REPLACE FUNCTION properties_idx (IN content jsonb) RETURNS jsonb AS $$ + with recursive extract_all as + ( + select + ARRAY[key]::text[] as path, + ARRAY[key]::text[] as fullpath, + value + FROM jsonb_each(content->'properties') + union all + select + CASE WHEN obj_key IS NOT NULL THEN path || obj_key ELSE path END, + path || coalesce(obj_key, (arr_key- 1)::text), + coalesce(obj_value, arr_value) + from extract_all + left join lateral + jsonb_each(case jsonb_typeof(value) when 'object' then value end) + as o(obj_key, obj_value) + on jsonb_typeof(value) = 'object' + left join lateral + jsonb_array_elements(case jsonb_typeof(value) when 'array' then value end) + with ordinality as a(arr_value, arr_key) + on jsonb_typeof(value) = 'array' + where obj_key is not null or arr_key is not null + ) + , paths AS ( + select + array_to_string(path, '.') as path, + value + FROM extract_all + WHERE + jsonb_typeof(value) NOT IN ('array','object') + ), grouped AS ( + SELECT path, jsonb_agg(distinct value) vals FROM paths group by path + ) SELECT coalesce(jsonb_object_agg(path, CASE WHEN jsonb_array_length(vals)=1 THEN vals->0 ELSE vals END) - '{datetime}'::text[], '{}'::jsonb) FROM grouped + ; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET JIT TO OFF; + + +CREATE OR REPLACE FUNCTION analyze_empty_partitions() RETURNS VOID AS $$ +DECLARE + p text; +BEGIN + FOR p IN SELECT partition FROM all_items_partitions WHERE est_cnt = 0 LOOP + EXECUTE format('ANALYZE %I;', p); + END LOOP; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE OR REPLACE FUNCTION items_partition_name(timestamptz) RETURNS text AS $$ + SELECT to_char($1, '"items_p"IYYY"w"IW'); +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION items_partition_exists(text) RETURNS boolean AS $$ + SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class WHERE relname=$1); +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION items_partition_exists(timestamptz) RETURNS boolean AS $$ + SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class WHERE relname=items_partition_name($1)); +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION items_partition_create_worker(partition text, partition_start timestamptz, partition_end timestamptz) RETURNS VOID AS $$ +DECLARE + err_context text; +BEGIN + EXECUTE format( + $f$ + CREATE TABLE IF NOT EXISTS %1$I PARTITION OF items + FOR VALUES FROM (%2$L) TO (%3$L); + CREATE UNIQUE INDEX IF NOT EXISTS %4$I ON %1$I (id); + $f$, + partition, + partition_start, + partition_end, + concat(partition, '_id_pk') + ); +EXCEPTION + WHEN duplicate_table THEN + RAISE NOTICE 'Partition % already exists.', partition; + WHEN others THEN + GET STACKED DIAGNOSTICS err_context = PG_EXCEPTION_CONTEXT; + RAISE INFO 'Error Name:%',SQLERRM; + RAISE INFO 'Error State:%', SQLSTATE; + RAISE INFO 'Error Context:%', err_context; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH to pgstac, public; + +CREATE OR REPLACE FUNCTION items_partition_create(ts timestamptz) RETURNS text AS $$ +DECLARE + partition text := items_partition_name(ts); + partition_start timestamptz; + partition_end timestamptz; +BEGIN + IF items_partition_exists(partition) THEN + RETURN partition; + END IF; + partition_start := date_trunc('week', ts); + partition_end := partition_start + '1 week'::interval; + PERFORM items_partition_create_worker(partition, partition_start, partition_end); + RAISE NOTICE 'partition: %', partition; + RETURN partition; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION items_partition_create(st timestamptz, et timestamptz) RETURNS SETOF text AS $$ +WITH t AS ( + SELECT + generate_series( + date_trunc('week',st), + date_trunc('week', et), + '1 week'::interval + ) w +) +SELECT items_partition_create(w) FROM t; +$$ LANGUAGE SQL; + + +CREATE UNLOGGED TABLE items_staging ( + content JSONB NOT NULL +); + +CREATE OR REPLACE FUNCTION items_staging_insert_triggerfunc() RETURNS TRIGGER AS $$ +DECLARE + mindate timestamptz; + maxdate timestamptz; + partition text; +BEGIN + SELECT min(stac_datetime(content)), max(stac_datetime(content)) INTO mindate, maxdate FROM newdata; + PERFORM items_partition_create(mindate, maxdate); + INSERT INTO items (id, geometry, collection_id, datetime, end_datetime, properties, content) + SELECT + content->>'id', + stac_geom(content), + content->>'collection', + stac_datetime(content), + stac_end_datetime(content), + properties_idx(content), + content + FROM newdata + ; + DELETE FROM items_staging; + PERFORM analyze_empty_partitions(); + RETURN NULL; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE TRIGGER items_staging_insert_trigger AFTER INSERT ON items_staging REFERENCING NEW TABLE AS newdata + FOR EACH STATEMENT EXECUTE PROCEDURE items_staging_insert_triggerfunc(); + + +CREATE UNLOGGED TABLE items_staging_ignore ( + content JSONB NOT NULL +); + +CREATE OR REPLACE FUNCTION items_staging_ignore_insert_triggerfunc() RETURNS TRIGGER AS $$ +DECLARE + mindate timestamptz; + maxdate timestamptz; + partition text; +BEGIN + SELECT min(stac_datetime(content)), max(stac_datetime(content)) INTO mindate, maxdate FROM newdata; + PERFORM items_partition_create(mindate, maxdate); + INSERT INTO items (id, geometry, collection_id, datetime, end_datetime, properties, content) + SELECT + content->>'id', + stac_geom(content), + content->>'collection', + stac_datetime(content), + stac_end_datetime(content), + properties_idx(content), + content + FROM newdata + ON CONFLICT DO NOTHING + ; + DELETE FROM items_staging_ignore; + PERFORM analyze_empty_partitions(); + RETURN NULL; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE TRIGGER items_staging_ignore_insert_trigger AFTER INSERT ON items_staging_ignore REFERENCING NEW TABLE AS newdata + FOR EACH STATEMENT EXECUTE PROCEDURE items_staging_ignore_insert_triggerfunc(); + +CREATE UNLOGGED TABLE items_staging_upsert ( + content JSONB NOT NULL +); + +CREATE OR REPLACE FUNCTION items_staging_upsert_insert_triggerfunc() RETURNS TRIGGER AS $$ +DECLARE + mindate timestamptz; + maxdate timestamptz; + partition text; +BEGIN + SELECT min(stac_datetime(content)), max(stac_datetime(content)) INTO mindate, maxdate FROM newdata; + PERFORM items_partition_create(mindate, maxdate); + INSERT INTO items (id, geometry, collection_id, datetime, end_datetime, properties, content) + SELECT + content->>'id', + stac_geom(content), + content->>'collection', + stac_datetime(content), + stac_end_datetime(content), + properties_idx(content), + content + FROM newdata + ON CONFLICT (datetime, id) DO UPDATE SET + content = EXCLUDED.content + WHERE items.content IS DISTINCT FROM EXCLUDED.content + ; + DELETE FROM items_staging_upsert; + PERFORM analyze_empty_partitions(); + RETURN NULL; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE TRIGGER items_staging_upsert_insert_trigger AFTER INSERT ON items_staging_upsert REFERENCING NEW TABLE AS newdata + FOR EACH STATEMENT EXECUTE PROCEDURE items_staging_upsert_insert_triggerfunc(); + +CREATE OR REPLACE FUNCTION items_update_triggerfunc() RETURNS TRIGGER AS $$ +DECLARE +BEGIN + NEW.id := NEW.content->>'id'; + NEW.datetime := stac_datetime(NEW.content); + NEW.end_datetime := stac_end_datetime(NEW.content); + NEW.collection_id := NEW.content->>'collection'; + NEW.geometry := stac_geom(NEW.content); + NEW.properties := properties_idx(NEW.content); + IF TG_OP = 'UPDATE' AND NEW IS NOT DISTINCT FROM OLD THEN + RETURN NULL; + END IF; + RETURN NEW; +END; +$$ LANGUAGE PLPGSQL; + +CREATE TRIGGER items_update_trigger BEFORE UPDATE ON items + FOR EACH ROW EXECUTE PROCEDURE items_update_triggerfunc(); + +/* +View to get a table of available items partitions +with date ranges +*/ +CREATE VIEW all_items_partitions AS +WITH base AS +(SELECT + c.oid::pg_catalog.regclass::text as partition, + pg_catalog.pg_get_expr(c.relpartbound, c.oid) as _constraint, + regexp_matches( + pg_catalog.pg_get_expr(c.relpartbound, c.oid), + E'\\(''\([0-9 :+-]*\)''\\).*\\(''\([0-9 :+-]*\)''\\)' + ) as t, + reltuples::bigint as est_cnt +FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i +WHERE c.oid = i.inhrelid AND i.inhparent = 'items'::regclass) +SELECT partition, tstzrange( + t[1]::timestamptz, + t[2]::timestamptz +), est_cnt +FROM base +ORDER BY 2 desc; + +CREATE OR REPLACE VIEW items_partitions AS +SELECT * FROM all_items_partitions WHERE est_cnt>0; + +CREATE OR REPLACE FUNCTION get_item(_id text) RETURNS jsonb AS $$ + SELECT content FROM items WHERE id=_id; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION delete_item(_id text) RETURNS VOID AS $$ +DECLARE +out items%ROWTYPE; +BEGIN + DELETE FROM items WHERE id = _id RETURNING * INTO STRICT out; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION create_item(data jsonb) RETURNS VOID AS $$ + INSERT INTO items_staging (content) VALUES (data); +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac,public; + + +CREATE OR REPLACE FUNCTION update_item(data jsonb) RETURNS VOID AS $$ +DECLARE + out items%ROWTYPE; +BEGIN + UPDATE items SET content=data WHERE id = data->>'id' RETURNING * INTO STRICT out; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION upsert_item(data jsonb) RETURNS VOID AS $$ + INSERT INTO items_staging_upsert (content) VALUES (data); +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac,public; + + +CREATE OR REPLACE FUNCTION collection_bbox(id text) RETURNS jsonb AS $$ +SELECT (replace(replace(replace(st_extent(geometry)::text,'BOX(','[['),')',']]'),' ',','))::jsonb +FROM items WHERE collection_id=$1; +; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION collection_temporal_extent(id text) RETURNS jsonb AS $$ +SELECT to_jsonb(array[array[min(datetime)::text, max(datetime)::text]]) +FROM items WHERE collection_id=$1; +; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION update_collection_extents() RETURNS VOID AS $$ +UPDATE collections SET + content = content || + jsonb_build_object( + 'extent', jsonb_build_object( + 'spatial', jsonb_build_object( + 'bbox', collection_bbox(collections.id) + ), + 'temporal', jsonb_build_object( + 'interval', collection_temporal_extent(collections.id) + ) + ) + ) +; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac, public; + +----- BEGIN SEARCH + +CREATE OR REPLACE FUNCTION items_path( + IN dotpath text, + OUT field text, + OUT path text, + OUT path_txt text, + OUT jsonpath text, + OUT eq text +) RETURNS RECORD AS $$ +DECLARE +path_elements text[]; +last_element text; +BEGIN +dotpath := replace(trim(dotpath), 'properties.', ''); + +IF dotpath = '' THEN + RETURN; +END IF; + +path_elements := string_to_array(dotpath, '.'); +jsonpath := NULL; + +IF path_elements[1] IN ('id','geometry','datetime') THEN + field := path_elements[1]; + path_elements := path_elements[2:]; +ELSIF path_elements[1] = 'collection' THEN + field := 'collection_id'; + path_elements := path_elements[2:]; +ELSIF path_elements[1] IN ('links', 'assets', 'stac_version', 'stac_extensions') THEN + field := 'content'; +ELSE + field := 'content'; + path_elements := '{properties}'::text[] || path_elements; +END IF; +IF cardinality(path_elements)<1 THEN + path := field; + path_txt := field; + jsonpath := '$'; + eq := NULL; -- format($F$ %s = %%s $F$, field); + RETURN; +END IF; + + +last_element := path_elements[cardinality(path_elements)]; +path_elements := path_elements[1:cardinality(path_elements)-1]; +jsonpath := concat(array_to_string('{$}'::text[] || array_map_ident(path_elements), '.'), '.', quote_ident(last_element)); +path_elements := array_map_literal(path_elements); +path := format($F$ properties->%s $F$, quote_literal(dotpath)); +path_txt := format($F$ properties->>%s $F$, quote_literal(dotpath)); +eq := format($F$ properties @? '$.%s[*] ? (@ == %%s) '$F$, quote_ident(dotpath)); + +RAISE NOTICE 'ITEMS PATH -- % % % % %', field, path, path_txt, jsonpath, eq; +RETURN; +END; +$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION parse_dtrange(IN _indate jsonb, OUT _tstzrange tstzrange) AS $$ +WITH t AS ( + SELECT CASE + WHEN jsonb_typeof(_indate) = 'array' THEN + textarr(_indate) + ELSE + regexp_split_to_array( + btrim(_indate::text,'"'), + '/' + ) + END AS arr +) +, t1 AS ( + SELECT + CASE + WHEN array_upper(arr,1) = 1 OR arr[1] = '..' OR arr[1] IS NULL THEN '-infinity'::timestamptz + ELSE arr[1]::timestamptz + END AS st, + CASE + WHEN array_upper(arr,1) = 1 THEN arr[1]::timestamptz + WHEN arr[2] = '..' OR arr[2] IS NULL THEN 'infinity'::timestamptz + ELSE arr[2]::timestamptz + END AS et + FROM t +) +SELECT + tstzrange(st,et) +FROM t1; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION bbox_geom(_bbox jsonb) RETURNS geometry AS $$ +SELECT CASE jsonb_array_length(_bbox) + WHEN 4 THEN + ST_SetSRID(ST_MakeEnvelope( + (_bbox->>0)::float, + (_bbox->>1)::float, + (_bbox->>2)::float, + (_bbox->>3)::float + ),4326) + WHEN 6 THEN + ST_SetSRID(ST_3DMakeBox( + ST_MakePoint( + (_bbox->>0)::float, + (_bbox->>1)::float, + (_bbox->>2)::float + ), + ST_MakePoint( + (_bbox->>3)::float, + (_bbox->>4)::float, + (_bbox->>5)::float + ) + ),4326) + ELSE null END; +; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION cql_and_append(existing jsonb, newfilters jsonb) RETURNS jsonb AS $$ +SELECT CASE WHEN existing ? 'filter' AND newfilters IS NOT NULL THEN + jsonb_build_object( + 'and', + jsonb_build_array( + existing->'filter', + newfilters + ) + ) +ELSE + newfilters +END; +$$ LANGUAGE SQL; + + +-- ADDs base filters (ids, collections, datetime, bbox, intersects) that are +-- added outside of the filter/query in the stac request +CREATE OR REPLACE FUNCTION add_filters_to_cql(j jsonb) RETURNS jsonb AS $$ +DECLARE +newprop jsonb; +newprops jsonb := '[]'::jsonb; +BEGIN +IF j ? 'id' THEN + newprop := jsonb_build_object( + 'in', + jsonb_build_array( + '{"property":"id"}'::jsonb, + j->'id' + ) + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; +IF j ? 'collection' THEN + newprop := jsonb_build_object( + 'in', + jsonb_build_array( + '{"property":"collection"}'::jsonb, + j->'collection' + ) + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; + +IF j ? 'datetime' THEN + newprop := format( + '{"anyinteracts":[{"property":"datetime"}, %s]}', + j->'datetime' + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; + +IF j ? 'bbox' THEN + newprop := format( + '{"intersects":[{"property":"geometry"}, %s]}', + j->'bbox' + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; + +IF j ? 'intersects' THEN + newprop := format( + '{"intersects":[{"property":"geometry"}, %s]}', + j->'intersects' + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; + +RAISE NOTICE 'newprops: %', newprops; + +IF newprops IS NOT NULL AND jsonb_array_length(newprops) > 0 THEN + return jsonb_set( + j, + '{filter}', + cql_and_append(j, jsonb_build_object('and', newprops)) + ) - '{id,collection,datetime,bbox,intersects}'::text[]; +END IF; + +return j; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE OR REPLACE FUNCTION query_to_cqlfilter(j jsonb) RETURNS jsonb AS $$ +-- Translates anything passed in through the deprecated "query" into equivalent CQL +WITH t AS ( + SELECT key as property, value as ops + FROM jsonb_each(j->'query') +), t2 AS ( + SELECT property, (jsonb_each(ops)).* + FROM t WHERE jsonb_typeof(ops) = 'object' + UNION ALL + SELECT property, 'eq', ops + FROM t WHERE jsonb_typeof(ops) != 'object' +), t3 AS ( +SELECT + jsonb_strip_nulls(jsonb_build_object( + 'and', + jsonb_agg( + jsonb_build_object( + key, + jsonb_build_array( + jsonb_build_object('property',property), + value + ) + ) + ) + )) as qcql FROM t2 +) +SELECT + CASE WHEN qcql IS NOT NULL THEN + jsonb_set(j, '{filter}', cql_and_append(j, qcql)) - 'query' + ELSE j + END +FROM t3 +; +$$ LANGUAGE SQL; + + + +CREATE OR REPLACE FUNCTION temporal_op_query(op text, args jsonb) RETURNS text AS $$ +DECLARE +ll text := 'datetime'; +lh text := 'end_datetime'; +rrange tstzrange; +rl text; +rh text; +outq text; +BEGIN +rrange := parse_dtrange(args->1); +RAISE NOTICE 'Constructing temporal query OP: %, ARGS: %, RRANGE: %', op, args, rrange; +op := lower(op); +rl := format('%L::timestamptz', lower(rrange)); +rh := format('%L::timestamptz', upper(rrange)); +outq := CASE op + WHEN 't_before' THEN 'lh < rl' + WHEN 't_after' THEN 'll > rh' + WHEN 't_meets' THEN 'lh = rl' + WHEN 't_metby' THEN 'll = rh' + WHEN 't_overlaps' THEN 'll < rl AND rl < lh < rh' + WHEN 't_overlappedby' THEN 'rl < ll < rh AND lh > rh' + WHEN 't_starts' THEN 'll = rl AND lh < rh' + WHEN 't_startedby' THEN 'll = rl AND lh > rh' + WHEN 't_during' THEN 'll > rl AND lh < rh' + WHEN 't_contains' THEN 'll < rl AND lh > rh' + WHEN 't_finishes' THEN 'll > rl AND lh = rh' + WHEN 't_finishedby' THEN 'll < rl AND lh = rh' + WHEN 't_equals' THEN 'll = rl AND lh = rh' + WHEN 't_disjoint' THEN 'NOT (ll <= rh AND lh >= rl)' + WHEN 't_intersects' THEN 'll <= rh AND lh >= rl' + WHEN 'anyinteracts' THEN 'll <= rh AND lh >= rl' +END; +outq := regexp_replace(outq, '\mll\M', ll); +outq := regexp_replace(outq, '\mlh\M', lh); +outq := regexp_replace(outq, '\mrl\M', rl); +outq := regexp_replace(outq, '\mrh\M', rh); +outq := format('(%s)', outq); +RETURN outq; +END; +$$ LANGUAGE PLPGSQL; + +CREATE OR REPLACE FUNCTION spatial_op_query(op text, args jsonb) RETURNS text AS $$ +DECLARE +geom text; +j jsonb := args->1; +BEGIN +op := lower(op); +RAISE NOTICE 'Constructing spatial query OP: %, ARGS: %', op, args; +IF op NOT IN ('s_equals','s_disjoint','s_touches','s_within','s_overlaps','s_crosses','s_intersects','intersects','s_contains') THEN + RAISE EXCEPTION 'Spatial Operator % Not Supported', op; +END IF; +op := regexp_replace(op, '^s_', 'st_'); +IF op = 'intersects' THEN + op := 'st_intersects'; +END IF; +-- Convert geometry to WKB string +IF j ? 'type' AND j ? 'coordinates' THEN + geom := st_geomfromgeojson(j)::text; +ELSIF jsonb_typeof(j) = 'array' THEN + geom := bbox_geom(j)::text; +END IF; + +RETURN format('%s(geometry, %L::geometry)', op, geom); +END; +$$ LANGUAGE PLPGSQL; + + +/* cql_query_op -- Parses a CQL query operation, recursing when necessary + IN jsonb -- a subelement from a valid stac query + IN text -- the operator being used on elements passed in + RETURNS a SQL fragment to be used in a WHERE clause +*/ +CREATE OR REPLACE FUNCTION cql_query_op(j jsonb, _op text DEFAULT NULL) RETURNS text AS $$ +DECLARE +jtype text := jsonb_typeof(j); +op text := lower(_op); +ops jsonb := + '{ + "eq": "%s = %s", + "lt": "%s < %s", + "lte": "%s <= %s", + "gt": "%s > %s", + "gte": "%s >= %s", + "like": "%s LIKE %s", + "+": "%s + %s", + "-": "%s - %s", + "*": "%s * %s", + "/": "%s / %s", + "in": "%s = ANY (%s)", + "not": "NOT (%s)", + "between": "%s BETWEEN %s AND %s", + "lower":"lower(%s)" + }'::jsonb; +ret text; +args text[] := NULL; + +BEGIN +RAISE NOTICE 'j: %, op: %, jtype: %', j, op, jtype; + +-- Set Lower Case on Both Arguments When Case Insensitive Flag Set +IF op in ('eq','lt','lte','gt','gte','like') AND jsonb_typeof(j->2) = 'boolean' THEN + IF (j->>2)::boolean THEN + RETURN format(concat('(',ops->>op,')'), cql_query_op(jsonb_build_array(j->0), 'lower'), cql_query_op(jsonb_build_array(j->1), 'lower')); + END IF; +END IF; + +-- Special Case when comparing a property in a jsonb field to a string or number using eq +-- Allows to leverage GIN index on jsonb fields +IF op = 'eq' THEN + IF j->0 ? 'property' + AND jsonb_typeof(j->1) IN ('number','string') + AND (items_path(j->0->>'property')).eq IS NOT NULL + THEN + RETURN format((items_path(j->0->>'property')).eq, j->1); + END IF; +END IF; + +IF op ilike 't_%' or op = 'anyinteracts' THEN + RETURN temporal_op_query(op, j); +END IF; + +IF op ilike 's_%' or op = 'intersects' THEN + RETURN spatial_op_query(op, j); +END IF; + + +IF jtype = 'object' THEN + RAISE NOTICE 'parsing object'; + IF j ? 'property' THEN + -- Convert the property to be used as an identifier + return (items_path(j->>'property')).path_txt; + ELSIF _op IS NULL THEN + -- Iterate to convert elements in an object where the operator has not been set + -- Combining with AND + SELECT + array_to_string(array_agg(cql_query_op(e.value, e.key)), ' AND ') + INTO ret + FROM jsonb_each(j) e; + RETURN ret; + END IF; +END IF; + +IF jtype = 'string' THEN + RETURN quote_literal(j->>0); +END IF; + +IF jtype ='number' THEN + RETURN (j->>0)::numeric; +END IF; + +IF jtype = 'array' AND op IS NULL THEN + RAISE NOTICE 'Parsing array into array arg. j: %', j; + SELECT format($f$ '{%s}'::text[] $f$, string_agg(e,',')) INTO ret FROM jsonb_array_elements_text(j) e; + RETURN ret; +END IF; + + +-- If the type of the passed json is an array +-- Calculate the arguments that will be passed to functions/operators +IF jtype = 'array' THEN + RAISE NOTICE 'Parsing array into args. j: %', j; + -- If any argument is numeric, cast any text arguments to numeric + IF j @? '$[*] ? (@.type() == "number")' THEN + SELECT INTO args + array_agg(concat('(',cql_query_op(e),')::numeric')) + FROM jsonb_array_elements(j) e; + ELSE + SELECT INTO args + array_agg(cql_query_op(e)) + FROM jsonb_array_elements(j) e; + END IF; + --RETURN args; +END IF; +RAISE NOTICE 'ARGS after array cleaning: %', args; + +IF op IS NULL THEN + RETURN args::text[]; +END IF; + +IF args IS NULL OR cardinality(args) < 1 THEN + RAISE NOTICE 'No Args'; + RETURN ''; +END IF; + +IF op IN ('and','or') THEN + SELECT + CONCAT( + '(', + array_to_string(args, UPPER(CONCAT(' ',op,' '))), + ')' + ) INTO ret + FROM jsonb_array_elements(j) e; + RETURN ret; +END IF; + +-- If the op is in the ops json then run using the template in the json +IF ops ? op THEN + RAISE NOTICE 'ARGS: % MAPPED: %',args, array_map_literal(args); + + RETURN format(concat('(',ops->>op,')'), VARIADIC args); +END IF; + +RETURN j->>0; + +END; +$$ LANGUAGE PLPGSQL; + + + + +CREATE OR REPLACE FUNCTION cql_to_where(_search jsonb = '{}'::jsonb) RETURNS text AS $$ +DECLARE +search jsonb := _search; +_where text; +BEGIN +RAISE NOTICE 'SEARCH CQL 1: %', search; + +-- Convert any old style stac query to cql +search := query_to_cqlfilter(search); + +RAISE NOTICE 'SEARCH CQL 2: %', search; + +-- Convert item,collection,datetime,bbox,intersects to cql +search := add_filters_to_cql(search); + +RAISE NOTICE 'SEARCH CQL Final: %', search; +_where := cql_query_op(search->'filter'); + +IF trim(_where) = '' THEN + _where := NULL; +END IF; +_where := coalesce(_where, ' TRUE '); +RETURN _where; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE OR REPLACE FUNCTION parse_sort_dir(_dir text, reverse boolean default false) RETURNS text AS $$ +WITH t AS ( + SELECT COALESCE(upper(_dir), 'ASC') as d +) SELECT + CASE + WHEN NOT reverse THEN d + WHEN d = 'ASC' THEN 'DESC' + WHEN d = 'DESC' THEN 'ASC' + END +FROM t; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sort_dir_to_op(_dir text, prev boolean default false) RETURNS text AS $$ +WITH t AS ( + SELECT COALESCE(upper(_dir), 'ASC') as d +) SELECT + CASE + WHEN d = 'ASC' AND prev THEN '<=' + WHEN d = 'DESC' AND prev THEN '>=' + WHEN d = 'ASC' THEN '>=' + WHEN d = 'DESC' THEN '<=' + END +FROM t; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sort_sqlorderby( + _search jsonb DEFAULT NULL, + reverse boolean DEFAULT FALSE +) RETURNS text AS $$ +WITH sorts AS ( + SELECT + (items_path(value->>'field')).path as key, + parse_sort_dir(value->>'direction', reverse) as dir + FROM jsonb_array_elements( + '[]'::jsonb + || + coalesce(_search->'sort','[{"field":"datetime", "direction":"desc"}]') + || + '[{"field":"id","direction":"desc"}]'::jsonb + ) +) +SELECT array_to_string( + array_agg(concat(key, ' ', dir)), + ', ' +) FROM sorts; +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION get_sort_dir(sort_item jsonb) RETURNS text AS $$ +SELECT CASE WHEN sort_item->>'direction' ILIKE 'desc%' THEN 'DESC' ELSE 'ASC' END; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION get_token_filter(_search jsonb = '{}'::jsonb, token_rec jsonb DEFAULT NULL) RETURNS text AS $$ +DECLARE +token_id text; +filters text[] := '{}'::text[]; +prev boolean := TRUE; +field text; +dir text; +sort record; +orfilters text[] := '{}'::text[]; +andfilters text[] := '{}'::text[]; +output text; +token_where text; +BEGIN +-- If no token provided return NULL +IF token_rec IS NULL THEN + IF NOT (_search ? 'token' AND + ( + (_search->>'token' ILIKE 'prev:%') + OR + (_search->>'token' ILIKE 'next:%') + ) + ) THEN + RETURN NULL; + END IF; + prev := (_search->>'token' ILIKE 'prev:%'); + token_id := substr(_search->>'token', 6); + SELECT to_jsonb(items) INTO token_rec FROM items WHERE id=token_id; +END IF; +RAISE NOTICE 'TOKEN ID: %', token_rec->'id'; + +CREATE TEMP TABLE sorts ( + _row int GENERATED ALWAYS AS IDENTITY NOT NULL, + _field text PRIMARY KEY, + _dir text NOT NULL, + _val text +) ON COMMIT DROP; + +-- Make sure we only have distinct columns to sort with taking the first one we get +INSERT INTO sorts (_field, _dir) + SELECT + (items_path(value->>'field')).path, + get_sort_dir(value) + FROM + jsonb_array_elements(coalesce(_search->'sort','[{"field":"datetime","direction":"desc"}]')) +ON CONFLICT DO NOTHING +; + +-- Get the first sort direction provided. As the id is a primary key, if there are any +-- sorts after id they won't do anything, so make sure that id is the last sort item. +SELECT _dir INTO dir FROM sorts ORDER BY _row ASC LIMIT 1; +IF EXISTS (SELECT 1 FROM sorts WHERE _field = 'id') THEN + DELETE FROM sorts WHERE _row > (SELECT _row FROM sorts WHERE _field = 'id'); +ELSE + INSERT INTO sorts (_field, _dir) VALUES ('id', dir); +END IF; + +-- Add value from looked up item to the sorts table +UPDATE sorts SET _val=quote_literal(token_rec->>_field); + +-- Check if all sorts are the same direction and use row comparison +-- to filter +IF (SELECT count(DISTINCT _dir) FROM sorts) = 1 THEN + SELECT format( + '(%s) %s (%s)', + concat_ws(', ', VARIADIC array_agg(quote_ident(_field))), + CASE WHEN (prev AND dir = 'ASC') OR (NOT prev AND dir = 'DESC') THEN '<' ELSE '>' END, + concat_ws(', ', VARIADIC array_agg(_val)) + ) INTO output FROM sorts + WHERE token_rec ? _field + ; +ELSE + FOR sort IN SELECT * FROM sorts ORDER BY _row asc LOOP + RAISE NOTICE 'SORT: %', sort; + IF sort._row = 1 THEN + orfilters := orfilters || format('(%s %s %s)', + quote_ident(sort._field), + CASE WHEN (prev AND sort._dir = 'ASC') OR (NOT prev AND sort._dir = 'DESC') THEN '<' ELSE '>' END, + sort._val + ); + ELSE + orfilters := orfilters || format('(%s AND %s %s %s)', + array_to_string(andfilters, ' AND '), + quote_ident(sort._field), + CASE WHEN (prev AND sort._dir = 'ASC') OR (NOT prev AND sort._dir = 'DESC') THEN '<' ELSE '>' END, + sort._val + ); + + END IF; + andfilters := andfilters || format('%s = %s', + quote_ident(sort._field), + sort._val + ); + END LOOP; + output := array_to_string(orfilters, ' OR '); +END IF; +DROP TABLE IF EXISTS sorts; +token_where := concat('(',coalesce(output,'true'),')'); +IF trim(token_where) = '' THEN + token_where := NULL; +END IF; +RAISE NOTICE 'TOKEN_WHERE: |%|',token_where; +RETURN token_where; +END; +$$ LANGUAGE PLPGSQL; + +CREATE OR REPLACE FUNCTION search_tohash(jsonb) RETURNS jsonb AS $$ + SELECT $1 - '{token,limit,context,includes,excludes}'::text[]; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION search_hash(jsonb) RETURNS text AS $$ + SELECT md5(search_tohash($1)::text); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + + +CREATE TABLE IF NOT EXISTS searches( + hash text GENERATED ALWAYS AS (search_hash(search)) STORED PRIMARY KEY, + search jsonb NOT NULL, + _where text, + orderby text, + lastused timestamptz DEFAULT now(), + usecount bigint DEFAULT 0, + statslastupdated timestamptz, + estimated_count bigint, + total_count bigint +); + +CREATE OR REPLACE FUNCTION search_query(_search jsonb = '{}'::jsonb, updatestats boolean DEFAULT false) RETURNS searches AS $$ +DECLARE + search searches%ROWTYPE; +BEGIN +INSERT INTO searches (search) + VALUES (search_tohash(_search)) + ON CONFLICT DO NOTHING + RETURNING * INTO search; +IF search.hash IS NULL THEN + SELECT * INTO search FROM searches WHERE hash=search_hash(_search); +END IF; +IF search._where IS NULL THEN + search._where := cql_to_where(_search); +END IF; +IF search.orderby IS NULL THEN + search.orderby := sort_sqlorderby(_search); +END IF; + +IF search.statslastupdated IS NULL OR age(search.statslastupdated) > '1 day'::interval OR (_search ? 'context' AND search.total_count IS NULL) THEN + updatestats := TRUE; +END IF; + +IF updatestats THEN + -- Get Estimated Stats + RAISE NOTICE 'Getting stats for %', search._where; + search.estimated_count := estimated_count(search._where); + RAISE NOTICE 'Estimated Count: %', search.estimated_count; + + IF _search ? 'context' OR search.estimated_count < 10000 THEN + --search.total_count := partition_count(search._where); + EXECUTE format( + 'SELECT count(*) FROM items WHERE %s', + search._where + ) INTO search.total_count; + RAISE NOTICE 'Actual Count: %', search.total_count; + ELSE + search.total_count := NULL; + END IF; + search.statslastupdated := now(); +END IF; + +search.lastused := now(); +search.usecount := coalesce(search.usecount,0) + 1; +RAISE NOTICE 'SEARCH: %', search; +UPDATE searches SET + _where = search._where, + orderby = search.orderby, + lastused = search.lastused, + usecount = search.usecount, + statslastupdated = search.statslastupdated, + estimated_count = search.estimated_count, + total_count = search.total_count +WHERE hash = search.hash +; +RETURN search; + +END; +$$ LANGUAGE PLPGSQL; + + + +CREATE OR REPLACE FUNCTION search(_search jsonb = '{}'::jsonb) RETURNS jsonb AS $$ +DECLARE + searches searches%ROWTYPE; + _where text; + token_where text; + full_where text; + orderby text; + query text; + token_type text := substr(_search->>'token',1,4); + _limit int := coalesce((_search->>'limit')::int, 10); + curs refcursor; + cntr int := 0; + iter_record items%ROWTYPE; + first_record items%ROWTYPE; + last_record items%ROWTYPE; + out_records jsonb := '[]'::jsonb; + prev_query text; + next text; + prev_id text; + has_next boolean := false; + has_prev boolean := false; + prev text; + total_count bigint; + context jsonb; + collection jsonb; + includes text[]; + excludes text[]; + exit_flag boolean := FALSE; + batches int := 0; + timer timestamptz := clock_timestamp(); +BEGIN +searches := search_query(_search); +_where := searches._where; +orderby := searches.orderby; +total_count := coalesce(searches.total_count, searches.estimated_count); + + +IF token_type='prev' THEN + token_where := get_token_filter(_search, null::jsonb); + orderby := sort_sqlorderby(_search, TRUE); +END IF; +IF token_type='next' THEN + token_where := get_token_filter(_search, null::jsonb); +END IF; + +full_where := concat_ws(' AND ', _where, token_where); +RAISE NOTICE 'FULL QUERY % %', full_where, clock_timestamp()-timer; +timer := clock_timestamp(); + +FOR query IN SELECT partition_queries(full_where, orderby) LOOP + timer := clock_timestamp(); + query := format('%s LIMIT %L', query, _limit + 1); + RAISE NOTICE 'Partition Query: %', query; + batches := batches + 1; + curs = create_cursor(query); + LOOP + FETCH curs into iter_record; + EXIT WHEN NOT FOUND; + cntr := cntr + 1; + last_record := iter_record; + IF cntr = 1 THEN + first_record := last_record; + END IF; + IF cntr <= _limit THEN + out_records := out_records || last_record.content; + ELSIF cntr > _limit THEN + has_next := true; + exit_flag := true; + EXIT; + END IF; + END LOOP; + RAISE NOTICE 'Query took %', clock_timestamp()-timer; + timer := clock_timestamp(); + EXIT WHEN exit_flag; +END LOOP; +RAISE NOTICE 'Scanned through % partitions.', batches; + + +-- Flip things around if this was the result of a prev token query +IF token_type='prev' THEN + out_records := flip_jsonb_array(out_records); + first_record := last_record; +END IF; + +-- If this query has a token, see if there is data before the first record +IF _search ? 'token' THEN + prev_query := format( + 'SELECT 1 FROM items WHERE %s LIMIT 1', + concat_ws( + ' AND ', + _where, + trim(get_token_filter(_search, to_jsonb(first_record))) + ) + ); + RAISE NOTICE 'Query to get previous record: % --- %', prev_query, first_record; + EXECUTE prev_query INTO has_prev; + IF FOUND and has_prev IS NOT NULL THEN + RAISE NOTICE 'Query results from prev query: %', has_prev; + has_prev := TRUE; + END IF; +END IF; +has_prev := COALESCE(has_prev, FALSE); + +RAISE NOTICE 'token_type: %, has_next: %, has_prev: %', token_type, has_next, has_prev; +IF has_prev THEN + prev := out_records->0->>'id'; +END IF; +IF has_next OR token_type='prev' THEN + next := out_records->-1->>'id'; +END IF; + + + +-- include/exclude any fields following fields extension +IF _search ? 'fields' THEN + IF _search->'fields' ? 'exclude' THEN + excludes=textarr(_search->'fields'->'exclude'); + END IF; + IF _search->'fields' ? 'include' THEN + includes=textarr(_search->'fields'->'include'); + IF array_length(includes, 1)>0 AND NOT 'id' = ANY (includes) THEN + includes = includes || '{id}'; + END IF; + END IF; + SELECT jsonb_agg(filter_jsonb(row, includes, excludes)) INTO out_records FROM jsonb_array_elements(out_records) row; +END IF; + + +context := jsonb_strip_nulls(jsonb_build_object( + 'limit', _limit, + 'matched', total_count, + 'returned', coalesce(jsonb_array_length(out_records), 0) +)); + +collection := jsonb_build_object( + 'type', 'FeatureCollection', + 'features', out_records, + 'next', next, + 'prev', prev, + 'context', context +); + +RETURN collection; +END; +$$ LANGUAGE PLPGSQL SET jit TO off; + + + +----- END SEARCH + +WITH t AS (SELECT items_partition_create_worker(partition, lower(tstzrange), upper(tstzrange)) FROM pgstac_bk.items_partitions) SELECT count(*) FROM t; + +INSERT INTO items (id, geometry, collection_id, datetime, end_datetime, properties, content) +SELECT id, geometry, collection_id, stac_datetime(content), stac_end_datetime(content), properties_idx(content), content +FROM pgstac_bk.items; + +DROP SCHEMA pgstac_bk CASCADE; + +CREATE INDEX "datetime_idx" ON items (datetime); +CREATE INDEX "end_datetime_idx" ON items (end_datetime); +CREATE INDEX "properties_idx" ON items USING GIN (properties jsonb_path_ops); +CREATE INDEX "collection_idx" ON items (collection_id); +CREATE INDEX "geometry_idx" ON items USING GIST (geometry); +CREATE UNIQUE INDEX "items_id_datetime_idx" ON items (datetime, id); + +ALTER TABLE items ADD CONSTRAINT items_collections_fk FOREIGN KEY (collection_id) REFERENCES collections(id) ON DELETE CASCADE DEFERRABLE; + +INSERT INTO pgstac.migrations (version) VALUES ('0.3.0'); diff --git a/pypgstac/pypgstac/migrations/pgstac.0.3.0.sql b/pypgstac/pypgstac/migrations/pgstac.0.3.0.sql new file mode 100644 index 00000000..b97f83f0 --- /dev/null +++ b/pypgstac/pypgstac/migrations/pgstac.0.3.0.sql @@ -0,0 +1,1591 @@ +CREATE EXTENSION IF NOT EXISTS postgis; +CREATE SCHEMA IF NOT EXISTS pgstac; +SET SEARCH_PATH TO pgstac, public; + +CREATE TABLE migrations ( + version text, + datetime timestamptz DEFAULT now() NOT NULL +); + +CREATE OR REPLACE FUNCTION notice(VARIADIC text[]) RETURNS boolean AS $$ +DECLARE +debug boolean := current_setting('pgstac.debug', true); +BEGIN + IF debug THEN + RAISE NOTICE 'NOTICE FROM FUNC: % >>>>> %', concat_ws(' | ', $1), clock_timestamp(); + RETURN TRUE; + END IF; + RETURN FALSE; +END; +$$ LANGUAGE PLPGSQL; + +CREATE OR REPLACE FUNCTION empty_arr(ANYARRAY) RETURNS BOOLEAN AS $$ +SELECT CASE + WHEN $1 IS NULL THEN TRUE + WHEN cardinality($1)<1 THEN TRUE +ELSE FALSE +END; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION array_map_ident(_a text[]) + RETURNS text[] AS $$ + SELECT array_agg(quote_ident(v)) FROM unnest(_a) v; +$$ LANGUAGE sql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION array_map_literal(_a text[]) + RETURNS text[] AS $$ + SELECT array_agg(quote_literal(v)) FROM unnest(_a) v; +$$ LANGUAGE sql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION estimated_count(_where text) RETURNS bigint AS $$ +DECLARE +rec record; +rows bigint; +BEGIN + FOR rec in EXECUTE format( + $q$ + EXPLAIN SELECT 1 FROM items WHERE %s + $q$, + _where) + LOOP + rows := substring(rec."QUERY PLAN" FROM ' rows=([[:digit:]]+)'); + EXIT WHEN rows IS NOT NULL; + END LOOP; + + RETURN rows; +END; +$$ LANGUAGE PLPGSQL; +/* converts a jsonb text array to a pg text[] array */ +CREATE OR REPLACE FUNCTION textarr(_js jsonb) + RETURNS text[] AS $$ + SELECT + CASE jsonb_typeof(_js) + WHEN 'array' THEN ARRAY(SELECT jsonb_array_elements_text(_js)) + ELSE ARRAY[_js->>0] + END +; +$$ LANGUAGE sql IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION jsonb_paths (IN jdata jsonb, OUT path text[], OUT value jsonb) RETURNS +SETOF RECORD AS $$ +with recursive extract_all as +( + select + ARRAY[key]::text[] as path, + value + FROM jsonb_each(jdata) +union all + select + path || coalesce(obj_key, (arr_key- 1)::text), + coalesce(obj_value, arr_value) + from extract_all + left join lateral + jsonb_each(case jsonb_typeof(value) when 'object' then value end) + as o(obj_key, obj_value) + on jsonb_typeof(value) = 'object' + left join lateral + jsonb_array_elements(case jsonb_typeof(value) when 'array' then value end) + with ordinality as a(arr_value, arr_key) + on jsonb_typeof(value) = 'array' + where obj_key is not null or arr_key is not null +) +select * +from extract_all; +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION jsonb_obj_paths (IN jdata jsonb, OUT path text[], OUT value jsonb) RETURNS +SETOF RECORD AS $$ +with recursive extract_all as +( + select + ARRAY[key]::text[] as path, + value + FROM jsonb_each(jdata) +union all + select + path || obj_key, + obj_value + from extract_all + left join lateral + jsonb_each(case jsonb_typeof(value) when 'object' then value end) + as o(obj_key, obj_value) + on jsonb_typeof(value) = 'object' + where obj_key is not null +) +select * +from extract_all; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION jsonb_val_paths (IN jdata jsonb, OUT path text[], OUT value jsonb) RETURNS +SETOF RECORD AS $$ +SELECT * FROM jsonb_obj_paths(jdata) WHERE jsonb_typeof(value) not in ('object','array'); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION path_includes(IN path text[], IN includes text[]) RETURNS BOOLEAN AS $$ +WITH t AS (SELECT unnest(includes) i) +SELECT EXISTS ( + SELECT 1 FROM t WHERE path @> string_to_array(trim(i), '.') +); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION path_excludes(IN path text[], IN excludes text[]) RETURNS BOOLEAN AS $$ +WITH t AS (SELECT unnest(excludes) e) +SELECT NOT EXISTS ( + SELECT 1 FROM t WHERE path @> string_to_array(trim(e), '.') +); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION jsonb_obj_paths_filtered ( + IN jdata jsonb, + IN includes text[] DEFAULT ARRAY[]::text[], + IN excludes text[] DEFAULT ARRAY[]::text[], + OUT path text[], + OUT value jsonb +) RETURNS +SETOF RECORD AS $$ +SELECT path, value +FROM jsonb_obj_paths(jdata) +WHERE + CASE WHEN cardinality(includes) > 0 THEN path_includes(path, includes) ELSE TRUE END + AND + path_excludes(path, excludes) + +; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION filter_jsonb( + IN jdata jsonb, + IN includes text[] DEFAULT ARRAY[]::text[], + IN excludes text[] DEFAULT ARRAY[]::text[] +) RETURNS jsonb AS $$ +DECLARE +rec RECORD; +outj jsonb := '{}'::jsonb; +created_paths text[] := '{}'::text[]; +BEGIN + +IF empty_arr(includes) AND empty_arr(excludes) THEN +RAISE NOTICE 'no filter'; + RETURN jdata; +END IF; +FOR rec in +SELECT * FROM jsonb_obj_paths_filtered(jdata, includes, excludes) +WHERE jsonb_typeof(value) != 'object' +LOOP + IF array_length(rec.path,1)>1 THEN + FOR i IN 1..(array_length(rec.path,1)-1) LOOP + IF NOT array_to_string(rec.path[1:i],'.') = ANY (created_paths) THEN + outj := jsonb_set(outj, rec.path[1:i],'{}', true); + created_paths := created_paths || array_to_string(rec.path[1:i],'.'); + END IF; + END LOOP; + END IF; + outj := jsonb_set(outj, rec.path, rec.value, true); + created_paths := created_paths || array_to_string(rec.path,'.'); +END LOOP; +RETURN outj; +END; +$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION flip_jsonb_array(j jsonb) RETURNS jsonb AS $$ +SELECT jsonb_agg(value) FROM (SELECT value FROM jsonb_array_elements(j) WITH ORDINALITY ORDER BY ordinality DESC) as t; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; +/* Functions to create an iterable of cursors over partitions. */ +CREATE OR REPLACE FUNCTION create_cursor(q text) RETURNS refcursor AS $$ +DECLARE + curs refcursor; +BEGIN + OPEN curs FOR EXECUTE q; + RETURN curs; +END; +$$ LANGUAGE PLPGSQL; + +CREATE OR REPLACE FUNCTION partition_queries( + IN _where text DEFAULT 'TRUE', + IN _orderby text DEFAULT 'datetime DESC, id DESC' +) RETURNS SETOF text AS $$ +DECLARE + partition_query text; + query text; + p record; + cursors refcursor; +BEGIN +IF _orderby ILIKE 'datetime d%' THEN + partition_query := format($q$ + SELECT partition, tstzrange + FROM items_partitions + ORDER BY tstzrange DESC; + $q$); +ELSIF _orderby ILIKE 'datetime a%' THEN + partition_query := format($q$ + SELECT partition, tstzrange + FROM items_partitions + ORDER BY tstzrange ASC + ; + $q$); +ELSE + query := format($q$ + SELECT * FROM items + WHERE %s + ORDER BY %s + $q$, _where, _orderby + ); + + RETURN NEXT query; + RETURN; +END IF; +FOR p IN + EXECUTE partition_query +LOOP + query := format($q$ + SELECT * FROM items + WHERE datetime >= %L AND datetime < %L AND %s + ORDER BY %s + $q$, lower(p.tstzrange), upper(p.tstzrange), _where, _orderby + ); + RETURN NEXT query; +END LOOP; +RETURN; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION partition_cursor( + IN _where text DEFAULT 'TRUE', + IN _orderby text DEFAULT 'datetime DESC, id DESC' +) RETURNS SETOF refcursor AS $$ +DECLARE + partition_query text; + query text; + p record; + cursors refcursor; +BEGIN +FOR query IN SELECT * FROM partion_queries(_where, _orderby) LOOP + RETURN NEXT create_cursor(query); +END LOOP; +RETURN; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION partition_count( + IN _where text DEFAULT 'TRUE' +) RETURNS bigint AS $$ +DECLARE + partition_query text; + query text; + p record; + subtotal bigint; + total bigint := 0; +BEGIN +partition_query := format($q$ + SELECT partition, tstzrange + FROM items_partitions + ORDER BY tstzrange DESC; +$q$); +RAISE NOTICE 'Partition Query: %', partition_query; +FOR p IN + EXECUTE partition_query +LOOP + query := format($q$ + SELECT count(*) FROM items + WHERE datetime BETWEEN %L AND %L AND %s + $q$, lower(p.tstzrange), upper(p.tstzrange), _where + ); + RAISE NOTICE 'Query %', query; + RAISE NOTICE 'Partition %, Count %, Total %',p.partition, subtotal, total; + EXECUTE query INTO subtotal; + total := subtotal + total; +END LOOP; +RETURN total; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; +/* looks for a geometry in a stac item first from geometry and falling back to bbox */ +CREATE OR REPLACE FUNCTION stac_geom(value jsonb) RETURNS geometry AS $$ +SELECT + CASE + WHEN value->>'geometry' IS NOT NULL THEN + ST_GeomFromGeoJSON(value->>'geometry') + WHEN value->>'bbox' IS NOT NULL THEN + ST_MakeEnvelope( + (value->'bbox'->>0)::float, + (value->'bbox'->>1)::float, + (value->'bbox'->>2)::float, + (value->'bbox'->>3)::float, + 4326 + ) + ELSE NULL + END as geometry +; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION stac_datetime(value jsonb) RETURNS timestamptz AS $$ +SELECT COALESCE( + (value->'properties'->>'datetime')::timestamptz, + (value->'properties'->>'start_datetime')::timestamptz +); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET TIMEZONE='UTC'; + +CREATE OR REPLACE FUNCTION stac_end_datetime(value jsonb) RETURNS timestamptz AS $$ +SELECT COALESCE( + (value->'properties'->>'datetime')::timestamptz, + (value->'properties'->>'end_datetime')::timestamptz +); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET TIMEZONE='UTC'; + + +CREATE OR REPLACE FUNCTION stac_daterange(value jsonb) RETURNS tstzrange AS $$ +SELECT tstzrange(stac_datetime(value),stac_end_datetime(value)); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET TIMEZONE='UTC'; +SET SEARCH_PATH TO pgstac, public; + +CREATE TABLE IF NOT EXISTS collections ( + id VARCHAR GENERATED ALWAYS AS (content->>'id') STORED PRIMARY KEY, + content JSONB +); + +CREATE OR REPLACE FUNCTION create_collection(data jsonb) RETURNS VOID AS $$ + INSERT INTO collections (content) + VALUES (data) + ; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION update_collection(data jsonb) RETURNS VOID AS $$ +DECLARE +out collections%ROWTYPE; +BEGIN + UPDATE collections SET content=data WHERE id = data->>'id' RETURNING * INTO STRICT out; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION upsert_collection(data jsonb) RETURNS VOID AS $$ + INSERT INTO collections (content) + VALUES (data) + ON CONFLICT (id) DO + UPDATE + SET content=EXCLUDED.content + ; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION delete_collection(_id text) RETURNS VOID AS $$ +DECLARE +out collections%ROWTYPE; +BEGIN + DELETE FROM collections WHERE id = _id RETURNING * INTO STRICT out; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + + +CREATE OR REPLACE FUNCTION get_collection(id text) RETURNS jsonb AS $$ +SELECT content FROM collections +WHERE id=$1 +; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION all_collections() RETURNS jsonb AS $$ +SELECT jsonb_agg(content) FROM collections; +; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac, public; +SET SEARCH_PATH TO pgstac, public; + +CREATE TABLE items ( + id text NOT NULL, + geometry geometry NOT NULL, + collection_id text NOT NULL, + datetime timestamptz NOT NULL, + end_datetime timestamptz NOT NULL, + properties jsonb NOT NULL, + content JSONB NOT NULL +) +PARTITION BY RANGE (datetime) +; + +CREATE OR REPLACE FUNCTION properties_idx (IN content jsonb) RETURNS jsonb AS $$ + with recursive extract_all as + ( + select + ARRAY[key]::text[] as path, + ARRAY[key]::text[] as fullpath, + value + FROM jsonb_each(content->'properties') + union all + select + CASE WHEN obj_key IS NOT NULL THEN path || obj_key ELSE path END, + path || coalesce(obj_key, (arr_key- 1)::text), + coalesce(obj_value, arr_value) + from extract_all + left join lateral + jsonb_each(case jsonb_typeof(value) when 'object' then value end) + as o(obj_key, obj_value) + on jsonb_typeof(value) = 'object' + left join lateral + jsonb_array_elements(case jsonb_typeof(value) when 'array' then value end) + with ordinality as a(arr_value, arr_key) + on jsonb_typeof(value) = 'array' + where obj_key is not null or arr_key is not null + ) + , paths AS ( + select + array_to_string(path, '.') as path, + value + FROM extract_all + WHERE + jsonb_typeof(value) NOT IN ('array','object') + ), grouped AS ( + SELECT path, jsonb_agg(distinct value) vals FROM paths group by path + ) SELECT coalesce(jsonb_object_agg(path, CASE WHEN jsonb_array_length(vals)=1 THEN vals->0 ELSE vals END) - '{datetime}'::text[], '{}'::jsonb) FROM grouped + ; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET JIT TO OFF; + +CREATE INDEX "datetime_idx" ON items (datetime); +CREATE INDEX "end_datetime_idx" ON items (end_datetime); +CREATE INDEX "properties_idx" ON items USING GIN (properties jsonb_path_ops); +CREATE INDEX "collection_idx" ON items (collection_id); +CREATE INDEX "geometry_idx" ON items USING GIST (geometry); +CREATE UNIQUE INDEX "items_id_datetime_idx" ON items (datetime, id); + +ALTER TABLE items ADD CONSTRAINT items_collections_fk FOREIGN KEY (collection_id) REFERENCES collections(id) ON DELETE CASCADE DEFERRABLE; + +CREATE OR REPLACE FUNCTION analyze_empty_partitions() RETURNS VOID AS $$ +DECLARE + p text; +BEGIN + FOR p IN SELECT partition FROM all_items_partitions WHERE est_cnt = 0 LOOP + EXECUTE format('ANALYZE %I;', p); + END LOOP; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE OR REPLACE FUNCTION items_partition_name(timestamptz) RETURNS text AS $$ + SELECT to_char($1, '"items_p"IYYY"w"IW'); +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION items_partition_exists(text) RETURNS boolean AS $$ + SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class WHERE relname=$1); +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION items_partition_exists(timestamptz) RETURNS boolean AS $$ + SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class WHERE relname=items_partition_name($1)); +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION items_partition_create_worker(partition text, partition_start timestamptz, partition_end timestamptz) RETURNS VOID AS $$ +DECLARE + err_context text; +BEGIN + EXECUTE format( + $f$ + CREATE TABLE IF NOT EXISTS %1$I PARTITION OF items + FOR VALUES FROM (%2$L) TO (%3$L); + CREATE UNIQUE INDEX IF NOT EXISTS %4$I ON %1$I (id); + $f$, + partition, + partition_start, + partition_end, + concat(partition, '_id_pk') + ); +EXCEPTION + WHEN duplicate_table THEN + RAISE NOTICE 'Partition % already exists.', partition; + WHEN others THEN + GET STACKED DIAGNOSTICS err_context = PG_EXCEPTION_CONTEXT; + RAISE INFO 'Error Name:%',SQLERRM; + RAISE INFO 'Error State:%', SQLSTATE; + RAISE INFO 'Error Context:%', err_context; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH to pgstac, public; + +CREATE OR REPLACE FUNCTION items_partition_create(ts timestamptz) RETURNS text AS $$ +DECLARE + partition text := items_partition_name(ts); + partition_start timestamptz; + partition_end timestamptz; +BEGIN + IF items_partition_exists(partition) THEN + RETURN partition; + END IF; + partition_start := date_trunc('week', ts); + partition_end := partition_start + '1 week'::interval; + PERFORM items_partition_create_worker(partition, partition_start, partition_end); + RAISE NOTICE 'partition: %', partition; + RETURN partition; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION items_partition_create(st timestamptz, et timestamptz) RETURNS SETOF text AS $$ +WITH t AS ( + SELECT + generate_series( + date_trunc('week',st), + date_trunc('week', et), + '1 week'::interval + ) w +) +SELECT items_partition_create(w) FROM t; +$$ LANGUAGE SQL; + + +CREATE UNLOGGED TABLE items_staging ( + content JSONB NOT NULL +); + +CREATE OR REPLACE FUNCTION items_staging_insert_triggerfunc() RETURNS TRIGGER AS $$ +DECLARE + mindate timestamptz; + maxdate timestamptz; + partition text; +BEGIN + SELECT min(stac_datetime(content)), max(stac_datetime(content)) INTO mindate, maxdate FROM newdata; + PERFORM items_partition_create(mindate, maxdate); + INSERT INTO items (id, geometry, collection_id, datetime, end_datetime, properties, content) + SELECT + content->>'id', + stac_geom(content), + content->>'collection', + stac_datetime(content), + stac_end_datetime(content), + properties_idx(content), + content + FROM newdata + ; + DELETE FROM items_staging; + PERFORM analyze_empty_partitions(); + RETURN NULL; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE TRIGGER items_staging_insert_trigger AFTER INSERT ON items_staging REFERENCING NEW TABLE AS newdata + FOR EACH STATEMENT EXECUTE PROCEDURE items_staging_insert_triggerfunc(); + + +CREATE UNLOGGED TABLE items_staging_ignore ( + content JSONB NOT NULL +); + +CREATE OR REPLACE FUNCTION items_staging_ignore_insert_triggerfunc() RETURNS TRIGGER AS $$ +DECLARE + mindate timestamptz; + maxdate timestamptz; + partition text; +BEGIN + SELECT min(stac_datetime(content)), max(stac_datetime(content)) INTO mindate, maxdate FROM newdata; + PERFORM items_partition_create(mindate, maxdate); + INSERT INTO items (id, geometry, collection_id, datetime, end_datetime, properties, content) + SELECT + content->>'id', + stac_geom(content), + content->>'collection', + stac_datetime(content), + stac_end_datetime(content), + properties_idx(content), + content + FROM newdata + ON CONFLICT DO NOTHING + ; + DELETE FROM items_staging_ignore; + PERFORM analyze_empty_partitions(); + RETURN NULL; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE TRIGGER items_staging_ignore_insert_trigger AFTER INSERT ON items_staging_ignore REFERENCING NEW TABLE AS newdata + FOR EACH STATEMENT EXECUTE PROCEDURE items_staging_ignore_insert_triggerfunc(); + +CREATE UNLOGGED TABLE items_staging_upsert ( + content JSONB NOT NULL +); + +CREATE OR REPLACE FUNCTION items_staging_upsert_insert_triggerfunc() RETURNS TRIGGER AS $$ +DECLARE + mindate timestamptz; + maxdate timestamptz; + partition text; +BEGIN + SELECT min(stac_datetime(content)), max(stac_datetime(content)) INTO mindate, maxdate FROM newdata; + PERFORM items_partition_create(mindate, maxdate); + INSERT INTO items (id, geometry, collection_id, datetime, end_datetime, properties, content) + SELECT + content->>'id', + stac_geom(content), + content->>'collection', + stac_datetime(content), + stac_end_datetime(content), + properties_idx(content), + content + FROM newdata + ON CONFLICT (datetime, id) DO UPDATE SET + content = EXCLUDED.content + WHERE items.content IS DISTINCT FROM EXCLUDED.content + ; + DELETE FROM items_staging_upsert; + PERFORM analyze_empty_partitions(); + RETURN NULL; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE TRIGGER items_staging_upsert_insert_trigger AFTER INSERT ON items_staging_upsert REFERENCING NEW TABLE AS newdata + FOR EACH STATEMENT EXECUTE PROCEDURE items_staging_upsert_insert_triggerfunc(); + +CREATE OR REPLACE FUNCTION items_update_triggerfunc() RETURNS TRIGGER AS $$ +DECLARE +BEGIN + NEW.id := NEW.content->>'id'; + NEW.datetime := stac_datetime(NEW.content); + NEW.end_datetime := stac_end_datetime(NEW.content); + NEW.collection_id := NEW.content->>'collection'; + NEW.geometry := stac_geom(NEW.content); + NEW.properties := properties_idx(NEW.content); + IF TG_OP = 'UPDATE' AND NEW IS NOT DISTINCT FROM OLD THEN + RETURN NULL; + END IF; + RETURN NEW; +END; +$$ LANGUAGE PLPGSQL; + +CREATE TRIGGER items_update_trigger BEFORE UPDATE ON items + FOR EACH ROW EXECUTE PROCEDURE items_update_triggerfunc(); + +/* +View to get a table of available items partitions +with date ranges +*/ +CREATE VIEW all_items_partitions AS +WITH base AS +(SELECT + c.oid::pg_catalog.regclass::text as partition, + pg_catalog.pg_get_expr(c.relpartbound, c.oid) as _constraint, + regexp_matches( + pg_catalog.pg_get_expr(c.relpartbound, c.oid), + E'\\(''\([0-9 :+-]*\)''\\).*\\(''\([0-9 :+-]*\)''\\)' + ) as t, + reltuples::bigint as est_cnt +FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i +WHERE c.oid = i.inhrelid AND i.inhparent = 'items'::regclass) +SELECT partition, tstzrange( + t[1]::timestamptz, + t[2]::timestamptz +), est_cnt +FROM base +ORDER BY 2 desc; + +CREATE OR REPLACE VIEW items_partitions AS +SELECT * FROM all_items_partitions WHERE est_cnt>0; + +CREATE OR REPLACE FUNCTION get_item(_id text) RETURNS jsonb AS $$ + SELECT content FROM items WHERE id=_id; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION delete_item(_id text) RETURNS VOID AS $$ +DECLARE +out items%ROWTYPE; +BEGIN + DELETE FROM items WHERE id = _id RETURNING * INTO STRICT out; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION create_item(data jsonb) RETURNS VOID AS $$ + INSERT INTO items_staging (content) VALUES (data); +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac,public; + + +CREATE OR REPLACE FUNCTION update_item(data jsonb) RETURNS VOID AS $$ +DECLARE + out items%ROWTYPE; +BEGIN + UPDATE items SET content=data WHERE id = data->>'id' RETURNING * INTO STRICT out; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION upsert_item(data jsonb) RETURNS VOID AS $$ + INSERT INTO items_staging_upsert (content) VALUES (data); +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac,public; + + +CREATE OR REPLACE FUNCTION collection_bbox(id text) RETURNS jsonb AS $$ +SELECT (replace(replace(replace(st_extent(geometry)::text,'BOX(','[['),')',']]'),' ',','))::jsonb +FROM items WHERE collection_id=$1; +; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION collection_temporal_extent(id text) RETURNS jsonb AS $$ +SELECT to_jsonb(array[array[min(datetime)::text, max(datetime)::text]]) +FROM items WHERE collection_id=$1; +; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION update_collection_extents() RETURNS VOID AS $$ +UPDATE collections SET + content = content || + jsonb_build_object( + 'extent', jsonb_build_object( + 'spatial', jsonb_build_object( + 'bbox', collection_bbox(collections.id) + ), + 'temporal', jsonb_build_object( + 'interval', collection_temporal_extent(collections.id) + ) + ) + ) +; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac, public; + +SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION items_path( + IN dotpath text, + OUT field text, + OUT path text, + OUT path_txt text, + OUT jsonpath text, + OUT eq text +) RETURNS RECORD AS $$ +DECLARE +path_elements text[]; +last_element text; +BEGIN +dotpath := replace(trim(dotpath), 'properties.', ''); + +IF dotpath = '' THEN + RETURN; +END IF; + +path_elements := string_to_array(dotpath, '.'); +jsonpath := NULL; + +IF path_elements[1] IN ('id','geometry','datetime') THEN + field := path_elements[1]; + path_elements := path_elements[2:]; +ELSIF path_elements[1] = 'collection' THEN + field := 'collection_id'; + path_elements := path_elements[2:]; +ELSIF path_elements[1] IN ('links', 'assets', 'stac_version', 'stac_extensions') THEN + field := 'content'; +ELSE + field := 'content'; + path_elements := '{properties}'::text[] || path_elements; +END IF; +IF cardinality(path_elements)<1 THEN + path := field; + path_txt := field; + jsonpath := '$'; + eq := NULL; -- format($F$ %s = %%s $F$, field); + RETURN; +END IF; + + +last_element := path_elements[cardinality(path_elements)]; +path_elements := path_elements[1:cardinality(path_elements)-1]; +jsonpath := concat(array_to_string('{$}'::text[] || array_map_ident(path_elements), '.'), '.', quote_ident(last_element)); +path_elements := array_map_literal(path_elements); +path := format($F$ properties->%s $F$, quote_literal(dotpath)); +path_txt := format($F$ properties->>%s $F$, quote_literal(dotpath)); +eq := format($F$ properties @? '$.%s[*] ? (@ == %%s) '$F$, quote_ident(dotpath)); + +RAISE NOTICE 'ITEMS PATH -- % % % % %', field, path, path_txt, jsonpath, eq; +RETURN; +END; +$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION parse_dtrange(IN _indate jsonb, OUT _tstzrange tstzrange) AS $$ +WITH t AS ( + SELECT CASE + WHEN jsonb_typeof(_indate) = 'array' THEN + textarr(_indate) + ELSE + regexp_split_to_array( + btrim(_indate::text,'"'), + '/' + ) + END AS arr +) +, t1 AS ( + SELECT + CASE + WHEN array_upper(arr,1) = 1 OR arr[1] = '..' OR arr[1] IS NULL THEN '-infinity'::timestamptz + ELSE arr[1]::timestamptz + END AS st, + CASE + WHEN array_upper(arr,1) = 1 THEN arr[1]::timestamptz + WHEN arr[2] = '..' OR arr[2] IS NULL THEN 'infinity'::timestamptz + ELSE arr[2]::timestamptz + END AS et + FROM t +) +SELECT + tstzrange(st,et) +FROM t1; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION bbox_geom(_bbox jsonb) RETURNS geometry AS $$ +SELECT CASE jsonb_array_length(_bbox) + WHEN 4 THEN + ST_SetSRID(ST_MakeEnvelope( + (_bbox->>0)::float, + (_bbox->>1)::float, + (_bbox->>2)::float, + (_bbox->>3)::float + ),4326) + WHEN 6 THEN + ST_SetSRID(ST_3DMakeBox( + ST_MakePoint( + (_bbox->>0)::float, + (_bbox->>1)::float, + (_bbox->>2)::float + ), + ST_MakePoint( + (_bbox->>3)::float, + (_bbox->>4)::float, + (_bbox->>5)::float + ) + ),4326) + ELSE null END; +; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION cql_and_append(existing jsonb, newfilters jsonb) RETURNS jsonb AS $$ +SELECT CASE WHEN existing ? 'filter' AND newfilters IS NOT NULL THEN + jsonb_build_object( + 'and', + jsonb_build_array( + existing->'filter', + newfilters + ) + ) +ELSE + newfilters +END; +$$ LANGUAGE SQL; + + +-- ADDs base filters (ids, collections, datetime, bbox, intersects) that are +-- added outside of the filter/query in the stac request +CREATE OR REPLACE FUNCTION add_filters_to_cql(j jsonb) RETURNS jsonb AS $$ +DECLARE +newprop jsonb; +newprops jsonb := '[]'::jsonb; +BEGIN +IF j ? 'id' THEN + newprop := jsonb_build_object( + 'in', + jsonb_build_array( + '{"property":"id"}'::jsonb, + j->'id' + ) + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; +IF j ? 'collection' THEN + newprop := jsonb_build_object( + 'in', + jsonb_build_array( + '{"property":"collection"}'::jsonb, + j->'collection' + ) + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; + +IF j ? 'datetime' THEN + newprop := format( + '{"anyinteracts":[{"property":"datetime"}, %s]}', + j->'datetime' + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; + +IF j ? 'bbox' THEN + newprop := format( + '{"intersects":[{"property":"geometry"}, %s]}', + j->'bbox' + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; + +IF j ? 'intersects' THEN + newprop := format( + '{"intersects":[{"property":"geometry"}, %s]}', + j->'intersects' + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; + +RAISE NOTICE 'newprops: %', newprops; + +IF newprops IS NOT NULL AND jsonb_array_length(newprops) > 0 THEN + return jsonb_set( + j, + '{filter}', + cql_and_append(j, jsonb_build_object('and', newprops)) + ) - '{id,collection,datetime,bbox,intersects}'::text[]; +END IF; + +return j; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE OR REPLACE FUNCTION query_to_cqlfilter(j jsonb) RETURNS jsonb AS $$ +-- Translates anything passed in through the deprecated "query" into equivalent CQL +WITH t AS ( + SELECT key as property, value as ops + FROM jsonb_each(j->'query') +), t2 AS ( + SELECT property, (jsonb_each(ops)).* + FROM t WHERE jsonb_typeof(ops) = 'object' + UNION ALL + SELECT property, 'eq', ops + FROM t WHERE jsonb_typeof(ops) != 'object' +), t3 AS ( +SELECT + jsonb_strip_nulls(jsonb_build_object( + 'and', + jsonb_agg( + jsonb_build_object( + key, + jsonb_build_array( + jsonb_build_object('property',property), + value + ) + ) + ) + )) as qcql FROM t2 +) +SELECT + CASE WHEN qcql IS NOT NULL THEN + jsonb_set(j, '{filter}', cql_and_append(j, qcql)) - 'query' + ELSE j + END +FROM t3 +; +$$ LANGUAGE SQL; + + + +CREATE OR REPLACE FUNCTION temporal_op_query(op text, args jsonb) RETURNS text AS $$ +DECLARE +ll text := 'datetime'; +lh text := 'end_datetime'; +rrange tstzrange; +rl text; +rh text; +outq text; +BEGIN +rrange := parse_dtrange(args->1); +RAISE NOTICE 'Constructing temporal query OP: %, ARGS: %, RRANGE: %', op, args, rrange; +op := lower(op); +rl := format('%L::timestamptz', lower(rrange)); +rh := format('%L::timestamptz', upper(rrange)); +outq := CASE op + WHEN 't_before' THEN 'lh < rl' + WHEN 't_after' THEN 'll > rh' + WHEN 't_meets' THEN 'lh = rl' + WHEN 't_metby' THEN 'll = rh' + WHEN 't_overlaps' THEN 'll < rl AND rl < lh < rh' + WHEN 't_overlappedby' THEN 'rl < ll < rh AND lh > rh' + WHEN 't_starts' THEN 'll = rl AND lh < rh' + WHEN 't_startedby' THEN 'll = rl AND lh > rh' + WHEN 't_during' THEN 'll > rl AND lh < rh' + WHEN 't_contains' THEN 'll < rl AND lh > rh' + WHEN 't_finishes' THEN 'll > rl AND lh = rh' + WHEN 't_finishedby' THEN 'll < rl AND lh = rh' + WHEN 't_equals' THEN 'll = rl AND lh = rh' + WHEN 't_disjoint' THEN 'NOT (ll <= rh AND lh >= rl)' + WHEN 't_intersects' THEN 'll <= rh AND lh >= rl' + WHEN 'anyinteracts' THEN 'll <= rh AND lh >= rl' +END; +outq := regexp_replace(outq, '\mll\M', ll); +outq := regexp_replace(outq, '\mlh\M', lh); +outq := regexp_replace(outq, '\mrl\M', rl); +outq := regexp_replace(outq, '\mrh\M', rh); +outq := format('(%s)', outq); +RETURN outq; +END; +$$ LANGUAGE PLPGSQL; + +CREATE OR REPLACE FUNCTION spatial_op_query(op text, args jsonb) RETURNS text AS $$ +DECLARE +geom text; +j jsonb := args->1; +BEGIN +op := lower(op); +RAISE NOTICE 'Constructing spatial query OP: %, ARGS: %', op, args; +IF op NOT IN ('s_equals','s_disjoint','s_touches','s_within','s_overlaps','s_crosses','s_intersects','intersects','s_contains') THEN + RAISE EXCEPTION 'Spatial Operator % Not Supported', op; +END IF; +op := regexp_replace(op, '^s_', 'st_'); +IF op = 'intersects' THEN + op := 'st_intersects'; +END IF; +-- Convert geometry to WKB string +IF j ? 'type' AND j ? 'coordinates' THEN + geom := st_geomfromgeojson(j)::text; +ELSIF jsonb_typeof(j) = 'array' THEN + geom := bbox_geom(j)::text; +END IF; + +RETURN format('%s(geometry, %L::geometry)', op, geom); +END; +$$ LANGUAGE PLPGSQL; + + +/* cql_query_op -- Parses a CQL query operation, recursing when necessary + IN jsonb -- a subelement from a valid stac query + IN text -- the operator being used on elements passed in + RETURNS a SQL fragment to be used in a WHERE clause +*/ +CREATE OR REPLACE FUNCTION cql_query_op(j jsonb, _op text DEFAULT NULL) RETURNS text AS $$ +DECLARE +jtype text := jsonb_typeof(j); +op text := lower(_op); +ops jsonb := + '{ + "eq": "%s = %s", + "lt": "%s < %s", + "lte": "%s <= %s", + "gt": "%s > %s", + "gte": "%s >= %s", + "like": "%s LIKE %s", + "+": "%s + %s", + "-": "%s - %s", + "*": "%s * %s", + "/": "%s / %s", + "in": "%s = ANY (%s)", + "not": "NOT (%s)", + "between": "%s BETWEEN %s AND %s", + "lower":"lower(%s)" + }'::jsonb; +ret text; +args text[] := NULL; + +BEGIN +RAISE NOTICE 'j: %, op: %, jtype: %', j, op, jtype; + +-- Set Lower Case on Both Arguments When Case Insensitive Flag Set +IF op in ('eq','lt','lte','gt','gte','like') AND jsonb_typeof(j->2) = 'boolean' THEN + IF (j->>2)::boolean THEN + RETURN format(concat('(',ops->>op,')'), cql_query_op(jsonb_build_array(j->0), 'lower'), cql_query_op(jsonb_build_array(j->1), 'lower')); + END IF; +END IF; + +-- Special Case when comparing a property in a jsonb field to a string or number using eq +-- Allows to leverage GIN index on jsonb fields +IF op = 'eq' THEN + IF j->0 ? 'property' + AND jsonb_typeof(j->1) IN ('number','string') + AND (items_path(j->0->>'property')).eq IS NOT NULL + THEN + RETURN format((items_path(j->0->>'property')).eq, j->1); + END IF; +END IF; + +IF op ilike 't_%' or op = 'anyinteracts' THEN + RETURN temporal_op_query(op, j); +END IF; + +IF op ilike 's_%' or op = 'intersects' THEN + RETURN spatial_op_query(op, j); +END IF; + + +IF jtype = 'object' THEN + RAISE NOTICE 'parsing object'; + IF j ? 'property' THEN + -- Convert the property to be used as an identifier + return (items_path(j->>'property')).path_txt; + ELSIF _op IS NULL THEN + -- Iterate to convert elements in an object where the operator has not been set + -- Combining with AND + SELECT + array_to_string(array_agg(cql_query_op(e.value, e.key)), ' AND ') + INTO ret + FROM jsonb_each(j) e; + RETURN ret; + END IF; +END IF; + +IF jtype = 'string' THEN + RETURN quote_literal(j->>0); +END IF; + +IF jtype ='number' THEN + RETURN (j->>0)::numeric; +END IF; + +IF jtype = 'array' AND op IS NULL THEN + RAISE NOTICE 'Parsing array into array arg. j: %', j; + SELECT format($f$ '{%s}'::text[] $f$, string_agg(e,',')) INTO ret FROM jsonb_array_elements_text(j) e; + RETURN ret; +END IF; + + +-- If the type of the passed json is an array +-- Calculate the arguments that will be passed to functions/operators +IF jtype = 'array' THEN + RAISE NOTICE 'Parsing array into args. j: %', j; + -- If any argument is numeric, cast any text arguments to numeric + IF j @? '$[*] ? (@.type() == "number")' THEN + SELECT INTO args + array_agg(concat('(',cql_query_op(e),')::numeric')) + FROM jsonb_array_elements(j) e; + ELSE + SELECT INTO args + array_agg(cql_query_op(e)) + FROM jsonb_array_elements(j) e; + END IF; + --RETURN args; +END IF; +RAISE NOTICE 'ARGS after array cleaning: %', args; + +IF op IS NULL THEN + RETURN args::text[]; +END IF; + +IF args IS NULL OR cardinality(args) < 1 THEN + RAISE NOTICE 'No Args'; + RETURN ''; +END IF; + +IF op IN ('and','or') THEN + SELECT + CONCAT( + '(', + array_to_string(args, UPPER(CONCAT(' ',op,' '))), + ')' + ) INTO ret + FROM jsonb_array_elements(j) e; + RETURN ret; +END IF; + +-- If the op is in the ops json then run using the template in the json +IF ops ? op THEN + RAISE NOTICE 'ARGS: % MAPPED: %',args, array_map_literal(args); + + RETURN format(concat('(',ops->>op,')'), VARIADIC args); +END IF; + +RETURN j->>0; + +END; +$$ LANGUAGE PLPGSQL; + + + + +CREATE OR REPLACE FUNCTION cql_to_where(_search jsonb = '{}'::jsonb) RETURNS text AS $$ +DECLARE +search jsonb := _search; +_where text; +BEGIN +RAISE NOTICE 'SEARCH CQL 1: %', search; + +-- Convert any old style stac query to cql +search := query_to_cqlfilter(search); + +RAISE NOTICE 'SEARCH CQL 2: %', search; + +-- Convert item,collection,datetime,bbox,intersects to cql +search := add_filters_to_cql(search); + +RAISE NOTICE 'SEARCH CQL Final: %', search; +_where := cql_query_op(search->'filter'); + +IF trim(_where) = '' THEN + _where := NULL; +END IF; +_where := coalesce(_where, ' TRUE '); +RETURN _where; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE OR REPLACE FUNCTION parse_sort_dir(_dir text, reverse boolean default false) RETURNS text AS $$ +WITH t AS ( + SELECT COALESCE(upper(_dir), 'ASC') as d +) SELECT + CASE + WHEN NOT reverse THEN d + WHEN d = 'ASC' THEN 'DESC' + WHEN d = 'DESC' THEN 'ASC' + END +FROM t; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sort_dir_to_op(_dir text, prev boolean default false) RETURNS text AS $$ +WITH t AS ( + SELECT COALESCE(upper(_dir), 'ASC') as d +) SELECT + CASE + WHEN d = 'ASC' AND prev THEN '<=' + WHEN d = 'DESC' AND prev THEN '>=' + WHEN d = 'ASC' THEN '>=' + WHEN d = 'DESC' THEN '<=' + END +FROM t; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sort_sqlorderby( + _search jsonb DEFAULT NULL, + reverse boolean DEFAULT FALSE +) RETURNS text AS $$ +WITH sorts AS ( + SELECT + (items_path(value->>'field')).path as key, + parse_sort_dir(value->>'direction', reverse) as dir + FROM jsonb_array_elements( + '[]'::jsonb + || + coalesce(_search->'sort','[{"field":"datetime", "direction":"desc"}]') + || + '[{"field":"id","direction":"desc"}]'::jsonb + ) +) +SELECT array_to_string( + array_agg(concat(key, ' ', dir)), + ', ' +) FROM sorts; +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION get_sort_dir(sort_item jsonb) RETURNS text AS $$ +SELECT CASE WHEN sort_item->>'direction' ILIKE 'desc%' THEN 'DESC' ELSE 'ASC' END; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION get_token_filter(_search jsonb = '{}'::jsonb, token_rec jsonb DEFAULT NULL) RETURNS text AS $$ +DECLARE +token_id text; +filters text[] := '{}'::text[]; +prev boolean := TRUE; +field text; +dir text; +sort record; +orfilters text[] := '{}'::text[]; +andfilters text[] := '{}'::text[]; +output text; +token_where text; +BEGIN +-- If no token provided return NULL +IF token_rec IS NULL THEN + IF NOT (_search ? 'token' AND + ( + (_search->>'token' ILIKE 'prev:%') + OR + (_search->>'token' ILIKE 'next:%') + ) + ) THEN + RETURN NULL; + END IF; + prev := (_search->>'token' ILIKE 'prev:%'); + token_id := substr(_search->>'token', 6); + SELECT to_jsonb(items) INTO token_rec FROM items WHERE id=token_id; +END IF; +RAISE NOTICE 'TOKEN ID: %', token_rec->'id'; + +CREATE TEMP TABLE sorts ( + _row int GENERATED ALWAYS AS IDENTITY NOT NULL, + _field text PRIMARY KEY, + _dir text NOT NULL, + _val text +) ON COMMIT DROP; + +-- Make sure we only have distinct columns to sort with taking the first one we get +INSERT INTO sorts (_field, _dir) + SELECT + (items_path(value->>'field')).path, + get_sort_dir(value) + FROM + jsonb_array_elements(coalesce(_search->'sort','[{"field":"datetime","direction":"desc"}]')) +ON CONFLICT DO NOTHING +; + +-- Get the first sort direction provided. As the id is a primary key, if there are any +-- sorts after id they won't do anything, so make sure that id is the last sort item. +SELECT _dir INTO dir FROM sorts ORDER BY _row ASC LIMIT 1; +IF EXISTS (SELECT 1 FROM sorts WHERE _field = 'id') THEN + DELETE FROM sorts WHERE _row > (SELECT _row FROM sorts WHERE _field = 'id'); +ELSE + INSERT INTO sorts (_field, _dir) VALUES ('id', dir); +END IF; + +-- Add value from looked up item to the sorts table +UPDATE sorts SET _val=quote_literal(token_rec->>_field); + +-- Check if all sorts are the same direction and use row comparison +-- to filter +IF (SELECT count(DISTINCT _dir) FROM sorts) = 1 THEN + SELECT format( + '(%s) %s (%s)', + concat_ws(', ', VARIADIC array_agg(quote_ident(_field))), + CASE WHEN (prev AND dir = 'ASC') OR (NOT prev AND dir = 'DESC') THEN '<' ELSE '>' END, + concat_ws(', ', VARIADIC array_agg(_val)) + ) INTO output FROM sorts + WHERE token_rec ? _field + ; +ELSE + FOR sort IN SELECT * FROM sorts ORDER BY _row asc LOOP + RAISE NOTICE 'SORT: %', sort; + IF sort._row = 1 THEN + orfilters := orfilters || format('(%s %s %s)', + quote_ident(sort._field), + CASE WHEN (prev AND sort._dir = 'ASC') OR (NOT prev AND sort._dir = 'DESC') THEN '<' ELSE '>' END, + sort._val + ); + ELSE + orfilters := orfilters || format('(%s AND %s %s %s)', + array_to_string(andfilters, ' AND '), + quote_ident(sort._field), + CASE WHEN (prev AND sort._dir = 'ASC') OR (NOT prev AND sort._dir = 'DESC') THEN '<' ELSE '>' END, + sort._val + ); + + END IF; + andfilters := andfilters || format('%s = %s', + quote_ident(sort._field), + sort._val + ); + END LOOP; + output := array_to_string(orfilters, ' OR '); +END IF; +DROP TABLE IF EXISTS sorts; +token_where := concat('(',coalesce(output,'true'),')'); +IF trim(token_where) = '' THEN + token_where := NULL; +END IF; +RAISE NOTICE 'TOKEN_WHERE: |%|',token_where; +RETURN token_where; +END; +$$ LANGUAGE PLPGSQL; + +CREATE OR REPLACE FUNCTION search_tohash(jsonb) RETURNS jsonb AS $$ + SELECT $1 - '{token,limit,context,includes,excludes}'::text[]; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION search_hash(jsonb) RETURNS text AS $$ + SELECT md5(search_tohash($1)::text); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + + +CREATE TABLE IF NOT EXISTS searches( + hash text GENERATED ALWAYS AS (search_hash(search)) STORED PRIMARY KEY, + search jsonb NOT NULL, + _where text, + orderby text, + lastused timestamptz DEFAULT now(), + usecount bigint DEFAULT 0, + statslastupdated timestamptz, + estimated_count bigint, + total_count bigint +); + +CREATE OR REPLACE FUNCTION search_query(_search jsonb = '{}'::jsonb, updatestats boolean DEFAULT false) RETURNS searches AS $$ +DECLARE + search searches%ROWTYPE; +BEGIN +INSERT INTO searches (search) + VALUES (search_tohash(_search)) + ON CONFLICT DO NOTHING + RETURNING * INTO search; +IF search.hash IS NULL THEN + SELECT * INTO search FROM searches WHERE hash=search_hash(_search); +END IF; +IF search._where IS NULL THEN + search._where := cql_to_where(_search); +END IF; +IF search.orderby IS NULL THEN + search.orderby := sort_sqlorderby(_search); +END IF; + +IF search.statslastupdated IS NULL OR age(search.statslastupdated) > '1 day'::interval OR (_search ? 'context' AND search.total_count IS NULL) THEN + updatestats := TRUE; +END IF; + +IF updatestats THEN + -- Get Estimated Stats + RAISE NOTICE 'Getting stats for %', search._where; + search.estimated_count := estimated_count(search._where); + RAISE NOTICE 'Estimated Count: %', search.estimated_count; + + IF _search ? 'context' OR search.estimated_count < 10000 THEN + --search.total_count := partition_count(search._where); + EXECUTE format( + 'SELECT count(*) FROM items WHERE %s', + search._where + ) INTO search.total_count; + RAISE NOTICE 'Actual Count: %', search.total_count; + ELSE + search.total_count := NULL; + END IF; + search.statslastupdated := now(); +END IF; + +search.lastused := now(); +search.usecount := coalesce(search.usecount,0) + 1; +RAISE NOTICE 'SEARCH: %', search; +UPDATE searches SET + _where = search._where, + orderby = search.orderby, + lastused = search.lastused, + usecount = search.usecount, + statslastupdated = search.statslastupdated, + estimated_count = search.estimated_count, + total_count = search.total_count +WHERE hash = search.hash +; +RETURN search; + +END; +$$ LANGUAGE PLPGSQL; + + + +CREATE OR REPLACE FUNCTION search(_search jsonb = '{}'::jsonb) RETURNS jsonb AS $$ +DECLARE + searches searches%ROWTYPE; + _where text; + token_where text; + full_where text; + orderby text; + query text; + token_type text := substr(_search->>'token',1,4); + _limit int := coalesce((_search->>'limit')::int, 10); + curs refcursor; + cntr int := 0; + iter_record items%ROWTYPE; + first_record items%ROWTYPE; + last_record items%ROWTYPE; + out_records jsonb := '[]'::jsonb; + prev_query text; + next text; + prev_id text; + has_next boolean := false; + has_prev boolean := false; + prev text; + total_count bigint; + context jsonb; + collection jsonb; + includes text[]; + excludes text[]; + exit_flag boolean := FALSE; + batches int := 0; + timer timestamptz := clock_timestamp(); +BEGIN +searches := search_query(_search); +_where := searches._where; +orderby := searches.orderby; +total_count := coalesce(searches.total_count, searches.estimated_count); + + +IF token_type='prev' THEN + token_where := get_token_filter(_search, null::jsonb); + orderby := sort_sqlorderby(_search, TRUE); +END IF; +IF token_type='next' THEN + token_where := get_token_filter(_search, null::jsonb); +END IF; + +full_where := concat_ws(' AND ', _where, token_where); +RAISE NOTICE 'FULL QUERY % %', full_where, clock_timestamp()-timer; +timer := clock_timestamp(); + +FOR query IN SELECT partition_queries(full_where, orderby) LOOP + timer := clock_timestamp(); + query := format('%s LIMIT %L', query, _limit + 1); + RAISE NOTICE 'Partition Query: %', query; + batches := batches + 1; + curs = create_cursor(query); + LOOP + FETCH curs into iter_record; + EXIT WHEN NOT FOUND; + cntr := cntr + 1; + last_record := iter_record; + IF cntr = 1 THEN + first_record := last_record; + END IF; + IF cntr <= _limit THEN + out_records := out_records || last_record.content; + ELSIF cntr > _limit THEN + has_next := true; + exit_flag := true; + EXIT; + END IF; + END LOOP; + RAISE NOTICE 'Query took %', clock_timestamp()-timer; + timer := clock_timestamp(); + EXIT WHEN exit_flag; +END LOOP; +RAISE NOTICE 'Scanned through % partitions.', batches; + + +-- Flip things around if this was the result of a prev token query +IF token_type='prev' THEN + out_records := flip_jsonb_array(out_records); + first_record := last_record; +END IF; + +-- If this query has a token, see if there is data before the first record +IF _search ? 'token' THEN + prev_query := format( + 'SELECT 1 FROM items WHERE %s LIMIT 1', + concat_ws( + ' AND ', + _where, + trim(get_token_filter(_search, to_jsonb(first_record))) + ) + ); + RAISE NOTICE 'Query to get previous record: % --- %', prev_query, first_record; + EXECUTE prev_query INTO has_prev; + IF FOUND and has_prev IS NOT NULL THEN + RAISE NOTICE 'Query results from prev query: %', has_prev; + has_prev := TRUE; + END IF; +END IF; +has_prev := COALESCE(has_prev, FALSE); + +RAISE NOTICE 'token_type: %, has_next: %, has_prev: %', token_type, has_next, has_prev; +IF has_prev THEN + prev := out_records->0->>'id'; +END IF; +IF has_next OR token_type='prev' THEN + next := out_records->-1->>'id'; +END IF; + + + +-- include/exclude any fields following fields extension +IF _search ? 'fields' THEN + IF _search->'fields' ? 'exclude' THEN + excludes=textarr(_search->'fields'->'exclude'); + END IF; + IF _search->'fields' ? 'include' THEN + includes=textarr(_search->'fields'->'include'); + IF array_length(includes, 1)>0 AND NOT 'id' = ANY (includes) THEN + includes = includes || '{id}'; + END IF; + END IF; + SELECT jsonb_agg(filter_jsonb(row, includes, excludes)) INTO out_records FROM jsonb_array_elements(out_records) row; +END IF; + + +context := jsonb_strip_nulls(jsonb_build_object( + 'limit', _limit, + 'matched', total_count, + 'returned', coalesce(jsonb_array_length(out_records), 0) +)); + +collection := jsonb_build_object( + 'type', 'FeatureCollection', + 'features', out_records, + 'next', next, + 'prev', prev, + 'context', context +); + +RETURN collection; +END; +$$ LANGUAGE PLPGSQL SET jit TO off; +INSERT INTO pgstac.migrations (version) VALUES ('0.3.0'); diff --git a/pypgstac/pyproject.toml b/pypgstac/pyproject.toml index d896fc88..c622ca79 100644 --- a/pypgstac/pyproject.toml +++ b/pypgstac/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pypgstac" -version = "0.2.9" +version = "0.3.0" description = "" authors = ["David Bitner "] keywords = ["stac", "asyncpg"] @@ -17,6 +17,7 @@ smart-open = "^4.2.0" typer = "^0.3.2" asyncio = "^3.4.3" orjson = "^3.5.2" +python-dateutil = "^2.8.2" [tool.poetry.dev-dependencies] pytest = "^5.2" diff --git a/scripts/bin/migra_funcs b/scripts/bin/migra_funcs index d039f361..4c46cede 100644 --- a/scripts/bin/migra_funcs +++ b/scripts/bin/migra_funcs @@ -45,7 +45,7 @@ export -f pgwait function pgtap(){ TESTOUTPUT=$(psql -X -f $BASEDIR/test/pgtap.sql $1) echo "Checking if any tests are not ok on db $1" - if [ $(echo "$TESTOUTPUT" | grep '^not') ]; then + if [[ $(echo "$TESTOUTPUT" | grep '^not') == 0 ]]; then echo "PGTap tests failed." echo "$TESTOUTPUT" | grep '^not' exit 1 diff --git a/scripts/bin/testdb b/scripts/bin/testdb index dc143c6e..80a4c167 100755 --- a/scripts/bin/testdb +++ b/scripts/bin/testdb @@ -16,6 +16,27 @@ This scripts is meant to be run inside the dev container. " } +function usage() { + echo -n \ + "Usage: $(basename "$0") [--skipincremental] +Run database tests + +--skipincremental: Skip incremental migration checks. +" +} + +while [[ "$#" > 0 ]]; do case $1 in + --skipincremental) + SKIPINCREMENTAL=1 + shift + ;; + *) + usage "Unknown parameter passed: $1" + shift + shift + ;; + esac; done + function bail() { echo $1 exit 1 @@ -28,21 +49,28 @@ if [ "${BASH_SOURCE[0]}" = "${0}" ]; then create_migra_dbs trap drop_migra_dbs 0 2 3 15 - echo "Setting Temp DB 1 to initial version 0.1.9" - pypgstac migrate --dsn $FROMDBURL --toversion 0.1.9 - echo "Using incremental migrations to bring Temp DB 1 up to date" - pypgstac migrate --dsn $FROMDBURL - echo "Running PGTap Tests on Temp DB 1" - pgtap $FROMDBURL - echo "Using latest base migrations on Temp DB 2" pypgstac migrate --dsn $TODBURL echo "Running PGTap Tests on Temp DB 2" pgtap $TODBURL - echo "Using Migra to test for any differences between incrementally migrated DB and DB created with latest base migration." - diffs=$(migra --schema pgstac --unsafe $FROMDBURL $TODBURL || echo "") - [ $(echo $diff | wc -l) -gt 1 ] && { echo "DIFFERENCES FOUND: $diff"; exit 1; } + if [[ ! "${SKIPINCREMENTAL}" ]]; then + echo "-----Testing incremental migrations.-----" + echo "Setting Temp DB 1 to initial version 0.1.9" + pypgstac migrate --dsn $FROMDBURL --toversion 0.1.9 + echo "Using incremental migrations to bring Temp DB 1 up to date" + pypgstac migrate --dsn $FROMDBURL + echo "Running PGTap Tests on Temp DB 1" + pgtap $FROMDBURL + + echo "Using Migra to test for any differences between incrementally migrated DB and DB created with latest base migration." + diffs=$(migra --schema pgstac --unsafe $FROMDBURL $TODBURL || echo "") + [ $(echo $diffs | wc -l) -gt 1 ] && { echo "DIFFERENCES FOUND: \n$diffs"; exit 1; } + fi + + + + echo "No differences found." diff --git a/scripts/sql/resetdb.sql b/scripts/sql/resetdb.sql new file mode 100644 index 00000000..32509919 --- /dev/null +++ b/scripts/sql/resetdb.sql @@ -0,0 +1,6 @@ +BEGIN; + DROP SCHEMA IF EXISTS pgstac CASCADE; + \i pgstac.sql + \copy collections (content) FROM 'test/testdata/collections.ndjson' + \copy items_staging_ignore (content) FROM 'test/testdata/items.ndjson' +COMMIT; diff --git a/scripts/stageversion b/scripts/stageversion index ebd7cbf9..d421aeca 100755 --- a/scripts/stageversion +++ b/scripts/stageversion @@ -16,9 +16,6 @@ Create a new tag if [ "${BASH_SOURCE[0]}" = "${0}" ]; then echo "Updating Version..." - DIRTY=$(git status --porcelain=v1 2>/dev/null | wc -l) - [ $DIRTY -gt 0 ] && (echo "Git has dirty files, stash or commit before staging version."; exit 1) - docker-compose run --rm dev scripts/bin/stageversion $1 docker-compose exec -T database scripts/bin/stageversiondb fi diff --git a/scripts/test b/scripts/test index 15cbf97d..a5a77da0 100755 --- a/scripts/test +++ b/scripts/test @@ -8,12 +8,26 @@ fi function usage() { echo -n \ - "Usage: $(basename "$0") [--dev, --db, --migrations, --deploy] -Runs tests for the project. + "Usage: $(basename "$0") [--skipincremental] +Run database tests +--skipincremental: Skip incremental migration checks. " } +SKIPINCREMENTAL='' +while [[ "$#" > 0 ]]; do case $1 in + --skipincremental) + SKIPINCREMENTAL='--skipincremental' + shift + ;; + *) + usage "Unknown parameter passed: $1" + shift + shift + ;; + esac; done + if [ "${BASH_SOURCE[0]}" = "${0}" ]; then echo "Starting database..." scripts/server --detach; @@ -21,7 +35,7 @@ if [ "${BASH_SOURCE[0]}" = "${0}" ]; then echo "Running database tests..." docker-compose \ exec -T \ - database /opt/src/scripts/bin/testdb; + database /opt/src/scripts/bin/testdb $SKIPINCREMENTAL; echo "Running pypgstac tests..." docker-compose \ diff --git a/sql/001_core.sql b/sql/001_core.sql index 211cd371..87914805 100644 --- a/sql/001_core.sql +++ b/sql/001_core.sql @@ -1,9 +1,5 @@ CREATE EXTENSION IF NOT EXISTS postgis; -CREATE SCHEMA IF NOT EXISTS partman; -CREATE EXTENSION IF NOT EXISTS pg_partman SCHEMA partman; CREATE SCHEMA IF NOT EXISTS pgstac; - - SET SEARCH_PATH TO pgstac, public; CREATE TABLE migrations ( @@ -11,133 +7,17 @@ CREATE TABLE migrations ( datetime timestamptz DEFAULT now() NOT NULL ); -/* converts a jsonb text array to a pg text[] array */ -CREATE OR REPLACE FUNCTION textarr(_js jsonb) - RETURNS text[] AS $$ - SELECT ARRAY(SELECT jsonb_array_elements_text(_js)); -$$ LANGUAGE sql IMMUTABLE PARALLEL SAFE; - -/* -converts a jsonb text array to comma delimited list of identifer quoted -useful for constructing column lists for selects -*/ -CREATE OR REPLACE FUNCTION array_idents(_js jsonb) - RETURNS text AS $$ - SELECT string_agg(quote_ident(v),',') FROM jsonb_array_elements_text(_js) v; -$$ LANGUAGE sql IMMUTABLE PARALLEL SAFE; - - -/* looks for a geometry in a stac item first from geometry and falling back to bbox */ -CREATE OR REPLACE FUNCTION stac_geom(value jsonb) RETURNS geometry AS $$ -SELECT - CASE - WHEN value->>'geometry' IS NOT NULL THEN - ST_GeomFromGeoJSON(value->>'geometry') - WHEN value->>'bbox' IS NOT NULL THEN - ST_MakeEnvelope( - (value->'bbox'->>0)::float, - (value->'bbox'->>1)::float, - (value->'bbox'->>2)::float, - (value->'bbox'->>3)::float, - 4326 - ) - ELSE NULL - END as geometry -; -$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION stac_datetime(value jsonb) RETURNS timestamptz AS $$ -SELECT (value->'properties'->>'datetime')::timestamptz; -$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET TIMEZONE='UTC'; - -CREATE OR REPLACE FUNCTION jsonb_paths (IN jdata jsonb, OUT path text[], OUT value jsonb) RETURNS -SETOF RECORD AS $$ -with recursive extract_all as -( - select - ARRAY[key]::text[] as path, - value - FROM jsonb_each(jdata) -union all - select - path || coalesce(obj_key, (arr_key- 1)::text), - coalesce(obj_value, arr_value) - from extract_all - left join lateral - jsonb_each(case jsonb_typeof(value) when 'object' then value end) - as o(obj_key, obj_value) - on jsonb_typeof(value) = 'object' - left join lateral - jsonb_array_elements(case jsonb_typeof(value) when 'array' then value end) - with ordinality as a(arr_value, arr_key) - on jsonb_typeof(value) = 'array' - where obj_key is not null or arr_key is not null -) -select * -from extract_all; -$$ LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION jsonb_obj_paths (IN jdata jsonb, OUT path text[], OUT value jsonb) RETURNS -SETOF RECORD AS $$ -with recursive extract_all as -( - select - ARRAY[key]::text[] as path, - value - FROM jsonb_each(jdata) -union all - select - path || obj_key, - obj_value - from extract_all - left join lateral - jsonb_each(case jsonb_typeof(value) when 'object' then value end) - as o(obj_key, obj_value) - on jsonb_typeof(value) = 'object' - where obj_key is not null -) -select * -from extract_all; -$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION jsonb_val_paths (IN jdata jsonb, OUT path text[], OUT value jsonb) RETURNS -SETOF RECORD AS $$ -SELECT * FROM jsonb_obj_paths(jdata) WHERE jsonb_typeof(value) not in ('object','array'); -$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; - - -CREATE OR REPLACE FUNCTION path_includes(IN path text[], IN includes text[]) RETURNS BOOLEAN AS $$ -WITH t AS (SELECT unnest(includes) i) -SELECT EXISTS ( - SELECT 1 FROM t WHERE path @> string_to_array(trim(i), '.') -); -$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION path_excludes(IN path text[], IN excludes text[]) RETURNS BOOLEAN AS $$ -WITH t AS (SELECT unnest(excludes) e) -SELECT NOT EXISTS ( - SELECT 1 FROM t WHERE path @> string_to_array(trim(e), '.') -); -$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; - - -CREATE OR REPLACE FUNCTION jsonb_obj_paths_filtered ( - IN jdata jsonb, - IN includes text[] DEFAULT ARRAY[]::text[], - IN excludes text[] DEFAULT ARRAY[]::text[], - OUT path text[], - OUT value jsonb -) RETURNS -SETOF RECORD AS $$ -SELECT path, value -FROM jsonb_obj_paths(jdata) -WHERE - CASE WHEN cardinality(includes) > 0 THEN path_includes(path, includes) ELSE TRUE END - AND - path_excludes(path, excludes) - -; -$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; +CREATE OR REPLACE FUNCTION notice(VARIADIC text[]) RETURNS boolean AS $$ +DECLARE +debug boolean := current_setting('pgstac.debug', true); +BEGIN + IF debug THEN + RAISE NOTICE 'NOTICE FROM FUNC: % >>>>> %', concat_ws(' | ', $1), clock_timestamp(); + RETURN TRUE; + END IF; + RETURN FALSE; +END; +$$ LANGUAGE PLPGSQL; CREATE OR REPLACE FUNCTION empty_arr(ANYARRAY) RETURNS BOOLEAN AS $$ SELECT CASE @@ -147,46 +27,31 @@ ELSE FALSE END; $$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; +CREATE OR REPLACE FUNCTION array_map_ident(_a text[]) + RETURNS text[] AS $$ + SELECT array_agg(quote_ident(v)) FROM unnest(_a) v; +$$ LANGUAGE sql IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION array_map_literal(_a text[]) + RETURNS text[] AS $$ + SELECT array_agg(quote_literal(v)) FROM unnest(_a) v; +$$ LANGUAGE sql IMMUTABLE PARALLEL SAFE; -CREATE OR REPLACE FUNCTION filter_jsonb( - IN jdata jsonb, - IN includes text[] DEFAULT ARRAY[]::text[], - IN excludes text[] DEFAULT ARRAY[]::text[] -) RETURNS jsonb AS $$ +CREATE OR REPLACE FUNCTION estimated_count(_where text) RETURNS bigint AS $$ DECLARE -rec RECORD; -outj jsonb := '{}'::jsonb; -created_paths text[] := '{}'::text[]; +rec record; +rows bigint; BEGIN - -IF empty_arr(includes) AND empty_arr(excludes) THEN -RAISE NOTICE 'no filter'; - RETURN jdata; -END IF; -FOR rec in -SELECT * FROM jsonb_obj_paths_filtered(jdata, includes, excludes) -WHERE jsonb_typeof(value) != 'object' -LOOP - IF array_length(rec.path,1)>1 THEN - FOR i IN 1..(array_length(rec.path,1)-1) LOOP - IF NOT array_to_string(rec.path[1:i],'.') = ANY (created_paths) THEN - outj := jsonb_set(outj, rec.path[1:i],'{}', true); - created_paths := created_paths || array_to_string(rec.path[1:i],'.'); - END IF; - END LOOP; - END IF; - outj := jsonb_set(outj, rec.path, rec.value, true); - created_paths := created_paths || array_to_string(rec.path,'.'); -END LOOP; -RETURN outj; + FOR rec in EXECUTE format( + $q$ + EXPLAIN SELECT 1 FROM items WHERE %s + $q$, + _where) + LOOP + rows := substring(rec."QUERY PLAN" FROM ' rows=([[:digit:]]+)'); + EXIT WHEN rows IS NOT NULL; + END LOOP; + + RETURN rows; END; -$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION properties_idx(_in jsonb) RETURNS jsonb AS $$ -WITH t AS ( - select array_to_string(path,'.') as path, lower(value::text)::jsonb as lowerval - FROM jsonb_val_paths(_in) - WHERE array_to_string(path,'.') not in ('datetime') -) -SELECT jsonb_object_agg(path, lowerval) FROM t; -$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; +$$ LANGUAGE PLPGSQL; diff --git a/sql/001a_jsonutils.sql b/sql/001a_jsonutils.sql new file mode 100644 index 00000000..183cd4a4 --- /dev/null +++ b/sql/001a_jsonutils.sql @@ -0,0 +1,138 @@ +/* converts a jsonb text array to a pg text[] array */ +CREATE OR REPLACE FUNCTION textarr(_js jsonb) + RETURNS text[] AS $$ + SELECT + CASE jsonb_typeof(_js) + WHEN 'array' THEN ARRAY(SELECT jsonb_array_elements_text(_js)) + ELSE ARRAY[_js->>0] + END +; +$$ LANGUAGE sql IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION jsonb_paths (IN jdata jsonb, OUT path text[], OUT value jsonb) RETURNS +SETOF RECORD AS $$ +with recursive extract_all as +( + select + ARRAY[key]::text[] as path, + value + FROM jsonb_each(jdata) +union all + select + path || coalesce(obj_key, (arr_key- 1)::text), + coalesce(obj_value, arr_value) + from extract_all + left join lateral + jsonb_each(case jsonb_typeof(value) when 'object' then value end) + as o(obj_key, obj_value) + on jsonb_typeof(value) = 'object' + left join lateral + jsonb_array_elements(case jsonb_typeof(value) when 'array' then value end) + with ordinality as a(arr_value, arr_key) + on jsonb_typeof(value) = 'array' + where obj_key is not null or arr_key is not null +) +select * +from extract_all; +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION jsonb_obj_paths (IN jdata jsonb, OUT path text[], OUT value jsonb) RETURNS +SETOF RECORD AS $$ +with recursive extract_all as +( + select + ARRAY[key]::text[] as path, + value + FROM jsonb_each(jdata) +union all + select + path || obj_key, + obj_value + from extract_all + left join lateral + jsonb_each(case jsonb_typeof(value) when 'object' then value end) + as o(obj_key, obj_value) + on jsonb_typeof(value) = 'object' + where obj_key is not null +) +select * +from extract_all; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION jsonb_val_paths (IN jdata jsonb, OUT path text[], OUT value jsonb) RETURNS +SETOF RECORD AS $$ +SELECT * FROM jsonb_obj_paths(jdata) WHERE jsonb_typeof(value) not in ('object','array'); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION path_includes(IN path text[], IN includes text[]) RETURNS BOOLEAN AS $$ +WITH t AS (SELECT unnest(includes) i) +SELECT EXISTS ( + SELECT 1 FROM t WHERE path @> string_to_array(trim(i), '.') +); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION path_excludes(IN path text[], IN excludes text[]) RETURNS BOOLEAN AS $$ +WITH t AS (SELECT unnest(excludes) e) +SELECT NOT EXISTS ( + SELECT 1 FROM t WHERE path @> string_to_array(trim(e), '.') +); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + + +CREATE OR REPLACE FUNCTION jsonb_obj_paths_filtered ( + IN jdata jsonb, + IN includes text[] DEFAULT ARRAY[]::text[], + IN excludes text[] DEFAULT ARRAY[]::text[], + OUT path text[], + OUT value jsonb +) RETURNS +SETOF RECORD AS $$ +SELECT path, value +FROM jsonb_obj_paths(jdata) +WHERE + CASE WHEN cardinality(includes) > 0 THEN path_includes(path, includes) ELSE TRUE END + AND + path_excludes(path, excludes) + +; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION filter_jsonb( + IN jdata jsonb, + IN includes text[] DEFAULT ARRAY[]::text[], + IN excludes text[] DEFAULT ARRAY[]::text[] +) RETURNS jsonb AS $$ +DECLARE +rec RECORD; +outj jsonb := '{}'::jsonb; +created_paths text[] := '{}'::text[]; +BEGIN + +IF empty_arr(includes) AND empty_arr(excludes) THEN +RAISE NOTICE 'no filter'; + RETURN jdata; +END IF; +FOR rec in +SELECT * FROM jsonb_obj_paths_filtered(jdata, includes, excludes) +WHERE jsonb_typeof(value) != 'object' +LOOP + IF array_length(rec.path,1)>1 THEN + FOR i IN 1..(array_length(rec.path,1)-1) LOOP + IF NOT array_to_string(rec.path[1:i],'.') = ANY (created_paths) THEN + outj := jsonb_set(outj, rec.path[1:i],'{}', true); + created_paths := created_paths || array_to_string(rec.path[1:i],'.'); + END IF; + END LOOP; + END IF; + outj := jsonb_set(outj, rec.path, rec.value, true); + created_paths := created_paths || array_to_string(rec.path,'.'); +END LOOP; +RETURN outj; +END; +$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION flip_jsonb_array(j jsonb) RETURNS jsonb AS $$ +SELECT jsonb_agg(value) FROM (SELECT value FROM jsonb_array_elements(j) WITH ORDINALITY ORDER BY ordinality DESC) as t; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; diff --git a/sql/001b_cursorutils.sql b/sql/001b_cursorutils.sql new file mode 100644 index 00000000..3cd765e4 --- /dev/null +++ b/sql/001b_cursorutils.sql @@ -0,0 +1,108 @@ +/* Functions to create an iterable of cursors over partitions. */ +CREATE OR REPLACE FUNCTION create_cursor(q text) RETURNS refcursor AS $$ +DECLARE + curs refcursor; +BEGIN + OPEN curs FOR EXECUTE q; + RETURN curs; +END; +$$ LANGUAGE PLPGSQL; + +CREATE OR REPLACE FUNCTION partition_queries( + IN _where text DEFAULT 'TRUE', + IN _orderby text DEFAULT 'datetime DESC, id DESC' +) RETURNS SETOF text AS $$ +DECLARE + partition_query text; + query text; + p record; + cursors refcursor; +BEGIN +IF _orderby ILIKE 'datetime d%' THEN + partition_query := format($q$ + SELECT partition, tstzrange + FROM items_partitions + ORDER BY tstzrange DESC; + $q$); +ELSIF _orderby ILIKE 'datetime a%' THEN + partition_query := format($q$ + SELECT partition, tstzrange + FROM items_partitions + ORDER BY tstzrange ASC + ; + $q$); +ELSE + query := format($q$ + SELECT * FROM items + WHERE %s + ORDER BY %s + $q$, _where, _orderby + ); + + RETURN NEXT query; + RETURN; +END IF; +FOR p IN + EXECUTE partition_query +LOOP + query := format($q$ + SELECT * FROM items + WHERE datetime >= %L AND datetime < %L AND %s + ORDER BY %s + $q$, lower(p.tstzrange), upper(p.tstzrange), _where, _orderby + ); + RETURN NEXT query; +END LOOP; +RETURN; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION partition_cursor( + IN _where text DEFAULT 'TRUE', + IN _orderby text DEFAULT 'datetime DESC, id DESC' +) RETURNS SETOF refcursor AS $$ +DECLARE + partition_query text; + query text; + p record; + cursors refcursor; +BEGIN +FOR query IN SELECT * FROM partion_queries(_where, _orderby) LOOP + RETURN NEXT create_cursor(query); +END LOOP; +RETURN; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION partition_count( + IN _where text DEFAULT 'TRUE' +) RETURNS bigint AS $$ +DECLARE + partition_query text; + query text; + p record; + subtotal bigint; + total bigint := 0; +BEGIN +partition_query := format($q$ + SELECT partition, tstzrange + FROM items_partitions + ORDER BY tstzrange DESC; +$q$); +RAISE NOTICE 'Partition Query: %', partition_query; +FOR p IN + EXECUTE partition_query +LOOP + query := format($q$ + SELECT count(*) FROM items + WHERE datetime BETWEEN %L AND %L AND %s + $q$, lower(p.tstzrange), upper(p.tstzrange), _where + ); + RAISE NOTICE 'Query %', query; + RAISE NOTICE 'Partition %, Count %, Total %',p.partition, subtotal, total; + EXECUTE query INTO subtotal; + total := subtotal + total; +END LOOP; +RETURN total; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; diff --git a/sql/001s_stacutils.sql b/sql/001s_stacutils.sql new file mode 100644 index 00000000..42e0afe3 --- /dev/null +++ b/sql/001s_stacutils.sql @@ -0,0 +1,37 @@ +/* looks for a geometry in a stac item first from geometry and falling back to bbox */ +CREATE OR REPLACE FUNCTION stac_geom(value jsonb) RETURNS geometry AS $$ +SELECT + CASE + WHEN value->>'geometry' IS NOT NULL THEN + ST_GeomFromGeoJSON(value->>'geometry') + WHEN value->>'bbox' IS NOT NULL THEN + ST_MakeEnvelope( + (value->'bbox'->>0)::float, + (value->'bbox'->>1)::float, + (value->'bbox'->>2)::float, + (value->'bbox'->>3)::float, + 4326 + ) + ELSE NULL + END as geometry +; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION stac_datetime(value jsonb) RETURNS timestamptz AS $$ +SELECT COALESCE( + (value->'properties'->>'datetime')::timestamptz, + (value->'properties'->>'start_datetime')::timestamptz +); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET TIMEZONE='UTC'; + +CREATE OR REPLACE FUNCTION stac_end_datetime(value jsonb) RETURNS timestamptz AS $$ +SELECT COALESCE( + (value->'properties'->>'datetime')::timestamptz, + (value->'properties'->>'end_datetime')::timestamptz +); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET TIMEZONE='UTC'; + + +CREATE OR REPLACE FUNCTION stac_daterange(value jsonb) RETURNS tstzrange AS $$ +SELECT tstzrange(stac_datetime(value),stac_end_datetime(value)); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET TIMEZONE='UTC'; diff --git a/sql/003_items.sql b/sql/003_items.sql index c2cf8d3c..bfebc1ca 100644 --- a/sql/003_items.sql +++ b/sql/003_items.sql @@ -1,161 +1,270 @@ SET SEARCH_PATH TO pgstac, public; -CREATE TABLE IF NOT EXISTS items ( - id VARCHAR GENERATED ALWAYS AS (content->>'id') STORED NOT NULL, - geometry geometry GENERATED ALWAYS AS (stac_geom(content)) STORED NOT NULL, - properties jsonb GENERATED ALWAYS as (properties_idx(content->'properties')) STORED, - collection_id text GENERATED ALWAYS AS (content->>'collection') STORED NOT NULL, - datetime timestamptz GENERATED ALWAYS AS (stac_datetime(content)) STORED NOT NULL, +CREATE TABLE items ( + id text NOT NULL, + geometry geometry NOT NULL, + collection_id text NOT NULL, + datetime timestamptz NOT NULL, + end_datetime timestamptz NOT NULL, + properties jsonb NOT NULL, content JSONB NOT NULL ) -PARTITION BY RANGE (stac_datetime(content)) +PARTITION BY RANGE (datetime) ; -ALTER TABLE items ADD constraint items_collections_fk FOREIGN KEY (collection_id) REFERENCES collections(id) DEFERRABLE; +CREATE OR REPLACE FUNCTION properties_idx (IN content jsonb) RETURNS jsonb AS $$ + with recursive extract_all as + ( + select + ARRAY[key]::text[] as path, + ARRAY[key]::text[] as fullpath, + value + FROM jsonb_each(content->'properties') + union all + select + CASE WHEN obj_key IS NOT NULL THEN path || obj_key ELSE path END, + path || coalesce(obj_key, (arr_key- 1)::text), + coalesce(obj_value, arr_value) + from extract_all + left join lateral + jsonb_each(case jsonb_typeof(value) when 'object' then value end) + as o(obj_key, obj_value) + on jsonb_typeof(value) = 'object' + left join lateral + jsonb_array_elements(case jsonb_typeof(value) when 'array' then value end) + with ordinality as a(arr_value, arr_key) + on jsonb_typeof(value) = 'array' + where obj_key is not null or arr_key is not null + ) + , paths AS ( + select + array_to_string(path, '.') as path, + value + FROM extract_all + WHERE + jsonb_typeof(value) NOT IN ('array','object') + ), grouped AS ( + SELECT path, jsonb_agg(distinct value) vals FROM paths group by path + ) SELECT coalesce(jsonb_object_agg(path, CASE WHEN jsonb_array_length(vals)=1 THEN vals->0 ELSE vals END) - '{datetime}'::text[], '{}'::jsonb) FROM grouped + ; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE SET JIT TO OFF; -CREATE TABLE items_template ( - LIKE items -); +CREATE INDEX "datetime_idx" ON items (datetime); +CREATE INDEX "end_datetime_idx" ON items (end_datetime); +CREATE INDEX "properties_idx" ON items USING GIN (properties jsonb_path_ops); +CREATE INDEX "collection_idx" ON items (collection_id); +CREATE INDEX "geometry_idx" ON items USING GIST (geometry); +CREATE UNIQUE INDEX "items_id_datetime_idx" ON items (datetime, id); + +ALTER TABLE items ADD CONSTRAINT items_collections_fk FOREIGN KEY (collection_id) REFERENCES collections(id) ON DELETE CASCADE DEFERRABLE; + +CREATE OR REPLACE FUNCTION analyze_empty_partitions() RETURNS VOID AS $$ +DECLARE + p text; +BEGIN + FOR p IN SELECT partition FROM all_items_partitions WHERE est_cnt = 0 LOOP + EXECUTE format('ANALYZE %I;', p); + END LOOP; +END; +$$ LANGUAGE PLPGSQL; -ALTER TABLE items_template ADD PRIMARY KEY (id); +CREATE OR REPLACE FUNCTION items_partition_name(timestamptz) RETURNS text AS $$ + SELECT to_char($1, '"items_p"IYYY"w"IW'); +$$ LANGUAGE SQL; -DELETE from partman.part_config WHERE parent_table = 'pgstac.items'; -SELECT partman.create_parent( - 'pgstac.items', - 'datetime', - 'native', - 'weekly', - p_template_table := 'pgstac.items_template', - p_premake := 4 -); +CREATE OR REPLACE FUNCTION items_partition_exists(text) RETURNS boolean AS $$ + SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class WHERE relname=$1); +$$ LANGUAGE SQL; -CREATE OR REPLACE FUNCTION make_partitions(st timestamptz, et timestamptz DEFAULT NULL) RETURNS BOOL AS $$ +CREATE OR REPLACE FUNCTION items_partition_exists(timestamptz) RETURNS boolean AS $$ + SELECT EXISTS (SELECT 1 FROM pg_catalog.pg_class WHERE relname=items_partition_name($1)); +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION items_partition_create_worker(partition text, partition_start timestamptz, partition_end timestamptz) RETURNS VOID AS $$ +DECLARE + err_context text; +BEGIN + EXECUTE format( + $f$ + CREATE TABLE IF NOT EXISTS %1$I PARTITION OF items + FOR VALUES FROM (%2$L) TO (%3$L); + CREATE UNIQUE INDEX IF NOT EXISTS %4$I ON %1$I (id); + $f$, + partition, + partition_start, + partition_end, + concat(partition, '_id_pk') + ); +EXCEPTION + WHEN duplicate_table THEN + RAISE NOTICE 'Partition % already exists.', partition; + WHEN others THEN + GET STACKED DIAGNOSTICS err_context = PG_EXCEPTION_CONTEXT; + RAISE INFO 'Error Name:%',SQLERRM; + RAISE INFO 'Error State:%', SQLSTATE; + RAISE INFO 'Error Context:%', err_context; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH to pgstac, public; + +CREATE OR REPLACE FUNCTION items_partition_create(ts timestamptz) RETURNS text AS $$ +DECLARE + partition text := items_partition_name(ts); + partition_start timestamptz; + partition_end timestamptz; +BEGIN + IF items_partition_exists(partition) THEN + RETURN partition; + END IF; + partition_start := date_trunc('week', ts); + partition_end := partition_start + '1 week'::interval; + PERFORM items_partition_create_worker(partition, partition_start, partition_end); + RAISE NOTICE 'partition: %', partition; + RETURN partition; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac, public; + +CREATE OR REPLACE FUNCTION items_partition_create(st timestamptz, et timestamptz) RETURNS SETOF text AS $$ WITH t AS ( SELECT generate_series( date_trunc('week',st), - date_trunc('week', coalesce(et, st)), + date_trunc('week', et), '1 week'::interval ) w -), -w AS (SELECT array_agg(w) as w FROM t) -SELECT CASE WHEN w IS NULL THEN NULL ELSE partman.create_partition_time('pgstac.items', w, true) END FROM w; -$$ LANGUAGE SQL; - -CREATE OR REPLACE FUNCTION get_partition(timestamptz) RETURNS text AS $$ -SELECT to_char($1, '"items_p"IYYY"w"IW'); +) +SELECT items_partition_create(w) FROM t; $$ LANGUAGE SQL; -CREATE INDEX "datetime_id_idx" ON items (datetime, id); -CREATE INDEX "properties_idx" ON items USING GIN (properties); -CREATE INDEX "collection_idx" ON items (collection_id); -CREATE INDEX "geometry_idx" ON items USING GIST (geometry); - -CREATE TYPE item AS ( - id text, - geometry geometry, - properties JSONB, - collection_id text, - datetime timestamptz +CREATE UNLOGGED TABLE items_staging ( + content JSONB NOT NULL ); - -CREATE OR REPLACE FUNCTION get_item(_id text) RETURNS jsonb AS $$ - SELECT content FROM items WHERE id=_id; -$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac,public; - -CREATE OR REPLACE FUNCTION delete_item(_id text) RETURNS VOID AS $$ +CREATE OR REPLACE FUNCTION items_staging_insert_triggerfunc() RETURNS TRIGGER AS $$ DECLARE -out items%ROWTYPE; + mindate timestamptz; + maxdate timestamptz; + partition text; BEGIN - DELETE FROM items WHERE id = _id RETURNING * INTO STRICT out; + SELECT min(stac_datetime(content)), max(stac_datetime(content)) INTO mindate, maxdate FROM newdata; + PERFORM items_partition_create(mindate, maxdate); + INSERT INTO items (id, geometry, collection_id, datetime, end_datetime, properties, content) + SELECT + content->>'id', + stac_geom(content), + content->>'collection', + stac_datetime(content), + stac_end_datetime(content), + properties_idx(content), + content + FROM newdata + ; + DELETE FROM items_staging; + PERFORM analyze_empty_partitions(); + RETURN NULL; END; -$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; +$$ LANGUAGE PLPGSQL; -CREATE OR REPLACE FUNCTION create_item(data jsonb) RETURNS VOID AS $$ - SELECT make_partitions(stac_datetime(data)); - INSERT INTO items (content) VALUES (data); -$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac,public; +CREATE TRIGGER items_staging_insert_trigger AFTER INSERT ON items_staging REFERENCING NEW TABLE AS newdata + FOR EACH STATEMENT EXECUTE PROCEDURE items_staging_insert_triggerfunc(); -CREATE OR REPLACE FUNCTION update_item(data jsonb) RETURNS VOID AS $$ -DECLARE -out items%ROWTYPE; -BEGIN - UPDATE items SET content=data WHERE id = data->>'id' RETURNING * INTO STRICT out; -END; -$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; -CREATE OR REPLACE FUNCTION upsert_item(data jsonb) RETURNS VOID AS $$ +CREATE UNLOGGED TABLE items_staging_ignore ( + content JSONB NOT NULL +); + +CREATE OR REPLACE FUNCTION items_staging_ignore_insert_triggerfunc() RETURNS TRIGGER AS $$ DECLARE -partition text; -q text; -newcontent jsonb; + mindate timestamptz; + maxdate timestamptz; + partition text; BEGIN - PERFORM make_partitions(stac_datetime(data)); - partition := get_partition(stac_datetime(data)); - q := format($q$ - INSERT INTO %I (content) VALUES ($1) - ON CONFLICT (id) DO - UPDATE SET content = EXCLUDED.content - WHERE %I.content IS DISTINCT FROM EXCLUDED.content RETURNING content; - $q$, partition, partition); - EXECUTE q INTO newcontent USING (data); - RAISE NOTICE 'newcontent: %', newcontent; - RETURN; + SELECT min(stac_datetime(content)), max(stac_datetime(content)) INTO mindate, maxdate FROM newdata; + PERFORM items_partition_create(mindate, maxdate); + INSERT INTO items (id, geometry, collection_id, datetime, end_datetime, properties, content) + SELECT + content->>'id', + stac_geom(content), + content->>'collection', + stac_datetime(content), + stac_end_datetime(content), + properties_idx(content), + content + FROM newdata + ON CONFLICT DO NOTHING + ; + DELETE FROM items_staging_ignore; + PERFORM analyze_empty_partitions(); + RETURN NULL; END; -$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; +$$ LANGUAGE PLPGSQL; -CREATE OR REPLACE FUNCTION analyze_empty_partitions() RETURNS VOID AS $$ +CREATE TRIGGER items_staging_ignore_insert_trigger AFTER INSERT ON items_staging_ignore REFERENCING NEW TABLE AS newdata + FOR EACH STATEMENT EXECUTE PROCEDURE items_staging_ignore_insert_triggerfunc(); + +CREATE UNLOGGED TABLE items_staging_upsert ( + content JSONB NOT NULL +); + +CREATE OR REPLACE FUNCTION items_staging_upsert_insert_triggerfunc() RETURNS TRIGGER AS $$ DECLARE -p text; + mindate timestamptz; + maxdate timestamptz; + partition text; BEGIN -FOR p IN SELECT partition FROM all_items_partitions WHERE est_cnt = 0 LOOP - RAISE NOTICE 'Analyzing %', p; - EXECUTE format('ANALYZE %I;', p); -END LOOP; + SELECT min(stac_datetime(content)), max(stac_datetime(content)) INTO mindate, maxdate FROM newdata; + PERFORM items_partition_create(mindate, maxdate); + INSERT INTO items (id, geometry, collection_id, datetime, end_datetime, properties, content) + SELECT + content->>'id', + stac_geom(content), + content->>'collection', + stac_datetime(content), + stac_end_datetime(content), + properties_idx(content), + content + FROM newdata + ON CONFLICT (datetime, id) DO UPDATE SET + content = EXCLUDED.content + WHERE items.content IS DISTINCT FROM EXCLUDED.content + ; + DELETE FROM items_staging_upsert; + PERFORM analyze_empty_partitions(); + RETURN NULL; END; $$ LANGUAGE PLPGSQL; -CREATE OR REPLACE FUNCTION backfill_partitions() -RETURNS VOID AS $$ -DECLARE -BEGIN - IF EXISTS (SELECT 1 FROM items_default LIMIT 1) THEN - RAISE NOTICE 'Creating new partitions and moving data from default'; - CREATE TEMP TABLE items_default_tmp ON COMMIT DROP AS SELECT datetime, content FROM items_default; - TRUNCATE items_default; - PERFORM make_partitions(min(datetime), max(datetime)) FROM items_default_tmp; - INSERT INTO items (content) SELECT content FROM items_default_tmp; - END IF; - RETURN; -END; -$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; -CREATE OR REPLACE FUNCTION items_trigger_stmt_func() -RETURNS TRIGGER AS $$ +CREATE TRIGGER items_staging_upsert_insert_trigger AFTER INSERT ON items_staging_upsert REFERENCING NEW TABLE AS newdata + FOR EACH STATEMENT EXECUTE PROCEDURE items_staging_upsert_insert_triggerfunc(); + +CREATE OR REPLACE FUNCTION items_update_triggerfunc() RETURNS TRIGGER AS $$ DECLARE BEGIN - PERFORM analyze_empty_partitions(); - RETURN NULL; + NEW.id := NEW.content->>'id'; + NEW.datetime := stac_datetime(NEW.content); + NEW.end_datetime := stac_end_datetime(NEW.content); + NEW.collection_id := NEW.content->>'collection'; + NEW.geometry := stac_geom(NEW.content); + NEW.properties := properties_idx(NEW.content); + IF TG_OP = 'UPDATE' AND NEW IS NOT DISTINCT FROM OLD THEN + RETURN NULL; + END IF; + RETURN NEW; END; -$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; - -DROP TRIGGER IF EXISTS items_stmt_trigger ON items; -CREATE TRIGGER items_stmt_trigger -AFTER INSERT OR UPDATE OR DELETE ON items -FOR EACH STATEMENT EXECUTE PROCEDURE items_trigger_stmt_func(); +$$ LANGUAGE PLPGSQL; +CREATE TRIGGER items_update_trigger BEFORE UPDATE ON items + FOR EACH ROW EXECUTE PROCEDURE items_update_triggerfunc(); /* View to get a table of available items partitions with date ranges */ ---DROP VIEW IF EXISTS all_items_partitions CASCADE; -CREATE OR REPLACE VIEW all_items_partitions AS +CREATE VIEW all_items_partitions AS WITH base AS (SELECT c.oid::pg_catalog.regclass::text as partition, @@ -174,10 +283,39 @@ SELECT partition, tstzrange( FROM base ORDER BY 2 desc; ---DROP VIEW IF EXISTS items_partitions; CREATE OR REPLACE VIEW items_partitions AS SELECT * FROM all_items_partitions WHERE est_cnt>0; +CREATE OR REPLACE FUNCTION get_item(_id text) RETURNS jsonb AS $$ + SELECT content FROM items WHERE id=_id; +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION delete_item(_id text) RETURNS VOID AS $$ +DECLARE +out items%ROWTYPE; +BEGIN + DELETE FROM items WHERE id = _id RETURNING * INTO STRICT out; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION create_item(data jsonb) RETURNS VOID AS $$ + INSERT INTO items_staging (content) VALUES (data); +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac,public; + + +CREATE OR REPLACE FUNCTION update_item(data jsonb) RETURNS VOID AS $$ +DECLARE + out items%ROWTYPE; +BEGIN + UPDATE items SET content=data WHERE id = data->>'id' RETURNING * INTO STRICT out; +END; +$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; + +CREATE OR REPLACE FUNCTION upsert_item(data jsonb) RETURNS VOID AS $$ + INSERT INTO items_staging_upsert (content) VALUES (data); +$$ LANGUAGE SQL SET SEARCH_PATH TO pgstac,public; + + CREATE OR REPLACE FUNCTION collection_bbox(id text) RETURNS jsonb AS $$ SELECT (replace(replace(replace(st_extent(geometry)::text,'BOX(','[['),')',']]'),' ',','))::jsonb FROM items WHERE collection_id=$1; diff --git a/sql/004_search.sql b/sql/004_search.sql index e8283090..770493aa 100644 --- a/sql/004_search.sql +++ b/sql/004_search.sql @@ -1,142 +1,91 @@ -SET SEARCH_PATH TO pgstac, public; +SET SEARCH_PATH TO pgstac, public; -CREATE OR REPLACE FUNCTION items_by_partition( - IN _where text DEFAULT 'TRUE', - IN _dtrange tstzrange DEFAULT tstzrange('-infinity','infinity'), - IN _orderby text DEFAULT 'datetime DESC, id DESC', - IN _limit int DEFAULT 10 -) RETURNS SETOF items AS $$ +CREATE OR REPLACE FUNCTION items_path( + IN dotpath text, + OUT field text, + OUT path text, + OUT path_txt text, + OUT jsonpath text, + OUT eq text +) RETURNS RECORD AS $$ DECLARE -partition_query text; -main_query text; -batchcount int; -counter int := 0; -p record; +path_elements text[]; +last_element text; BEGIN -IF _orderby ILIKE 'datetime d%' THEN - partition_query := format($q$ - SELECT partition - FROM items_partitions - WHERE tstzrange && $1 - ORDER BY tstzrange DESC; - $q$); -ELSIF _orderby ILIKE 'datetime a%' THEN - partition_query := format($q$ - SELECT partition - FROM items_partitions - WHERE tstzrange && $1 - ORDER BY tstzrange ASC - ; - $q$); +dotpath := replace(trim(dotpath), 'properties.', ''); + +IF dotpath = '' THEN + RETURN; +END IF; + +path_elements := string_to_array(dotpath, '.'); +jsonpath := NULL; + +IF path_elements[1] IN ('id','geometry','datetime') THEN + field := path_elements[1]; + path_elements := path_elements[2:]; +ELSIF path_elements[1] = 'collection' THEN + field := 'collection_id'; + path_elements := path_elements[2:]; +ELSIF path_elements[1] IN ('links', 'assets', 'stac_version', 'stac_extensions') THEN + field := 'content'; ELSE - partition_query := format($q$ - SELECT 'items' as partition WHERE $1 IS NOT NULL; - $q$); -END IF; -RAISE NOTICE 'Partition Query: %', partition_query; -FOR p IN - EXECUTE partition_query USING (_dtrange) -LOOP - IF lower(_dtrange)::timestamptz > '-infinity' THEN - _where := concat(_where,format(' AND datetime >= %L',lower(_dtrange)::timestamptz::text)); - END IF; - IF upper(_dtrange)::timestamptz < 'infinity' THEN - _where := concat(_where,format(' AND datetime <= %L',upper(_dtrange)::timestamptz::text)); - END IF; + field := 'content'; + path_elements := '{properties}'::text[] || path_elements; +END IF; +IF cardinality(path_elements)<1 THEN + path := field; + path_txt := field; + jsonpath := '$'; + eq := NULL; -- format($F$ %s = %%s $F$, field); + RETURN; +END IF; - main_query := format($q$ - SELECT * FROM %I - WHERE %s - ORDER BY %s - LIMIT %s - $1 - $q$, p.partition::text, _where, _orderby, _limit - ); - RAISE NOTICE 'Partition Query %', main_query; - RAISE NOTICE '%', counter; - RETURN QUERY EXECUTE main_query USING counter; - - GET DIAGNOSTICS batchcount = ROW_COUNT; - counter := counter + batchcount; - RAISE NOTICE 'FOUND %', batchcount; - IF counter >= _limit THEN - EXIT; - END IF; - RAISE NOTICE 'ADDED % FOR A TOTAL OF %', batchcount, counter; -END LOOP; -RETURN; -END; -$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; +last_element := path_elements[cardinality(path_elements)]; +path_elements := path_elements[1:cardinality(path_elements)-1]; +jsonpath := concat(array_to_string('{$}'::text[] || array_map_ident(path_elements), '.'), '.', quote_ident(last_element)); +path_elements := array_map_literal(path_elements); +path := format($F$ properties->%s $F$, quote_literal(dotpath)); +path_txt := format($F$ properties->>%s $F$, quote_literal(dotpath)); +eq := format($F$ properties @? '$.%s[*] ? (@ == %%s) '$F$, quote_ident(dotpath)); -CREATE OR REPLACE FUNCTION split_stac_path(IN path text, OUT col text, OUT dotpath text, OUT jspath text, OUT jspathtext text) AS $$ -WITH col AS ( - SELECT - CASE WHEN - split_part(path, '.', 1) IN ('id', 'stac_version', 'stac_extensions','geometry','properties','assets','collection_id','datetime','links', 'extra_fields') THEN split_part(path, '.', 1) - ELSE 'properties' - END AS col -), -dp AS ( - SELECT - col, ltrim(replace(path, col , ''),'.') as dotpath - FROM col -), -paths AS ( -SELECT - col, dotpath, - regexp_split_to_table(dotpath,E'\\.') as path FROM dp -) SELECT - col, - btrim(concat(col,'.',dotpath),'.'), - CASE WHEN btrim(concat(col,'.',dotpath),'.') != col THEN concat(col,'->',string_agg(concat('''',path,''''),'->')) ELSE col END, - regexp_replace( - CASE WHEN btrim(concat(col,'.',dotpath),'.') != col THEN concat(col,'->',string_agg(concat('''',path,''''),'->')) ELSE col END, - E'>([^>]*)$','>>\1' - ) -FROM paths group by col, dotpath; -$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; +RAISE NOTICE 'ITEMS PATH -- % % % % %', field, path, path_txt, jsonpath, eq; +RETURN; +END; +$$ LANGUAGE PLPGSQL IMMUTABLE PARALLEL SAFE; -/* Functions for searching items */ -CREATE OR REPLACE FUNCTION sort_base( - IN _sort jsonb DEFAULT '[{"field":"datetime","direction":"desc"}]', - OUT key text, - OUT col text, - OUT dir text, - OUT rdir text, - OUT sort text, - OUT rsort text -) RETURNS SETOF RECORD AS $$ -WITH sorts AS ( +CREATE OR REPLACE FUNCTION parse_dtrange(IN _indate jsonb, OUT _tstzrange tstzrange) AS $$ +WITH t AS ( + SELECT CASE + WHEN jsonb_typeof(_indate) = 'array' THEN + textarr(_indate) + ELSE + regexp_split_to_array( + btrim(_indate::text,'"'), + '/' + ) + END AS arr +) +, t1 AS ( SELECT - value->>'field' as key, - (split_stac_path(value->>'field')).jspathtext as col, - coalesce(upper(value->>'direction'),'ASC') as dir - FROM jsonb_array_elements('[]'::jsonb || coalesce(_sort,'[{"field":"datetime","direction":"desc"}]') ) + CASE + WHEN array_upper(arr,1) = 1 OR arr[1] = '..' OR arr[1] IS NULL THEN '-infinity'::timestamptz + ELSE arr[1]::timestamptz + END AS st, + CASE + WHEN array_upper(arr,1) = 1 THEN arr[1]::timestamptz + WHEN arr[2] = '..' OR arr[2] IS NULL THEN 'infinity'::timestamptz + ELSE arr[2]::timestamptz + END AS et + FROM t ) SELECT - key, - col, - dir, - CASE dir WHEN 'DESC' THEN 'ASC' ELSE 'ASC' END as rdir, - concat(col, ' ', dir, ' NULLS LAST ') AS sort, - concat(col,' ', CASE dir WHEN 'DESC' THEN 'ASC' ELSE 'ASC' END, ' NULLS LAST ') AS rsort -FROM sorts -UNION ALL -SELECT 'id', 'id', 'DESC', 'ASC', 'id DESC', 'id ASC' -; -$$ LANGUAGE SQL; - - -CREATE OR REPLACE FUNCTION sort(_sort jsonb) RETURNS text AS $$ -SELECT string_agg(sort,', ') FROM sort_base(_sort); -$$ LANGUAGE SQL PARALLEL SAFE SET SEARCH_PATH TO pgstac,public; - - -CREATE OR REPLACE FUNCTION rsort(_sort jsonb) RETURNS text AS $$ -SELECT string_agg(rsort,', ') FROM sort_base(_sort); -$$ LANGUAGE SQL PARALLEL SAFE SET SEARCH_PATH TO pgstac,public; + tstzrange(st,et) +FROM t1; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; CREATE OR REPLACE FUNCTION bbox_geom(_bbox jsonb) RETURNS geometry AS $$ @@ -165,406 +114,743 @@ SELECT CASE jsonb_array_length(_bbox) ; $$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; -CREATE OR REPLACE FUNCTION in_array_q(col text, arr jsonb) RETURNS text AS $$ -SELECT CASE jsonb_typeof(arr) WHEN 'array' THEN format('%I = ANY(textarr(%L))', col, arr) ELSE format('%I = %L', col, arr) END; -$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; - -CREATE OR REPLACE FUNCTION count_by_delim(text, text) RETURNS int AS $$ -SELECT count(*) FROM regexp_split_to_table($1,$2); -$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; - +CREATE OR REPLACE FUNCTION cql_and_append(existing jsonb, newfilters jsonb) RETURNS jsonb AS $$ +SELECT CASE WHEN existing ? 'filter' AND newfilters IS NOT NULL THEN + jsonb_build_object( + 'and', + jsonb_build_array( + existing->'filter', + newfilters + ) + ) +ELSE + newfilters +END; +$$ LANGUAGE SQL; -CREATE OR REPLACE FUNCTION stac_query_op(att text, _op text, val jsonb) RETURNS text AS $$ +-- ADDs base filters (ids, collections, datetime, bbox, intersects) that are +-- added outside of the filter/query in the stac request +CREATE OR REPLACE FUNCTION add_filters_to_cql(j jsonb) RETURNS jsonb AS $$ DECLARE -ret text := ''; -op text; -jp text; -att_parts RECORD; -val_str text; -prop_path text; +newprop jsonb; +newprops jsonb := '[]'::jsonb; BEGIN -val_str := lower(jsonb_build_object('a',val)->>'a'); -RAISE NOTICE 'val_str %', val_str; - -att_parts := split_stac_path(att); -prop_path := replace(att_parts.dotpath, 'properties.', ''); - -op := CASE _op - WHEN 'eq' THEN '=' - WHEN 'gte' THEN '>=' - WHEN 'gt' THEN '>' - WHEN 'lte' THEN '<=' - WHEN 'lt' THEN '<' - WHEN 'ne' THEN '!=' - WHEN 'neq' THEN '!=' - WHEN 'startsWith' THEN 'LIKE' - WHEN 'endsWith' THEN 'LIKE' - WHEN 'contains' THEN 'LIKE' - ELSE _op -END; +IF j ? 'id' THEN + newprop := jsonb_build_object( + 'in', + jsonb_build_array( + '{"property":"id"}'::jsonb, + j->'id' + ) + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; +IF j ? 'collection' THEN + newprop := jsonb_build_object( + 'in', + jsonb_build_array( + '{"property":"collection"}'::jsonb, + j->'collection' + ) + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; -val_str := CASE _op - WHEN 'startsWith' THEN concat(val_str, '%') - WHEN 'endsWith' THEN concat('%', val_str) - WHEN 'contains' THEN concat('%',val_str,'%') - ELSE val_str -END; +IF j ? 'datetime' THEN + newprop := format( + '{"anyinteracts":[{"property":"datetime"}, %s]}', + j->'datetime' + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; +IF j ? 'bbox' THEN + newprop := format( + '{"intersects":[{"property":"geometry"}, %s]}', + j->'bbox' + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; -RAISE NOTICE 'att_parts: % %', att_parts, count_by_delim(att_parts.dotpath,'\.'); -IF - op = '=' - AND att_parts.col = 'properties' - --AND count_by_delim(att_parts.dotpath,'\.') = 2 -THEN - -- use jsonpath query to leverage index for eqaulity tests on single level deep properties - jp := btrim(format($jp$ $.%I[*] ? ( @ == %s ) $jp$, replace(att_parts.dotpath, 'properties.',''), lower(val::text)::jsonb)); - raise notice 'jp: %', jp; - ret := format($q$ properties @? %L $q$, jp); -ELSIF jsonb_typeof(val) = 'number' THEN - ret := format('properties ? %L AND (%s)::numeric %s %s', prop_path, att_parts.jspathtext, op, val); -ELSE - ret := format('properties ? %L AND %s %s %L', prop_path ,att_parts.jspathtext, op, val_str); +IF j ? 'intersects' THEN + newprop := format( + '{"intersects":[{"property":"geometry"}, %s]}', + j->'intersects' + ); + newprops := jsonb_insert(newprops, '{1}', newprop); +END IF; + +RAISE NOTICE 'newprops: %', newprops; + +IF newprops IS NOT NULL AND jsonb_array_length(newprops) > 0 THEN + return jsonb_set( + j, + '{filter}', + cql_and_append(j, jsonb_build_object('and', newprops)) + ) - '{id,collection,datetime,bbox,intersects}'::text[]; END IF; -RAISE NOTICE 'Op Query: %', ret; -return ret; +return j; END; $$ LANGUAGE PLPGSQL; -CREATE OR REPLACE FUNCTION stac_query(_query jsonb) RETURNS TEXT[] AS $$ + +CREATE OR REPLACE FUNCTION query_to_cqlfilter(j jsonb) RETURNS jsonb AS $$ +-- Translates anything passed in through the deprecated "query" into equivalent CQL +WITH t AS ( + SELECT key as property, value as ops + FROM jsonb_each(j->'query') +), t2 AS ( + SELECT property, (jsonb_each(ops)).* + FROM t WHERE jsonb_typeof(ops) = 'object' + UNION ALL + SELECT property, 'eq', ops + FROM t WHERE jsonb_typeof(ops) != 'object' +), t3 AS ( +SELECT + jsonb_strip_nulls(jsonb_build_object( + 'and', + jsonb_agg( + jsonb_build_object( + key, + jsonb_build_array( + jsonb_build_object('property',property), + value + ) + ) + ) + )) as qcql FROM t2 +) +SELECT + CASE WHEN qcql IS NOT NULL THEN + jsonb_set(j, '{filter}', cql_and_append(j, qcql)) - 'query' + ELSE j + END +FROM t3 +; +$$ LANGUAGE SQL; + + + +CREATE OR REPLACE FUNCTION temporal_op_query(op text, args jsonb) RETURNS text AS $$ DECLARE -qa text[]; -att text; -ops jsonb; -op text; -val jsonb; +ll text := 'datetime'; +lh text := 'end_datetime'; +rrange tstzrange; +rl text; +rh text; +outq text; BEGIN -FOR att, ops IN SELECT key, value FROM jsonb_each(_query) -LOOP - FOR op, val IN SELECT key, value FROM jsonb_each(ops) - LOOP - qa := array_append(qa, stac_query_op(att,op, val)); - RAISE NOTICE '% % %', att, op, val; - END LOOP; -END LOOP; -RETURN qa; +rrange := parse_dtrange(args->1); +RAISE NOTICE 'Constructing temporal query OP: %, ARGS: %, RRANGE: %', op, args, rrange; +op := lower(op); +rl := format('%L::timestamptz', lower(rrange)); +rh := format('%L::timestamptz', upper(rrange)); +outq := CASE op + WHEN 't_before' THEN 'lh < rl' + WHEN 't_after' THEN 'll > rh' + WHEN 't_meets' THEN 'lh = rl' + WHEN 't_metby' THEN 'll = rh' + WHEN 't_overlaps' THEN 'll < rl AND rl < lh < rh' + WHEN 't_overlappedby' THEN 'rl < ll < rh AND lh > rh' + WHEN 't_starts' THEN 'll = rl AND lh < rh' + WHEN 't_startedby' THEN 'll = rl AND lh > rh' + WHEN 't_during' THEN 'll > rl AND lh < rh' + WHEN 't_contains' THEN 'll < rl AND lh > rh' + WHEN 't_finishes' THEN 'll > rl AND lh = rh' + WHEN 't_finishedby' THEN 'll < rl AND lh = rh' + WHEN 't_equals' THEN 'll = rl AND lh = rh' + WHEN 't_disjoint' THEN 'NOT (ll <= rh AND lh >= rl)' + WHEN 't_intersects' THEN 'll <= rh AND lh >= rl' + WHEN 'anyinteracts' THEN 'll <= rh AND lh >= rl' +END; +outq := regexp_replace(outq, '\mll\M', ll); +outq := regexp_replace(outq, '\mlh\M', lh); +outq := regexp_replace(outq, '\mrl\M', rl); +outq := regexp_replace(outq, '\mrh\M', rh); +outq := format('(%s)', outq); +RETURN outq; END; $$ LANGUAGE PLPGSQL; -CREATE OR REPLACE FUNCTION filter_by_order(item_id text, _sort jsonb, _type text) RETURNS text AS $$ +CREATE OR REPLACE FUNCTION spatial_op_query(op text, args jsonb) RETURNS text AS $$ DECLARE -item item; +geom text; +j jsonb := args->1; BEGIN -SELECT * INTO item FROM items WHERE id=item_id; -RETURN filter_by_order(item, _sort, _type); +op := lower(op); +RAISE NOTICE 'Constructing spatial query OP: %, ARGS: %', op, args; +IF op NOT IN ('s_equals','s_disjoint','s_touches','s_within','s_overlaps','s_crosses','s_intersects','intersects','s_contains') THEN + RAISE EXCEPTION 'Spatial Operator % Not Supported', op; +END IF; +op := regexp_replace(op, '^s_', 'st_'); +IF op = 'intersects' THEN + op := 'st_intersects'; +END IF; +-- Convert geometry to WKB string +IF j ? 'type' AND j ? 'coordinates' THEN + geom := st_geomfromgeojson(j)::text; +ELSIF jsonb_typeof(j) = 'array' THEN + geom := bbox_geom(j)::text; +END IF; + +RETURN format('%s(geometry, %L::geometry)', op, geom); END; -$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; +$$ LANGUAGE PLPGSQL; --- Used to create filters used for paging using the items id from the token -CREATE OR REPLACE FUNCTION filter_by_order(_item item, _sort jsonb, _type text) RETURNS text AS $$ + +/* cql_query_op -- Parses a CQL query operation, recursing when necessary + IN jsonb -- a subelement from a valid stac query + IN text -- the operator being used on elements passed in + RETURNS a SQL fragment to be used in a WHERE clause +*/ +CREATE OR REPLACE FUNCTION cql_query_op(j jsonb, _op text DEFAULT NULL) RETURNS text AS $$ DECLARE -sorts RECORD; -filts text[]; -itemval text; -op text; -idop text; +jtype text := jsonb_typeof(j); +op text := lower(_op); +ops jsonb := + '{ + "eq": "%s = %s", + "lt": "%s < %s", + "lte": "%s <= %s", + "gt": "%s > %s", + "gte": "%s >= %s", + "like": "%s LIKE %s", + "+": "%s + %s", + "-": "%s - %s", + "*": "%s * %s", + "/": "%s / %s", + "in": "%s = ANY (%s)", + "not": "NOT (%s)", + "between": "%s BETWEEN %s AND %s", + "lower":"lower(%s)" + }'::jsonb; ret text; -eq_flag text; -_item_j jsonb := to_jsonb(_item); +args text[] := NULL; + BEGIN -FOR sorts IN SELECT * FROM sort_base(_sort) LOOP - IF sorts.col = 'datetime' THEN - CONTINUE; +RAISE NOTICE 'j: %, op: %, jtype: %', j, op, jtype; + +-- Set Lower Case on Both Arguments When Case Insensitive Flag Set +IF op in ('eq','lt','lte','gt','gte','like') AND jsonb_typeof(j->2) = 'boolean' THEN + IF (j->>2)::boolean THEN + RETURN format(concat('(',ops->>op,')'), cql_query_op(jsonb_build_array(j->0), 'lower'), cql_query_op(jsonb_build_array(j->1), 'lower')); END IF; - IF sorts.col='id' AND _type IN ('prev','next') THEN - eq_flag := ''; - ELSE - eq_flag := '='; +END IF; + +-- Special Case when comparing a property in a jsonb field to a string or number using eq +-- Allows to leverage GIN index on jsonb fields +IF op = 'eq' THEN + IF j->0 ? 'property' + AND jsonb_typeof(j->1) IN ('number','string') + AND (items_path(j->0->>'property')).eq IS NOT NULL + THEN + RETURN format((items_path(j->0->>'property')).eq, j->1); END IF; +END IF; - op := concat( - CASE - WHEN _type in ('prev','first') AND sorts.dir = 'ASC' THEN '<' - WHEN _type in ('last','next') AND sorts.dir = 'ASC' THEN '>' - WHEN _type in ('prev','first') AND sorts.dir = 'DESC' THEN '>' - WHEN _type in ('last','next') AND sorts.dir = 'DESC' THEN '<' - END, - eq_flag - ); +IF op ilike 't_%' or op = 'anyinteracts' THEN + RETURN temporal_op_query(op, j); +END IF; - IF _item_j ? sorts.col THEN - filts = array_append(filts, format('%s %s %L', sorts.col, op, _item_j->>sorts.col)); +IF op ilike 's_%' or op = 'intersects' THEN + RETURN spatial_op_query(op, j); +END IF; + + +IF jtype = 'object' THEN + RAISE NOTICE 'parsing object'; + IF j ? 'property' THEN + -- Convert the property to be used as an identifier + return (items_path(j->>'property')).path_txt; + ELSIF _op IS NULL THEN + -- Iterate to convert elements in an object where the operator has not been set + -- Combining with AND + SELECT + array_to_string(array_agg(cql_query_op(e.value, e.key)), ' AND ') + INTO ret + FROM jsonb_each(j) e; + RETURN ret; END IF; -END LOOP; -ret := coalesce(array_to_string(filts,' AND '), 'TRUE'); -RAISE NOTICE 'Order Filter %', ret; -RETURN ret; +END IF; + +IF jtype = 'string' THEN + RETURN quote_literal(j->>0); +END IF; + +IF jtype ='number' THEN + RETURN (j->>0)::numeric; +END IF; + +IF jtype = 'array' AND op IS NULL THEN + RAISE NOTICE 'Parsing array into array arg. j: %', j; + SELECT format($f$ '{%s}'::text[] $f$, string_agg(e,',')) INTO ret FROM jsonb_array_elements_text(j) e; + RETURN ret; +END IF; + + +-- If the type of the passed json is an array +-- Calculate the arguments that will be passed to functions/operators +IF jtype = 'array' THEN + RAISE NOTICE 'Parsing array into args. j: %', j; + -- If any argument is numeric, cast any text arguments to numeric + IF j @? '$[*] ? (@.type() == "number")' THEN + SELECT INTO args + array_agg(concat('(',cql_query_op(e),')::numeric')) + FROM jsonb_array_elements(j) e; + ELSE + SELECT INTO args + array_agg(cql_query_op(e)) + FROM jsonb_array_elements(j) e; + END IF; + --RETURN args; +END IF; +RAISE NOTICE 'ARGS after array cleaning: %', args; + +IF op IS NULL THEN + RETURN args::text[]; +END IF; + +IF args IS NULL OR cardinality(args) < 1 THEN + RAISE NOTICE 'No Args'; + RETURN ''; +END IF; + +IF op IN ('and','or') THEN + SELECT + CONCAT( + '(', + array_to_string(args, UPPER(CONCAT(' ',op,' '))), + ')' + ) INTO ret + FROM jsonb_array_elements(j) e; + RETURN ret; +END IF; + +-- If the op is in the ops json then run using the template in the json +IF ops ? op THEN + RAISE NOTICE 'ARGS: % MAPPED: %',args, array_map_literal(args); + + RETURN format(concat('(',ops->>op,')'), VARIADIC args); +END IF; + +RETURN j->>0; + END; -$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; +$$ LANGUAGE PLPGSQL; + -CREATE OR REPLACE FUNCTION search_dtrange(IN _indate jsonb, OUT _tstzrange tstzrange) AS -$$ + + +CREATE OR REPLACE FUNCTION cql_to_where(_search jsonb = '{}'::jsonb) RETURNS text AS $$ +DECLARE +search jsonb := _search; +_where text; +BEGIN +RAISE NOTICE 'SEARCH CQL 1: %', search; + +-- Convert any old style stac query to cql +search := query_to_cqlfilter(search); + +RAISE NOTICE 'SEARCH CQL 2: %', search; + +-- Convert item,collection,datetime,bbox,intersects to cql +search := add_filters_to_cql(search); + +RAISE NOTICE 'SEARCH CQL Final: %', search; +_where := cql_query_op(search->'filter'); + +IF trim(_where) = '' THEN + _where := NULL; +END IF; +_where := coalesce(_where, ' TRUE '); +RETURN _where; +END; +$$ LANGUAGE PLPGSQL; + + +CREATE OR REPLACE FUNCTION parse_sort_dir(_dir text, reverse boolean default false) RETURNS text AS $$ WITH t AS ( - SELECT CASE - WHEN jsonb_typeof(_indate) = 'array' THEN - textarr(_indate) - ELSE - regexp_split_to_array( - btrim(_indate::text,'"'), - '/' - ) - END AS arr -) -, t1 AS ( - SELECT - CASE - WHEN array_upper(arr,1) = 1 OR arr[1] = '..' OR arr[1] IS NULL THEN '-infinity'::timestamptz - ELSE arr[1]::timestamptz - END AS st, - CASE - WHEN array_upper(arr,1) = 1 THEN arr[1]::timestamptz - WHEN arr[2] = '..' OR arr[2] IS NULL THEN 'infinity'::timestamptz - ELSE arr[2]::timestamptz - END AS et - FROM t -) -SELECT - tstzrange(st,et) -FROM t1; + SELECT COALESCE(upper(_dir), 'ASC') as d +) SELECT + CASE + WHEN NOT reverse THEN d + WHEN d = 'ASC' THEN 'DESC' + WHEN d = 'DESC' THEN 'ASC' + END +FROM t; $$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; -CREATE OR REPLACE FUNCTION flip_jsonb_array(j jsonb) RETURNS jsonb AS $$ +CREATE OR REPLACE FUNCTION sort_dir_to_op(_dir text, prev boolean default false) RETURNS text AS $$ WITH t AS ( - SELECT i, row_number() over () as r FROM jsonb_array_elements(j) i -), o AS ( - SELECT i FROM t ORDER BY r DESC + SELECT COALESCE(upper(_dir), 'ASC') as d +) SELECT + CASE + WHEN d = 'ASC' AND prev THEN '<=' + WHEN d = 'DESC' AND prev THEN '>=' + WHEN d = 'ASC' THEN '>=' + WHEN d = 'DESC' THEN '<=' + END +FROM t; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; + +CREATE OR REPLACE FUNCTION sort_sqlorderby( + _search jsonb DEFAULT NULL, + reverse boolean DEFAULT FALSE +) RETURNS text AS $$ +WITH sorts AS ( + SELECT + (items_path(value->>'field')).path as key, + parse_sort_dir(value->>'direction', reverse) as dir + FROM jsonb_array_elements( + '[]'::jsonb + || + coalesce(_search->'sort','[{"field":"datetime", "direction":"desc"}]') + || + '[{"field":"id","direction":"desc"}]'::jsonb + ) ) -SELECT jsonb_agg(i) from o -; +SELECT array_to_string( + array_agg(concat(key, ' ', dir)), + ', ' +) FROM sorts; +$$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION get_sort_dir(sort_item jsonb) RETURNS text AS $$ +SELECT CASE WHEN sort_item->>'direction' ILIKE 'desc%' THEN 'DESC' ELSE 'ASC' END; $$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; -CREATE OR REPLACE FUNCTION search(_search jsonb = '{}'::jsonb) RETURNS SETOF jsonb AS $$ +CREATE OR REPLACE FUNCTION get_token_filter(_search jsonb = '{}'::jsonb, token_rec jsonb DEFAULT NULL) RETURNS text AS $$ DECLARE -qstart timestamptz := clock_timestamp(); -_sort text := ''; -_rsort text := ''; -_limit int := 10; -_geom geometry; -qa text[]; -pq text[]; -query text; -pq_prop record; -pq_op record; -prev_id text := NULL; -next_id text := NULL; -whereq text := 'TRUE'; -links jsonb := '[]'::jsonb; -token text; -tok_val text; -tok_q text := 'TRUE'; -tok_sort text; -first_id text; -first_dt timestamptz; -last_id text; -sort text; -rsort text; -dt text[]; -dqa text[]; -dq text; -mq_where text; -startdt timestamptz; -enddt timestamptz; -item items%ROWTYPE; -counter int := 0; -batchcount int; -month timestamptz; -m record; -_dtrange tstzrange := tstzrange('-infinity','infinity'); -_dtsort text; -_token_dtrange tstzrange := tstzrange('-infinity','infinity'); -_token_record items%ROWTYPE; -is_prev boolean := false; -includes text[]; -excludes text[]; +token_id text; +filters text[] := '{}'::text[]; +prev boolean := TRUE; +field text; +dir text; +sort record; +orfilters text[] := '{}'::text[]; +andfilters text[] := '{}'::text[]; +output text; +token_where text; BEGIN --- Create table from sort query of items to sort -CREATE TEMP TABLE pgstac_tmp_sorts ON COMMIT DROP AS SELECT * FROM sort_base(_search->'sortby'); - --- Get the datetime sort direction, necessary for efficient cycling through partitions -SELECT INTO _dtsort dir FROM pgstac_tmp_sorts WHERE key='datetime'; -RAISE NOTICE '_dtsort: %',_dtsort; +-- If no token provided return NULL +IF token_rec IS NULL THEN + IF NOT (_search ? 'token' AND + ( + (_search->>'token' ILIKE 'prev:%') + OR + (_search->>'token' ILIKE 'next:%') + ) + ) THEN + RETURN NULL; + END IF; + prev := (_search->>'token' ILIKE 'prev:%'); + token_id := substr(_search->>'token', 6); + SELECT to_jsonb(items) INTO token_rec FROM items WHERE id=token_id; +END IF; +RAISE NOTICE 'TOKEN ID: %', token_rec->'id'; -SELECT INTO _sort string_agg(s.sort,', ') FROM pgstac_tmp_sorts s; -SELECT INTO _rsort string_agg(s.rsort,', ') FROM pgstac_tmp_sorts s; -tok_sort := _sort; +CREATE TEMP TABLE sorts ( + _row int GENERATED ALWAYS AS IDENTITY NOT NULL, + _field text PRIMARY KEY, + _dir text NOT NULL, + _val text +) ON COMMIT DROP; +-- Make sure we only have distinct columns to sort with taking the first one we get +INSERT INTO sorts (_field, _dir) + SELECT + (items_path(value->>'field')).path, + get_sort_dir(value) + FROM + jsonb_array_elements(coalesce(_search->'sort','[{"field":"datetime","direction":"desc"}]')) +ON CONFLICT DO NOTHING +; --- Get datetime from query as a tstzrange -IF _search ? 'datetime' THEN - _dtrange := search_dtrange(_search->'datetime'); - _token_dtrange := _dtrange; +-- Get the first sort direction provided. As the id is a primary key, if there are any +-- sorts after id they won't do anything, so make sure that id is the last sort item. +SELECT _dir INTO dir FROM sorts ORDER BY _row ASC LIMIT 1; +IF EXISTS (SELECT 1 FROM sorts WHERE _field = 'id') THEN + DELETE FROM sorts WHERE _row > (SELECT _row FROM sorts WHERE _field = 'id'); +ELSE + INSERT INTO sorts (_field, _dir) VALUES ('id', dir); END IF; --- Get the paging token -IF _search ? 'token' THEN - token := _search->>'token'; - tok_val := substr(token,6); - IF starts_with(token, 'prev:') THEN - is_prev := true; - END IF; - SELECT INTO _token_record * FROM items WHERE id=tok_val; - IF - (is_prev AND _dtsort = 'DESC') - OR - (not is_prev AND _dtsort = 'ASC') - THEN - _token_dtrange := _dtrange * tstzrange(_token_record.datetime, 'infinity'); - ELSIF - _dtsort IS NOT NULL - THEN - _token_dtrange := _dtrange * tstzrange('-infinity',_token_record.datetime); - END IF; - IF is_prev THEN - tok_q := filter_by_order(tok_val, _search->'sortby', 'first'); - _sort := _rsort; - ELSIF starts_with(token, 'next:') THEN - tok_q := filter_by_order(tok_val, _search->'sortby', 'last'); - END IF; +-- Add value from looked up item to the sorts table +UPDATE sorts SET _val=quote_literal(token_rec->>_field); + +-- Check if all sorts are the same direction and use row comparison +-- to filter +IF (SELECT count(DISTINCT _dir) FROM sorts) = 1 THEN + SELECT format( + '(%s) %s (%s)', + concat_ws(', ', VARIADIC array_agg(quote_ident(_field))), + CASE WHEN (prev AND dir = 'ASC') OR (NOT prev AND dir = 'DESC') THEN '<' ELSE '>' END, + concat_ws(', ', VARIADIC array_agg(_val)) + ) INTO output FROM sorts + WHERE token_rec ? _field + ; +ELSE + FOR sort IN SELECT * FROM sorts ORDER BY _row asc LOOP + RAISE NOTICE 'SORT: %', sort; + IF sort._row = 1 THEN + orfilters := orfilters || format('(%s %s %s)', + quote_ident(sort._field), + CASE WHEN (prev AND sort._dir = 'ASC') OR (NOT prev AND sort._dir = 'DESC') THEN '<' ELSE '>' END, + sort._val + ); + ELSE + orfilters := orfilters || format('(%s AND %s %s %s)', + array_to_string(andfilters, ' AND '), + quote_ident(sort._field), + CASE WHEN (prev AND sort._dir = 'ASC') OR (NOT prev AND sort._dir = 'DESC') THEN '<' ELSE '>' END, + sort._val + ); + + END IF; + andfilters := andfilters || format('%s = %s', + quote_ident(sort._field), + sort._val + ); + END LOOP; + output := array_to_string(orfilters, ' OR '); END IF; -RAISE NOTICE 'timing: %', age(clock_timestamp(), qstart); -RAISE NOTICE 'tok_q: % _token_dtrange: %', tok_q, _token_dtrange; +DROP TABLE IF EXISTS sorts; +token_where := concat('(',coalesce(output,'true'),')'); +IF trim(token_where) = '' THEN + token_where := NULL; +END IF; +RAISE NOTICE 'TOKEN_WHERE: |%|',token_where; +RETURN token_where; +END; +$$ LANGUAGE PLPGSQL; -IF _search ? 'ids' THEN - RAISE NOTICE 'searching solely based on ids... %',_search; - qa := array_append(qa, in_array_q('id', _search->'ids')); -ELSE - IF _search ? 'intersects' THEN - _geom := ST_SetSRID(ST_GeomFromGeoJSON(_search->>'intersects'), 4326); - ELSIF _search ? 'bbox' THEN - _geom := bbox_geom(_search->'bbox'); - END IF; +CREATE OR REPLACE FUNCTION search_tohash(jsonb) RETURNS jsonb AS $$ + SELECT $1 - '{token,limit,context,includes,excludes}'::text[]; +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; - IF _geom IS NOT NULL THEN - qa := array_append(qa, format('st_intersects(geometry, %L::geometry)',_geom)); - END IF; +CREATE OR REPLACE FUNCTION search_hash(jsonb) RETURNS text AS $$ + SELECT md5(search_tohash($1)::text); +$$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE; - IF _search ? 'collections' THEN - qa := array_append(qa, in_array_q('collection_id', _search->'collections')); - END IF; - IF _search ? 'query' THEN - qa := array_cat(qa, - stac_query(_search->'query') - ); - END IF; +CREATE TABLE IF NOT EXISTS searches( + hash text GENERATED ALWAYS AS (search_hash(search)) STORED PRIMARY KEY, + search jsonb NOT NULL, + _where text, + orderby text, + lastused timestamptz DEFAULT now(), + usecount bigint DEFAULT 0, + statslastupdated timestamptz, + estimated_count bigint, + total_count bigint +); + +CREATE OR REPLACE FUNCTION search_query(_search jsonb = '{}'::jsonb, updatestats boolean DEFAULT false) RETURNS searches AS $$ +DECLARE + search searches%ROWTYPE; +BEGIN +INSERT INTO searches (search) + VALUES (search_tohash(_search)) + ON CONFLICT DO NOTHING + RETURNING * INTO search; +IF search.hash IS NULL THEN + SELECT * INTO search FROM searches WHERE hash=search_hash(_search); +END IF; +IF search._where IS NULL THEN + search._where := cql_to_where(_search); +END IF; +IF search.orderby IS NULL THEN + search.orderby := sort_sqlorderby(_search); END IF; -IF _search ? 'limit' THEN - _limit := (_search->>'limit')::int; +IF search.statslastupdated IS NULL OR age(search.statslastupdated) > '1 day'::interval OR (_search ? 'context' AND search.total_count IS NULL) THEN + updatestats := TRUE; END IF; -IF _search ? 'fields' THEN - IF _search->'fields' ? 'exclude' THEN - excludes=textarr(_search->'fields'->'exclude'); - END IF; - IF _search->'fields' ? 'include' THEN - includes=textarr(_search->'fields'->'include'); - IF array_length(includes, 1)>0 AND NOT 'id' = ANY (includes) THEN - includes = includes || '{id}'; - END IF; +IF updatestats THEN + -- Get Estimated Stats + RAISE NOTICE 'Getting stats for %', search._where; + search.estimated_count := estimated_count(search._where); + RAISE NOTICE 'Estimated Count: %', search.estimated_count; + + IF _search ? 'context' OR search.estimated_count < 10000 THEN + --search.total_count := partition_count(search._where); + EXECUTE format( + 'SELECT count(*) FROM items WHERE %s', + search._where + ) INTO search.total_count; + RAISE NOTICE 'Actual Count: %', search.total_count; + ELSE + search.total_count := NULL; END IF; - RAISE NOTICE 'Includes: %, Excludes: %', includes, excludes; + search.statslastupdated := now(); END IF; -whereq := COALESCE(array_to_string(qa,' AND '),' TRUE '); -dq := COALESCE(array_to_string(dqa,' AND '),' TRUE '); -RAISE NOTICE 'timing before temp table: %', age(clock_timestamp(), qstart); +search.lastused := now(); +search.usecount := coalesce(search.usecount,0) + 1; +RAISE NOTICE 'SEARCH: %', search; +UPDATE searches SET + _where = search._where, + orderby = search.orderby, + lastused = search.lastused, + usecount = search.usecount, + statslastupdated = search.statslastupdated, + estimated_count = search.estimated_count, + total_count = search.total_count +WHERE hash = search.hash +; +RETURN search; -CREATE TEMP TABLE results_page ON COMMIT DROP AS -SELECT * FROM items_by_partition( - concat(whereq, ' AND ', tok_q), - _token_dtrange, - _sort, - _limit + 1 -); -RAISE NOTICE 'timing after temp table: %', age(clock_timestamp(), qstart); +END; +$$ LANGUAGE PLPGSQL; -RAISE NOTICE 'timing before min/max: %', age(clock_timestamp(), qstart); -IF is_prev THEN - SELECT INTO last_id, first_id, counter - first_value(id) OVER (), - last_value(id) OVER (), - count(*) OVER () - FROM results_page; -ELSE - SELECT INTO first_id, last_id, counter - first_value(id) OVER (), - last_value(id) OVER (), - count(*) OVER () - FROM results_page; + +CREATE OR REPLACE FUNCTION search(_search jsonb = '{}'::jsonb) RETURNS jsonb AS $$ +DECLARE + searches searches%ROWTYPE; + _where text; + token_where text; + full_where text; + orderby text; + query text; + token_type text := substr(_search->>'token',1,4); + _limit int := coalesce((_search->>'limit')::int, 10); + curs refcursor; + cntr int := 0; + iter_record items%ROWTYPE; + first_record items%ROWTYPE; + last_record items%ROWTYPE; + out_records jsonb := '[]'::jsonb; + prev_query text; + next text; + prev_id text; + has_next boolean := false; + has_prev boolean := false; + prev text; + total_count bigint; + context jsonb; + collection jsonb; + includes text[]; + excludes text[]; + exit_flag boolean := FALSE; + batches int := 0; + timer timestamptz := clock_timestamp(); +BEGIN +searches := search_query(_search); +_where := searches._where; +orderby := searches.orderby; +total_count := coalesce(searches.total_count, searches.estimated_count); + + +IF token_type='prev' THEN + token_where := get_token_filter(_search, null::jsonb); + orderby := sort_sqlorderby(_search, TRUE); +END IF; +IF token_type='next' THEN + token_where := get_token_filter(_search, null::jsonb); END IF; -RAISE NOTICE 'firstid: %, lastid %', first_id, last_id; -RAISE NOTICE 'timing after min/max: %', age(clock_timestamp(), qstart); +full_where := concat_ws(' AND ', _where, token_where); +RAISE NOTICE 'FULL QUERY % %', full_where, clock_timestamp()-timer; +timer := clock_timestamp(); +FOR query IN SELECT partition_queries(full_where, orderby) LOOP + timer := clock_timestamp(); + query := format('%s LIMIT %L', query, _limit + 1); + RAISE NOTICE 'Partition Query: %', query; + batches := batches + 1; + curs = create_cursor(query); + LOOP + FETCH curs into iter_record; + EXIT WHEN NOT FOUND; + cntr := cntr + 1; + last_record := iter_record; + IF cntr = 1 THEN + first_record := last_record; + END IF; + IF cntr <= _limit THEN + out_records := out_records || last_record.content; + ELSIF cntr > _limit THEN + has_next := true; + exit_flag := true; + EXIT; + END IF; + END LOOP; + RAISE NOTICE 'Query took %', clock_timestamp()-timer; + timer := clock_timestamp(); + EXIT WHEN exit_flag; +END LOOP; +RAISE NOTICE 'Scanned through % partitions.', batches; -IF counter > _limit THEN - next_id := last_id; - RAISE NOTICE 'next_id: %', next_id; -ELSE - RAISE NOTICE 'No more next'; +-- Flip things around if this was the result of a prev token query +IF token_type='prev' THEN + out_records := flip_jsonb_array(out_records); + first_record := last_record; END IF; -IF tok_q = 'TRUE' THEN - RAISE NOTICE 'Not a paging query, no previous item'; -ELSE - RAISE NOTICE 'Getting previous item id'; - RAISE NOTICE 'timing: %', age(clock_timestamp(), qstart); - SELECT INTO _token_record * FROM items WHERE id=first_id; - IF - _dtsort = 'DESC' - THEN - _token_dtrange := _dtrange * tstzrange(_token_record.datetime, 'infinity'); - ELSE - _token_dtrange := _dtrange * tstzrange('-infinity',_token_record.datetime); - END IF; - RAISE NOTICE '% %', _token_dtrange, _dtrange; - SELECT id INTO prev_id FROM items_by_partition( - concat(whereq, ' AND ', filter_by_order(first_id, _search->'sortby', 'prev')), - _token_dtrange, - _rsort, - 1 +-- If this query has a token, see if there is data before the first record +IF _search ? 'token' THEN + prev_query := format( + 'SELECT 1 FROM items WHERE %s LIMIT 1', + concat_ws( + ' AND ', + _where, + trim(get_token_filter(_search, to_jsonb(first_record))) + ) ); - RAISE NOTICE 'timing: %', age(clock_timestamp(), qstart); + RAISE NOTICE 'Query to get previous record: % --- %', prev_query, first_record; + EXECUTE prev_query INTO has_prev; + IF FOUND and has_prev IS NOT NULL THEN + RAISE NOTICE 'Query results from prev query: %', has_prev; + has_prev := TRUE; + END IF; +END IF; +has_prev := COALESCE(has_prev, FALSE); - RAISE NOTICE 'prev_id: %', prev_id; +RAISE NOTICE 'token_type: %, has_next: %, has_prev: %', token_type, has_next, has_prev; +IF has_prev THEN + prev := out_records->0->>'id'; +END IF; +IF has_next OR token_type='prev' THEN + next := out_records->-1->>'id'; END IF; -RETURN QUERY -WITH features AS ( - SELECT filter_jsonb(content, includes, excludes) as content - FROM results_page LIMIT _limit -), -j AS (SELECT jsonb_agg(content) as feature_arr FROM features) -SELECT jsonb_build_object( - 'type', 'FeatureCollection', - 'features', coalesce ( - CASE WHEN is_prev THEN flip_jsonb_array(feature_arr) ELSE feature_arr END - ,'[]'::jsonb), - 'links', links, - 'timeStamp', now(), - 'next', next_id, - 'prev', prev_id -) -FROM j -; +-- include/exclude any fields following fields extension +IF _search ? 'fields' THEN + IF _search->'fields' ? 'exclude' THEN + excludes=textarr(_search->'fields'->'exclude'); + END IF; + IF _search->'fields' ? 'include' THEN + includes=textarr(_search->'fields'->'include'); + IF array_length(includes, 1)>0 AND NOT 'id' = ANY (includes) THEN + includes = includes || '{id}'; + END IF; + END IF; + SELECT jsonb_agg(filter_jsonb(row, includes, excludes)) INTO out_records FROM jsonb_array_elements(out_records) row; +END IF; + + +context := jsonb_strip_nulls(jsonb_build_object( + 'limit', _limit, + 'matched', total_count, + 'returned', coalesce(jsonb_array_length(out_records), 0) +)); + +collection := jsonb_build_object( + 'type', 'FeatureCollection', + 'features', out_records, + 'next', next, + 'prev', prev, + 'context', context +); +RETURN collection; END; -$$ LANGUAGE PLPGSQL SET SEARCH_PATH TO pgstac,public; +$$ LANGUAGE PLPGSQL SET jit TO off; diff --git a/sql/999_version.sql b/sql/999_version.sql index ed324491..f04e59fc 100644 --- a/sql/999_version.sql +++ b/sql/999_version.sql @@ -1 +1 @@ -INSERT INTO pgstac.migrations (version) VALUES ('0.2.9'); +INSERT INTO pgstac.migrations (version) VALUES ('0.3.0'); diff --git a/test/pgtap.sql b/test/pgtap.sql index 466f6937..46f4e286 100644 --- a/test/pgtap.sql +++ b/test/pgtap.sql @@ -16,124 +16,23 @@ BEGIN; CREATE EXTENSION IF NOT EXISTS pgtap; SET SEARCH_PATH TO pgstac, pgtap, public; +SET CLIENT_MIN_MESSAGES TO 'warning'; -- Plan the tests. -SELECT plan(62); +SELECT plan(70); --SELECT * FROM no_plan(); -- Run the tests. -- Core - --- Check that schema exists -SELECT has_schema('pgstac'::name); - --- Check that PostGIS and PG_Partman extensions are installed and available on the path -SELECT has_extension('postgis'); -SELECT has_extension('pg_partman'); - -SELECT has_table('pgstac'::name, 'migrations'::name); - - -SELECT has_function('pgstac'::name, 'textarr', ARRAY['jsonb']); -SELECT results_eq( - $$ SELECT textarr('["a","b","c"]'::jsonb) $$, - $$ SELECT '{a,b,c}'::text[] $$, - 'textarr returns text[] from jsonb array' -); - -SELECT has_function('pgstac'::name, 'array_idents', ARRAY['jsonb']); -SELECT results_eq( - $$ SELECT array_idents('["a","b","c"]'::jsonb) $$, - $$ SELECT 'a,b,c' $$, - 'array_idents returns csv double quoted from jsonb array' -); - -SELECT has_function('pgstac'::name, 'properties_idx', ARRAY['jsonb']); -SELECT results_eq( - $$ SELECT properties_idx('{"a":1,"b":"B","c":[1,2]}'::jsonb) $$, - $$ SELECT '{"a":1,"b":"b"}'::jsonb $$, - 'properties_idx returns slimmed lower case jsonb' -); - -SELECT has_function('pgstac'::name, 'stac_geom', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'stac_datetime', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'jsonb_paths', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'jsonb_obj_paths', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'jsonb_val_paths', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'path_includes', ARRAY['text[]','text[]']); -SELECT has_function('pgstac'::name, 'path_excludes', ARRAY['text[]','text[]']); -SELECT has_function('pgstac'::name, 'jsonb_obj_paths_filtered', ARRAY['jsonb','text[]','text[]']); -SELECT has_function('pgstac'::name, 'empty_arr', ARRAY['anyarray']); -SELECT has_function('pgstac'::name, 'filter_jsonb', ARRAY['jsonb','text[]','text[]']); - - --- Collections -SELECT has_table('pgstac'::name, 'collections'::name); -SELECT col_is_pk('pgstac'::name, 'collections'::name, 'id', 'collections has primary key'); - -SELECT has_function('pgstac'::name, 'create_collection', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'update_collection', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'upsert_collection', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'get_collection', ARRAY['text']); -SELECT has_function('pgstac'::name, 'delete_collection', ARRAY['text']); -SELECT has_function('pgstac'::name, 'all_collections', NULL); - - - - - --- Items -SELECT has_table('pgstac'::name, 'items'::name); - -SELECT is_indexed('pgstac'::name, 'items'::name, ARRAY['datetime','id']); -SELECT is_indexed('pgstac'::name, 'items'::name, 'properties'); -SELECT is_indexed('pgstac'::name, 'items'::name, 'geometry'); -SELECT is_indexed('pgstac'::name, 'items'::name, 'collection_id'); - -SELECT has_type('pgstac'::name, 'item'::name); -SELECT is_partitioned('pgstac'::name,'items'::name); - - -SELECT has_function('pgstac'::name, 'get_item', ARRAY['text']); -SELECT has_function('pgstac'::name, 'delete_item', ARRAY['text']); -SELECT has_function('pgstac'::name, 'create_item', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'update_item', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'upsert_item', ARRAY['jsonb']); - - - -SELECT has_function('pgstac'::name, 'analyze_empty_partitions', NULL); -SELECT has_function('pgstac'::name, 'backfill_partitions', NULL); -SELECT has_function('pgstac'::name, 'items_trigger_stmt_func', NULL); - - -SELECT has_view('pgstac'::name, 'all_items_partitions'::name, 'all_items_partitions view exists'); -SELECT has_view('pgstac'::name, 'items_partitions'::name, 'items_partitions view exists'); - --- tools to update collection extents based on extents in items -SELECT has_function('pgstac'::name, 'collection_bbox', ARRAY['text']); -SELECT has_function('pgstac'::name, 'collection_temporal_extent', ARRAY['text']); -SELECT has_function('pgstac'::name, 'update_collection_extents', NULL); - - - --- Search - -SELECT has_function('pgstac'::name, 'items_by_partition', ARRAY['text','tstzrange','text','int']); -SELECT has_function('pgstac'::name, 'split_stac_path', ARRAY['text']); -SELECT has_function('pgstac'::name, 'sort_base', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'sort', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'rsort', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'bbox_geom', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'in_array_q', ARRAY['text','jsonb']); -SELECT has_function('pgstac'::name, 'count_by_delim', ARRAY['text','text']); -SELECT has_function('pgstac'::name, 'stac_query_op', ARRAY['text','text','jsonb']); -SELECT has_function('pgstac'::name, 'stac_query', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'filter_by_order', ARRAY['text','jsonb','text']); -SELECT has_function('pgstac'::name, 'filter_by_order', ARRAY['item','jsonb','text']); -SELECT has_function('pgstac'::name, 'search_dtrange', ARRAY['jsonb']); -SELECT has_function('pgstac'::name, 'search', ARRAY['jsonb']); +\i test//pgtap/001_core.sql +\i test/pgtap/001a_jsonutils.sql +\i test/pgtap/001b_cursorutils.sql +\i test/pgtap/001s_stacutils.sql +\i test/pgtap/002_collections.sql +\i test/pgtap/003_items.sql +\i test/pgtap/004_search.sql +\i test/pgtap/999_version.sql -- Finish the tests and clean up. SELECT * FROM finish(); diff --git a/test/pgtap/001_core.sql b/test/pgtap/001_core.sql new file mode 100644 index 00000000..e063a019 --- /dev/null +++ b/test/pgtap/001_core.sql @@ -0,0 +1,18 @@ +-- Check that schema exists +SELECT has_schema('pgstac'::name); + +-- Check that PostGIS extension are installed and available on the path +SELECT has_extension('postgis'); + +SELECT has_table('pgstac'::name, 'migrations'::name); + + +SELECT has_function('pgstac'::name, 'textarr', ARRAY['jsonb']); +SELECT results_eq( + $$ SELECT textarr('["a","b","c"]'::jsonb) $$, + $$ SELECT '{a,b,c}'::text[] $$, + 'textarr returns text[] from jsonb array' +); + + +SELECT has_function('pgstac'::name, 'estimated_count', ARRAY['text']); diff --git a/test/pgtap/001a_jsonutils.sql b/test/pgtap/001a_jsonutils.sql new file mode 100644 index 00000000..280bb79b --- /dev/null +++ b/test/pgtap/001a_jsonutils.sql @@ -0,0 +1,26 @@ +SELECT has_function('pgstac'::name, 'textarr', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'jsonb_paths', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'jsonb_obj_paths', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'jsonb_val_paths', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'path_includes', ARRAY['text[]', 'text[]']); +SELECT has_function('pgstac'::name, 'path_excludes', ARRAY['text[]', 'text[]']); +SELECT has_function('pgstac'::name, 'jsonb_obj_paths_filtered', ARRAY['jsonb','text[]','text[]']); +SELECT has_function('pgstac'::name, 'filter_jsonb', ARRAY['jsonb','text[]','text[]']); + + +SELECT results_eq( + $$ SELECT textarr('["a","b","c"]'::jsonb) $$, + $$ SELECT '{a,b,c}'::text[] $$, + 'textarr returns text[] from jsonb array' +); + +SELECT results_eq( + $$ SELECT filter_jsonb('{"a":1,"b":2,"c":3}'::jsonb, includes=>'{a,c}') $$, + $$ SELECT '{"a":1,"c":3}'::jsonb $$, + 'filter_jsonb includes work' +); +SELECT results_eq( + $$ SELECT filter_jsonb('{"a":1,"b":2,"c":3}'::jsonb, includes=>NULL, excludes=>'{a,c}') $$, + $$ SELECT '{"b":2}'::jsonb $$, + 'filter_jsonb excludes work' +); diff --git a/test/pgtap/001b_cursorutils.sql b/test/pgtap/001b_cursorutils.sql new file mode 100644 index 00000000..c94a4fc5 --- /dev/null +++ b/test/pgtap/001b_cursorutils.sql @@ -0,0 +1,5 @@ +--create_cursor +SELECT has_function('pgstac'::name, 'create_cursor', ARRAY['text']); + +--partition_cursor +SELECT has_function('pgstac'::name, 'partition_cursor', ARRAY['text', 'text']); diff --git a/test/pgtap/001s_stacutils.sql b/test/pgtap/001s_stacutils.sql new file mode 100644 index 00000000..98e6287a --- /dev/null +++ b/test/pgtap/001s_stacutils.sql @@ -0,0 +1,5 @@ +SELECT has_function('pgstac'::name, 'stac_geom', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'stac_datetime', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'stac_end_datetime', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'stac_daterange', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'properties_idx', ARRAY['jsonb']); diff --git a/test/pgtap/002_collections.sql b/test/pgtap/002_collections.sql new file mode 100644 index 00000000..9feebce3 --- /dev/null +++ b/test/pgtap/002_collections.sql @@ -0,0 +1,9 @@ +SELECT has_table('pgstac'::name, 'collections'::name); +SELECT col_is_pk('pgstac'::name, 'collections'::name, 'id', 'collections has primary key'); + +SELECT has_function('pgstac'::name, 'create_collection', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'update_collection', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'upsert_collection', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'get_collection', ARRAY['text']); +SELECT has_function('pgstac'::name, 'delete_collection', ARRAY['text']); +SELECT has_function('pgstac'::name, 'all_collections', NULL); diff --git a/test/pgtap/003_items.sql b/test/pgtap/003_items.sql new file mode 100644 index 00000000..622e0443 --- /dev/null +++ b/test/pgtap/003_items.sql @@ -0,0 +1,31 @@ +SELECT has_table('pgstac'::name, 'items'::name); + +-- SELECT is_indexed('pgstac'::name, 'items'::name, ARRAY['datetime','id']); +-- SELECT is_indexed('pgstac'::name, 'items'::name, 'properties'); +SELECT is_indexed('pgstac'::name, 'items'::name, 'geometry'); +SELECT is_indexed('pgstac'::name, 'items'::name, 'collection_id'); + +-- SELECT has_type('pgstac'::name, 'item'::name); +SELECT is_partitioned('pgstac'::name,'items'::name); + + +SELECT has_function('pgstac'::name, 'get_item', ARRAY['text']); +SELECT has_function('pgstac'::name, 'delete_item', ARRAY['text']); +SELECT has_function('pgstac'::name, 'create_item', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'update_item', ARRAY['jsonb']); +SELECT has_function('pgstac'::name, 'upsert_item', ARRAY['jsonb']); + + + +SELECT has_function('pgstac'::name, 'analyze_empty_partitions', NULL); +-- SELECT has_function('pgstac'::name, 'backfill_partitions', NULL); +-- SELECT has_function('pgstac'::name, 'items_trigger_stmt_func', NULL); + + +SELECT has_view('pgstac'::name, 'all_items_partitions'::name, 'all_items_partitions view exists'); +SELECT has_view('pgstac'::name, 'items_partitions'::name, 'items_partitions view exists'); + +-- tools to update collection extents based on extents in items +SELECT has_function('pgstac'::name, 'collection_bbox', ARRAY['text']); +SELECT has_function('pgstac'::name, 'collection_temporal_extent', ARRAY['text']); +SELECT has_function('pgstac'::name, 'update_collection_extents', NULL); diff --git a/test/pgtap/004_search.sql b/test/pgtap/004_search.sql new file mode 100644 index 00000000..517e1a46 --- /dev/null +++ b/test/pgtap/004_search.sql @@ -0,0 +1,148 @@ +-- CREATE fixtures for testing search - as tests are run within a transaction, these will not persist +DELETE FROM collections WHERE id = 'pgstac-test-collection'; +\copy collections (content) FROM 'test/testdata/collections.ndjson' +\copy items_staging (content) FROM 'test/testdata/items.ndjson' + + +SELECT has_function('pgstac'::name, 'parse_dtrange', ARRAY['jsonb']); + + +SELECT results_eq($$ SELECT parse_dtrange('["2020-01-01","2021-01-01"]') $$, $$ SELECT '["2020-01-01 00:00:00+00","2021-01-01 00:00:00+00")'::tstzrange $$, 'daterange passed as array range'); + + +SELECT results_eq($$ SELECT parse_dtrange('"2020-01-01/2021-01-01"') $$, $$ SELECT '["2020-01-01 00:00:00+00","2021-01-01 00:00:00+00")'::tstzrange $$, 'date range passed as string range'); + + +SELECT has_function('pgstac'::name, 'bbox_geom', ARRAY['jsonb']); + + +SELECT results_eq($$ SELECT bbox_geom('[0,1,2,3]') $$, $$ SELECT 'SRID=4326;POLYGON((0 1,0 3,2 3,2 1,0 1))'::geometry $$, '2d bbox'); + + +SELECT results_eq($$ SELECT bbox_geom('[0,1,2,3,4,5]'::jsonb) $$, $$ SELECT '010F0000A0E610000006000000010300008001000000050000000000000000000000000000000000F03F00000000000000400000000000000000000000000000104000000000000000400000000000000840000000000000104000000000000000400000000000000840000000000000F03F00000000000000400000000000000000000000000000F03F0000000000000040010300008001000000050000000000000000000000000000000000F03F00000000000014400000000000000840000000000000F03F00000000000014400000000000000840000000000000104000000000000014400000000000000000000000000000104000000000000014400000000000000000000000000000F03F0000000000001440010300008001000000050000000000000000000000000000000000F03F00000000000000400000000000000000000000000000F03F00000000000014400000000000000000000000000000104000000000000014400000000000000000000000000000104000000000000000400000000000000000000000000000F03F0000000000000040010300008001000000050000000000000000000840000000000000F03F00000000000000400000000000000840000000000000104000000000000000400000000000000840000000000000104000000000000014400000000000000840000000000000F03F00000000000014400000000000000840000000000000F03F0000000000000040010300008001000000050000000000000000000000000000000000F03F00000000000000400000000000000840000000000000F03F00000000000000400000000000000840000000000000F03F00000000000014400000000000000000000000000000F03F00000000000014400000000000000000000000000000F03F000000000000004001030000800100000005000000000000000000000000000000000010400000000000000040000000000000000000000000000010400000000000001440000000000000084000000000000010400000000000001440000000000000084000000000000010400000000000000040000000000000000000000000000010400000000000000040'::geometry $$, '3d bbox'); + + +SELECT has_function('pgstac'::name, 'add_filters_to_cql', ARRAY['jsonb']); + +SELECT results_eq($$ + SELECT add_filters_to_cql('{"id":["a","b"]}'::jsonb); + $$,$$ + SELECT '{"filter":{"and": [{"in": [{"property": "id"}, ["a", "b"]]}]}}'::jsonb; + $$, + 'Test that id gets added to cql filter when cql filter does not exist' +); + +SELECT results_eq($$ + SELECT add_filters_to_cql('{"id":["a","b"],"filter":{"and":[{"eq":[1,1]}]}}'::jsonb); + $$,$$ + SELECT '{"filter":{"and": [{"and": [{"eq": [1, 1]}]}, {"and": [{"in": [{"property": "id"}, ["a", "b"]]}]}]}}'::jsonb; + $$, + 'Test that id gets added to cql filter when cql filter does exist' +); + +SELECT has_function('pgstac'::name, 'cql_and_append', ARRAY['jsonb','jsonb']); + +SELECT has_function('pgstac'::name, 'query_to_cqlfilter', ARRAY['jsonb']); + +SELECT results_eq($$ + SELECT query_to_cqlfilter('{"query":{"a":{"gt":0,"lte":10},"b":"test"}}'); + $$,$$ + SELECT '{"filter":{"and": [{"gt": [{"property": "a"}, 0]}, {"lte": [{"property": "a"}, 10]}, {"eq": [{"property": "b"}, "test"]}]}}'::jsonb; + $$, + 'Test that query_to_cqlfilter appropriately converts old style query items to cql filters' +); + + +SELECT has_function('pgstac'::name, 'sort_sqlorderby', ARRAY['jsonb','boolean']); + +SELECT results_eq($$ + SELECT sort_sqlorderby('{"sort":[{"field":"datetime","direction":"desc"},{"field":"eo:cloudcover","direction":"asc"}]}'::jsonb); + $$,$$ + SELECT 'datetime DESC, properties->''eo:cloudcover'' ASC, id DESC'; + $$, + 'Test creation of sort sql' +); + + +SELECT results_eq($$ + SELECT sort_sqlorderby('{"sort":[{"field":"datetime","direction":"desc"},{"field":"eo:cloudcover","direction":"asc"}]}'::jsonb, true); + $$,$$ + SELECT 'datetime ASC, properties->''eo:cloudcover'' DESC, id ASC'; + $$, + 'Test creation of reverse sort sql' +); + +SELECT results_eq($$ + select s from search('{"fields":{"include":["id","datetime","eo:cloud_cover"]},"sort":[{"field":"datetime","direction":"desc"},{"field":"id","direction":"asc"}]}') s; + $$,$$ + select '{"next": "pgstac-test-item-0010", "prev": null, "type": "FeatureCollection", "context": {"limit": 10, "matched": 100, "returned": 10}, "features": [{"id": "pgstac-test-item-0001", "properties": {"datetime": "2011-08-25T00:00:00Z", "eo:cloud_cover": 89}}, {"id": "pgstac-test-item-0002", "properties": {"datetime": "2011-08-25T00:00:00Z", "eo:cloud_cover": 33}}, {"id": "pgstac-test-item-0003", "properties": {"datetime": "2011-08-25T00:00:00Z", "eo:cloud_cover": 28}}, {"id": "pgstac-test-item-0004", "properties": {"datetime": "2011-08-24T00:00:00Z", "eo:cloud_cover": 23}}, {"id": "pgstac-test-item-0005", "properties": {"datetime": "2011-08-24T00:00:00Z", "eo:cloud_cover": 3}}, {"id": "pgstac-test-item-0006", "properties": {"datetime": "2011-08-24T00:00:00Z", "eo:cloud_cover": 100}}, {"id": "pgstac-test-item-0007", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 59}}, {"id": "pgstac-test-item-0008", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 64}}, {"id": "pgstac-test-item-0009", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 61}}, {"id": "pgstac-test-item-0010", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 31}}]}'::jsonb + $$, + 'Test basic search with fields and sort extension' +); + +SELECT results_eq($$ + select s from search('{"token":"next:pgstac-test-item-0010", "fields":{"include":["id","datetime","eo:cloud_cover"]},"sort":[{"field":"datetime","direction":"desc"},{"field":"id","direction":"asc"}]}') s; + $$,$$ + select '{"next": "pgstac-test-item-0020", "prev": "pgstac-test-item-0011", "type": "FeatureCollection", "context": {"limit": 10, "matched": 100, "returned": 10}, "features": [{"id": "pgstac-test-item-0011", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 41}}, {"id": "pgstac-test-item-0012", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 4}}, {"id": "pgstac-test-item-0013", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 2}}, {"id": "pgstac-test-item-0014", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 17}}, {"id": "pgstac-test-item-0015", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 54}}, {"id": "pgstac-test-item-0016", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 13}}, {"id": "pgstac-test-item-0017", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 59}}, {"id": "pgstac-test-item-0018", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 29}}, {"id": "pgstac-test-item-0019", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 52}}, {"id": "pgstac-test-item-0020", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 39}}]}'::jsonb + $$, + 'Test basic search with fields and sort extension and next token' +); + +SELECT results_eq($$ + select s from search('{"token":"prev:pgstac-test-item-0011", "fields":{"include":["id","datetime","eo:cloud_cover"]},"sort":[{"field":"datetime","direction":"desc"},{"field":"id","direction":"asc"}]}') s; + $$,$$ -- should be the same result as the first base query + select '{"next": "pgstac-test-item-0010", "prev": null, "type": "FeatureCollection", "context": {"limit": 10, "matched": 100, "returned": 10}, "features": [{"id": "pgstac-test-item-0001", "properties": {"datetime": "2011-08-25T00:00:00Z", "eo:cloud_cover": 89}}, {"id": "pgstac-test-item-0002", "properties": {"datetime": "2011-08-25T00:00:00Z", "eo:cloud_cover": 33}}, {"id": "pgstac-test-item-0003", "properties": {"datetime": "2011-08-25T00:00:00Z", "eo:cloud_cover": 28}}, {"id": "pgstac-test-item-0004", "properties": {"datetime": "2011-08-24T00:00:00Z", "eo:cloud_cover": 23}}, {"id": "pgstac-test-item-0005", "properties": {"datetime": "2011-08-24T00:00:00Z", "eo:cloud_cover": 3}}, {"id": "pgstac-test-item-0006", "properties": {"datetime": "2011-08-24T00:00:00Z", "eo:cloud_cover": 100}}, {"id": "pgstac-test-item-0007", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 59}}, {"id": "pgstac-test-item-0008", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 64}}, {"id": "pgstac-test-item-0009", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 61}}, {"id": "pgstac-test-item-0010", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 31}}]}'::jsonb + $$, + 'Test basic search with fields and sort extension and prev token' +); + +SELECT results_eq($$ + select s from search('{"datetime":"2011-08-16T00:00:00Z/2011-08-17T00:00:00Z", "fields":{"include":["id","datetime","eo:cloud_cover"]},"sort":[{"field":"datetime","direction":"desc"},{"field":"id","direction":"asc"}]}') s; + $$,$$ + select '{"next": "pgstac-test-item-0016", "prev": null, "type": "FeatureCollection", "context": {"limit": 10, "matched": 57, "returned": 10}, "features": [{"id": "pgstac-test-item-0007", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 59}}, {"id": "pgstac-test-item-0008", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 64}}, {"id": "pgstac-test-item-0009", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 61}}, {"id": "pgstac-test-item-0010", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 31}}, {"id": "pgstac-test-item-0011", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 41}}, {"id": "pgstac-test-item-0012", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 4}}, {"id": "pgstac-test-item-0013", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 2}}, {"id": "pgstac-test-item-0014", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 17}}, {"id": "pgstac-test-item-0015", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 54}}, {"id": "pgstac-test-item-0016", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 13}}]}'::jsonb + $$, + 'Test datetime search with datetime as / separated string' +); + + +SELECT results_eq($$ + select s from search('{"datetime":["2011-08-16T00:00:00Z","2011-08-17T00:00:00Z"], "fields":{"include":["id","datetime","eo:cloud_cover"]},"sort":[{"field":"datetime","direction":"desc"},{"field":"id","direction":"asc"}]}') s; + $$,$$ + select '{"next": "pgstac-test-item-0016", "prev": null, "type": "FeatureCollection", "context": {"limit": 10, "matched": 57, "returned": 10}, "features": [{"id": "pgstac-test-item-0007", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 59}}, {"id": "pgstac-test-item-0008", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 64}}, {"id": "pgstac-test-item-0009", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 61}}, {"id": "pgstac-test-item-0010", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 31}}, {"id": "pgstac-test-item-0011", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 41}}, {"id": "pgstac-test-item-0012", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 4}}, {"id": "pgstac-test-item-0013", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 2}}, {"id": "pgstac-test-item-0014", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 17}}, {"id": "pgstac-test-item-0015", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 54}}, {"id": "pgstac-test-item-0016", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 13}}]}'::jsonb + $$, + 'Test datetime search with datetime as array' +); + +SELECT results_eq($$ + select s from search('{"filter":{"anyinteracts":[{"property":"datetime"},["2011-08-16T00:00:00Z","2011-08-17T00:00:00Z"]]}, "fields":{"include":["id","datetime","eo:cloud_cover"]},"sort":[{"field":"datetime","direction":"desc"},{"field":"id","direction":"asc"}]}') s; + $$,$$ + select '{"next": "pgstac-test-item-0016", "prev": null, "type": "FeatureCollection", "context": {"limit": 10, "matched": 57, "returned": 10}, "features": [{"id": "pgstac-test-item-0007", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 59}}, {"id": "pgstac-test-item-0008", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 64}}, {"id": "pgstac-test-item-0009", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 61}}, {"id": "pgstac-test-item-0010", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 31}}, {"id": "pgstac-test-item-0011", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 41}}, {"id": "pgstac-test-item-0012", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 4}}, {"id": "pgstac-test-item-0013", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 2}}, {"id": "pgstac-test-item-0014", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 17}}, {"id": "pgstac-test-item-0015", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 54}}, {"id": "pgstac-test-item-0016", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 13}}]}'::jsonb + $$, + 'Test datetime as an anyinteracts filter' +); + +SELECT results_eq($$ + select s from search('{"filter":{"eq":[{"property":"eo:cloud_cover"},36]}, "fields":{"include":["id","datetime","eo:cloud_cover"]},"sort":[{"field":"datetime","direction":"desc"},{"field":"id","direction":"asc"}]}') s; + $$,$$ + select '{"next": null, "prev": null, "type": "FeatureCollection", "context": {"limit": 10, "matched": 2, "returned": 2}, "features": [{"id": "pgstac-test-item-0087", "properties": {"datetime": "2011-08-01T00:00:00Z", "eo:cloud_cover": 36}}, {"id": "pgstac-test-item-0089", "properties": {"datetime": "2011-07-31T00:00:00Z", "eo:cloud_cover": 36}}]}'::jsonb + $$, + 'Test equality as a filter on a numeric field' +); + +SELECT results_eq($$ + select s from search('{"filter":{"lt":[{"property":"eo:cloud_cover"},25]}, "fields":{"include":["id","datetime","eo:cloud_cover"]},"sort":[{"field":"eo:cloud_cover","direction":"asc"}]}') s; + $$,$$ + select '{"next": "pgstac-test-item-0012", "prev": null, "type": "FeatureCollection", "context": {"limit": 10, "matched": 31, "returned": 10}, "features": [{"id": "pgstac-test-item-0097", "properties": {"datetime": "2011-07-31T00:00:00Z", "eo:cloud_cover": 1}}, {"id": "pgstac-test-item-0063", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 2}}, {"id": "pgstac-test-item-0013", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 2}}, {"id": "pgstac-test-item-0085", "properties": {"datetime": "2011-08-01T00:00:00Z", "eo:cloud_cover": 3}}, {"id": "pgstac-test-item-0073", "properties": {"datetime": "2011-08-15T00:00:00Z", "eo:cloud_cover": 3}}, {"id": "pgstac-test-item-0041", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 3}}, {"id": "pgstac-test-item-0034", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 3}}, {"id": "pgstac-test-item-0005", "properties": {"datetime": "2011-08-24T00:00:00Z", "eo:cloud_cover": 3}}, {"id": "pgstac-test-item-0048", "properties": {"datetime": "2011-08-16T00:00:00Z", "eo:cloud_cover": 4}}, {"id": "pgstac-test-item-0012", "properties": {"datetime": "2011-08-17T00:00:00Z", "eo:cloud_cover": 4}}]}'::jsonb + $$, + 'Test lt as a filter on a numeric field with order by' +); + +/* template +SELECT results_eq($$ + + $$,$$ + + $$, + 'Test that ...' +); +*/ diff --git a/test/pgtap/999_version.sql b/test/pgtap/999_version.sql new file mode 100644 index 00000000..e69de29b diff --git a/test/testdata/collections.ndjson b/test/testdata/collections.ndjson index 054b93f5..2219579c 100644 --- a/test/testdata/collections.ndjson +++ b/test/testdata/collections.ndjson @@ -1 +1 @@ -{"id":"usda-naip","stac_version":"1.0.0-beta.2","description":"The National Agriculture Imagery Program (NAIP) acquires aerial imagery\\nduring the agricultural growing seasons in the continental U.S.\\n\\nNAIP projects are contracted each year based upon available funding and the\\nFSA imagery acquisition cycle. Beginning in 2003, NAIP was acquired on\\na 5-year cycle. 2008 was a transition year, and a three-year cycle began\\nin 2009.\\n\\nNAIP imagery is acquired at a one-meter ground sample distance (GSD) with a\\nhorizontal accuracy that matches within six meters of photo-identifiable\\nground control points, which are used during image inspection.\\n\\nOlder images were collected using 3 bands (Red, Green, and Blue: RGB), but\\nnewer imagery is usually collected with an additional near-infrared band\\n(RGBN).","links":[{"rel":"root","href":"/collection.json","type":"application/json"},{"rel":"self","href":"/collection.json","type":"application/json"}],"stac_extensions":[],"title":"NAIP: National Agriculture Imagery Program","extent":{"spatial":{"bbox":[[-124.784,24.744,-66.951,49.346]]},"temporal":{"interval":[["2011-01-01T00:00:00Z","2019-01-01T00:00:00Z"]]}},"license":"PDDL-1.0","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}]} +{"id":"pgstac-test-collection","stac_version":"1.0.0-beta.2","description":"The National Agriculture Imagery Program (NAIP) acquires aerial imagery\\nduring the agricultural growing seasons in the continental U.S.\\n\\nNAIP projects are contracted each year based upon available funding and the\\nFSA imagery acquisition cycle. Beginning in 2003, NAIP was acquired on\\na 5-year cycle. 2008 was a transition year, and a three-year cycle began\\nin 2009.\\n\\nNAIP imagery is acquired at a one-meter ground sample distance (GSD) with a\\nhorizontal accuracy that matches within six meters of photo-identifiable\\nground control points, which are used during image inspection.\\n\\nOlder images were collected using 3 bands (Red, Green, and Blue: RGB), but\\nnewer imagery is usually collected with an additional near-infrared band\\n(RGBN).","links":[{"rel":"root","href":"/collection.json","type":"application/json"},{"rel":"self","href":"/collection.json","type":"application/json"}],"stac_extensions":[],"title":"NAIP: National Agriculture Imagery Program","extent":{"spatial":{"bbox":[[-124.784,24.744,-66.951,49.346]]},"temporal":{"interval":[["2011-01-01T00:00:00Z","2019-01-01T00:00:00Z"]]}},"license":"PDDL-1.0","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}]} diff --git a/test/testdata/items.ndjson b/test/testdata/items.ndjson index b98b90c3..ea5aa0c7 100644 --- a/test/testdata/items.ndjson +++ b/test/testdata/items.ndjson @@ -1,100 +1,100 @@ -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008501_ne_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7587,6638],"proj:bbox":[601135,3422859,607773,3430446],"proj:transform":[1,0,601135,0,-1,3430446,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.871894,30.934235],[-85.871089,31.002681],[-85.940611,31.00327],[-85.941366,30.934823],[-85.871894,30.934235]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008501_ne_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008501_ne_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008501_ne_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-85.941366,30.934235,-85.871089,31.00327],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008501_nw_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7583,6634],"proj:bbox":[595168,3422804,601802,3430387],"proj:transform":[1,0,595168,0,-1,3430387,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.934391,30.934269],[-85.933631,31.002681],[-86.003112,31.003236],[-86.003823,30.934823],[-85.934391,30.934269]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008501_nw_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008501_nw_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008501_nw_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.003823,30.934269,-85.933631,31.003236],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008502_ne_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7594,6646],"proj:bbox":[613069,3422979,619715,3430573],"proj:transform":[1,0,613069,0,-1,3430573,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.746902,30.934167],[-85.746007,31.002673],[-85.815609,31.00333],[-85.816455,30.934822],[-85.746902,30.934167]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008502_ne_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008502_ne_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008502_ne_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-85.816455,30.934167,-85.746007,31.00333],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008502_nw_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7591,6642],"proj:bbox":[607102,3422917,613744,3430508],"proj:transform":[1,0,607102,0,-1,3430508,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.809397,30.934198],[-85.808547,31.002679],[-85.87811,31.003302],[-85.87891,30.934819],[-85.809397,30.934198]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008502_nw_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008502_nw_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008502_nw_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-85.87891,30.934198,-85.808547,31.003302],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008503_ne_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7601,6654],"proj:bbox":[625004,3423113,631658,3430714],"proj:transform":[1,0,625004,0,-1,3430714,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.621902,30.934103],[-85.620917,31.002669],[-85.6906,31.003395],[-85.691535,30.934827],[-85.621902,30.934103]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008503_ne_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008503_ne_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008503_ne_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-85.691535,30.934103,-85.620917,31.003395],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008503_nw_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7597,6650],"proj:bbox":[619037,3423045,625687,3430642],"proj:transform":[1,0,619037,0,-1,3430642,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.684396,30.934141],[-85.683456,31.002673],[-85.753099,31.003364],[-85.753989,30.934831],[-85.684396,30.934141]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008503_nw_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008503_nw_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008503_nw_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-85.753989,30.934141,-85.683456,31.003364],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008504_ne_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7607,6662],"proj:bbox":[636939,3423261,643601,3430868],"proj:transform":[1,0,636939,0,-1,3430868,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.496906,30.934046],[-85.49583,31.002662],[-85.565593,31.003456],[-85.566619,30.934838],[-85.496906,30.934046]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008504_ne_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008504_ne_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008504_ne_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-85.566619,30.934046,-85.49583,31.003456],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008504_nw_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7604,6658],"proj:bbox":[630971,3423185,637629,3430789],"proj:transform":[1,0,630971,0,-1,3430789,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.559409,30.934072],[-85.558378,31.002663],[-85.628101,31.003423],[-85.629082,30.934829],[-85.559409,30.934072]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008504_nw_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008504_nw_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008504_nw_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-85.629082,30.934072,-85.558378,31.003423],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008505_ne_16_1_20110825_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7615,6670],"proj:bbox":[648874,3423421,655544,3431036],"proj:transform":[1,0,648874,0,-1,3431036,0,0,1],"datetime":"2011-08-25T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.371913,30.933975],[-85.370747,31.00266],[-85.440589,31.003522],[-85.441706,30.934836],[-85.371913,30.933975]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008505_ne_16_1_20110825.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008505_ne_16_1_20110825.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008505_ne_16_1_20110825.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-85.441706,30.933975,-85.370747,31.003522],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008505_nw_16_1_20110825_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7611,6666],"proj:bbox":[642906,3423339,649572,3430950],"proj:transform":[1,0,642906,0,-1,3430950,0,0,1],"datetime":"2011-08-25T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.434414,30.934008],[-85.433293,31.002658],[-85.503096,31.003486],[-85.504167,30.934834],[-85.434414,30.934008]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008505_nw_16_1_20110825.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008505_nw_16_1_20110825.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008505_nw_16_1_20110825.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-85.504167,30.934008,-85.433293,31.003486],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008506_ne_16_1_20110802_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7621,6678],"proj:bbox":[660809,3423596,667487,3431217],"proj:transform":[1,0,660809,0,-1,3431217,0,0,1],"datetime":"2011-08-02T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.246924,30.93392],[-85.245667,31.002654],[-85.315589,31.003585],[-85.316796,30.934848],[-85.246924,30.93392]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008506_ne_16_1_20110802.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008506_ne_16_1_20110802.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008506_ne_16_1_20110802.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-85.316796,30.93392,-85.245667,31.003585],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008506_nw_16_1_20110825_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7618,6674],"proj:bbox":[654842,3423507,661516,3431125],"proj:transform":[1,0,654842,0,-1,3431125,0,0,1],"datetime":"2011-08-25T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.309412,30.933949],[-85.308201,31.002658],[-85.378084,31.003555],[-85.379245,30.934843],[-85.309412,30.933949]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008506_nw_16_1_20110825.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008506_nw_16_1_20110825.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008506_nw_16_1_20110825.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-85.379245,30.933949,-85.308201,31.003555],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008601_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7532,6576],"proj:bbox":[505666,3422377,512242,3429909],"proj:transform":[1,0,505666,0,-1,3429909,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.871853,30.934744],[-86.871762,31.002707],[-86.940647,31.002757],[-86.940689,30.934794],[-86.871853,30.934744]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008601_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008601_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008601_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.940689,30.934744,-86.871762,31.002757],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008601_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7529,6571],"proj:bbox":[499700,3422375,506271,3429904],"proj:transform":[1,0,499700,0,-1,3429904,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.934356,30.934773],[-86.93431,31.002709],[-87.003143,31.002726],[-87.00314,30.934789],[-86.934356,30.934773]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008601_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008601_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008601_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.003143,30.934773,-86.93431,31.002726],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008602_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7539,6584],"proj:bbox":[517599,3422390,524183,3429929],"proj:transform":[1,0,517599,0,-1,3429929,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.746858,30.934677],[-86.746678,31.002703],[-86.815646,31.00282],[-86.815777,30.934794],[-86.746858,30.934677]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008602_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008602_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008602_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.815777,30.934677,-86.746678,31.00282],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008602_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7536,6579],"proj:bbox":[511633,3422382,518212,3429918],"proj:transform":[1,0,511633,0,-1,3429918,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.809361,30.934712],[-86.809225,31.002711],[-86.878142,31.002794],[-86.878228,30.934795],[-86.809361,30.934712]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008602_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008602_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008602_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.878228,30.934712,-86.809225,31.002794],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008603_ne_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7546,6591],"proj:bbox":[529533,3422417,536124,3429963],"proj:transform":[1,0,529533,0,-1,3429963,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.621863,30.934615],[-86.621594,31.002704],[-86.690635,31.002887],[-86.690855,30.934799],[-86.621863,30.934615]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008603_ne_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008603_ne_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008603_ne_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.690855,30.934615,-86.621594,31.002887],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008603_nw_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7542,6587],"proj:bbox":[523566,3422402,530153,3429944],"proj:transform":[1,0,523566,0,-1,3429944,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.684365,30.934648],[-86.684141,31.0027],[-86.753141,31.002851],[-86.753316,30.934798],[-86.684365,30.934648]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008603_nw_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008603_nw_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008603_nw_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.753316,30.934648,-86.684141,31.002851],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008604_ne_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7553,6599],"proj:bbox":[541466,3422457,548065,3430010],"proj:transform":[1,0,541466,0,-1,3430010,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.496869,30.93455],[-86.496512,31.002701],[-86.565635,31.002952],[-86.565944,30.934801],[-86.496869,30.93455]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008604_ne_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008604_ne_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008604_ne_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.565944,30.93455,-86.496512,31.002952],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008604_nw_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7550,6595],"proj:bbox":[535499,3422435,542094,3429985],"proj:transform":[1,0,535499,0,-1,3429985,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.559371,30.93458],[-86.559058,31.002704],[-86.62814,31.002921],[-86.628404,30.934797],[-86.559371,30.93458]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008604_nw_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008604_nw_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008604_nw_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.628404,30.93458,-86.559058,31.002921],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008605_ne_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7559,6606],"proj:bbox":[553400,3422511,560006,3430070],"proj:transform":[1,0,553400,0,-1,3430070,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.371877,30.934491],[-86.37143,31.002694],[-86.440626,31.003012],[-86.441023,30.934808],[-86.371877,30.934491]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008605_ne_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008605_ne_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008605_ne_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.441023,30.934491,-86.37143,31.003012],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008605_nw_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7556,6603],"proj:bbox":[547433,3422482,554036,3430038],"proj:transform":[1,0,547433,0,-1,3430038,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.434367,30.934518],[-86.433965,31.002694],[-86.50313,31.002979],[-86.503483,30.934802],[-86.434367,30.934518]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008605_nw_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008605_nw_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008605_nw_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.503483,30.934518,-86.433965,31.002979],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008606_ne_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7567,6615],"proj:bbox":[565333,3422577,571948,3430144],"proj:transform":[1,0,565333,0,-1,3430144,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.246875,30.934419],[-86.246339,31.002692],[-86.315627,31.003078],[-86.316114,30.934803],[-86.246875,30.934419]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008606_ne_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008606_ne_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008606_ne_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.316114,30.934419,-86.246339,31.003078],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008606_nw_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7563,6611],"proj:bbox":[559366,3422542,565977,3430105],"proj:transform":[1,0,559366,0,-1,3430105,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.309376,30.934452],[-86.308884,31.00269],[-86.378132,31.003042],[-86.378574,30.934803],[-86.309376,30.934452]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008606_nw_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008606_nw_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008606_nw_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.378574,30.934452,-86.308884,31.003042],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008607_ne_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7573,6622],"proj:bbox":[577267,3422658,583889,3430231],"proj:transform":[1,0,577267,0,-1,3430231,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.121886,30.934361],[-86.121261,31.002686],[-86.19062,31.00314],[-86.191196,30.934813],[-86.121886,30.934361]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008607_ne_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008607_ne_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008607_ne_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.191196,30.934361,-86.121261,31.00314],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008607_nw_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7570,6618],"proj:bbox":[571300,3422616,577918,3430186],"proj:transform":[1,0,571300,0,-1,3430186,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.184386,30.934391],[-86.183805,31.002691],[-86.253123,31.00311],[-86.253655,30.93481],[-86.184386,30.934391]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008607_nw_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008607_nw_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008607_nw_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.253655,30.934391,-86.183805,31.00311],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008608_ne_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7580,6630],"proj:bbox":[589201,3422752,595831,3430332],"proj:transform":[1,0,589201,0,-1,3430332,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-85.996889,30.9343],[-85.996173,31.002686],[-86.065614,31.003207],[-86.06628,30.93482],[-85.996889,30.9343]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008608_ne_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008608_ne_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008608_ne_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.06628,30.9343,-85.996173,31.003207],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008608_nw_16_1_20110815_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7577,6626],"proj:bbox":[583234,3422703,589860,3430280],"proj:transform":[1,0,583234,0,-1,3430280,0,0,1],"datetime":"2011-08-15T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.059387,30.934327],[-86.058717,31.002688],[-86.128117,31.003175],[-86.128738,30.934813],[-86.059387,30.934327]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008608_nw_16_1_20110815.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008608_nw_16_1_20110815.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008608_nw_16_1_20110815.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-86.128738,30.934327,-86.058717,31.003175],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008701_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7577,6626],"proj:bbox":[410140,3422703,416766,3430280],"proj:transform":[1,0,410140,0,-1,3430280,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.871262,30.934813],[-87.871883,31.003175],[-87.941283,31.002688],[-87.940613,30.934327],[-87.871262,30.934813]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008701_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.941283,30.934327,-87.871262,31.003175],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008701_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7580,6630],"proj:bbox":[404169,3422752,410799,3430332],"proj:transform":[1,0,404169,0,-1,3430332,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.93372,30.93482],[-87.934386,31.003207],[-88.003827,31.002686],[-88.003111,30.9343],[-87.93372,30.93482]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008701_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-88.003827,30.9343,-87.93372,31.003207],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008701_se_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7577,6630],"proj:bbox":[410082,3415776,416712,3423353],"proj:transform":[1,0,410082,0,-1,3423353,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.871261,30.872312],[-87.87188,30.940674],[-87.941277,30.940187],[-87.940609,30.871827],[-87.871261,30.872312]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_se_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008701_se_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_se_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.941277,30.871827,-87.871261,30.940674],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008701_sw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7580,6634],"proj:bbox":[404107,3415825,410741,3423405],"proj:transform":[1,0,404107,0,-1,3423405,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.93372,30.872319],[-87.934384,30.940707],[-88.003822,30.940186],[-88.003108,30.8718],[-87.93372,30.872319]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_sw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008701_sw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_sw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-88.003822,30.8718,-87.93372,30.940707],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008702_ne_16_1_20110801_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7570,6618],"proj:bbox":[422082,3422616,428700,3430186],"proj:transform":[1,0,422082,0,-1,3430186,0,0,1],"datetime":"2011-08-01T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.746345,30.93481],[-87.746877,31.00311],[-87.816195,31.002691],[-87.815614,30.934391],[-87.746345,30.93481]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_ne_16_1_20110801.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008702_ne_16_1_20110801.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_ne_16_1_20110801.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.816195,30.934391,-87.746345,31.00311],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008702_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7573,6622],"proj:bbox":[416111,3422658,422733,3430231],"proj:transform":[1,0,416111,0,-1,3430231,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.808804,30.934813],[-87.80938,31.00314],[-87.878739,31.002686],[-87.878114,30.934361],[-87.808804,30.934813]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008702_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.878739,30.934361,-87.808804,31.00314],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008702_se_16_1_20110801_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7570,6622],"proj:bbox":[422031,3415689,428653,3423259],"proj:transform":[1,0,422031,0,-1,3423259,0,0,1],"datetime":"2011-08-01T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.746352,30.872308],[-87.746882,30.940609],[-87.816197,30.94019],[-87.815618,30.87189],[-87.746352,30.872308]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_se_16_1_20110801.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008702_se_16_1_20110801.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_se_16_1_20110801.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.816197,30.87189,-87.746352,30.940609],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008702_sw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7573,6627],"proj:bbox":[416056,3415731,422683,3423304],"proj:transform":[1,0,416056,0,-1,3423304,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.808801,30.872311],[-87.809376,30.940638],[-87.878743,30.940186],[-87.878119,30.87186],[-87.808801,30.872311]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_sw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008702_sw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_sw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.878743,30.87186,-87.808801,30.940638],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008703_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7563,6611],"proj:bbox":[434023,3422542,440634,3430105],"proj:transform":[1,0,434023,0,-1,3430105,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.621426,30.934803],[-87.621868,31.003042],[-87.691116,31.00269],[-87.690624,30.934452],[-87.621426,30.934803]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008703_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.691116,30.934452,-87.621426,31.003042],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008703_nw_16_1_20110801_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7567,6615],"proj:bbox":[428052,3422577,434667,3430144],"proj:transform":[1,0,428052,0,-1,3430144,0,0,1],"datetime":"2011-08-01T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.683886,30.934803],[-87.684373,31.003078],[-87.753661,31.002692],[-87.753125,30.934419],[-87.683886,30.934803]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_nw_16_1_20110801.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008703_nw_16_1_20110801.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_nw_16_1_20110801.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.753661,30.934419,-87.683886,31.003078],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008703_se_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7562,6615],"proj:bbox":[433980,3415616,440595,3423178],"proj:transform":[1,0,433980,0,-1,3423178,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.621431,30.872309],[-87.621872,30.940539],[-87.691116,30.940188],[-87.690626,30.871958],[-87.621431,30.872309]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_se_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008703_se_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_se_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.691116,30.871958,-87.621431,30.940539],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008703_sw_16_1_20110801_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7566,6618],"proj:bbox":[428006,3415651,434624,3423217],"proj:transform":[1,0,428006,0,-1,3423217,0,0,1],"datetime":"2011-08-01T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.683891,30.87231],[-87.684377,30.940576],[-87.753652,30.94019],[-87.753117,30.871926],[-87.683891,30.87231]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_sw_16_1_20110801.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008703_sw_16_1_20110801.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_sw_16_1_20110801.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.753652,30.871926,-87.683891,30.940576],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008704_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7556,6603],"proj:bbox":[445964,3422482,452567,3430038],"proj:transform":[1,0,445964,0,-1,3430038,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.496517,30.934802],[-87.49687,31.002979],[-87.566035,31.002694],[-87.565633,30.934518],[-87.496517,30.934802]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008704_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008704_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008704_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.566035,30.934518,-87.496517,31.002979],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008704_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7559,6606],"proj:bbox":[439994,3422511,446600,3430070],"proj:transform":[1,0,439994,0,-1,3430070,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.558977,30.934808],[-87.559374,31.003012],[-87.62857,31.002694],[-87.628123,30.934491],[-87.558977,30.934808]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008704_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008704_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008704_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.62857,30.934491,-87.558977,31.003012],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008704_sw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7559,6610],"proj:bbox":[439955,3415584,446565,3423143],"proj:transform":[1,0,439955,0,-1,3423143,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.55898,30.872305],[-87.559377,30.940509],[-87.628569,30.940191],[-87.628123,30.871988],[-87.55898,30.872305]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008704_sw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008704_sw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008704_sw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.628569,30.871988,-87.55898,30.940509],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008705_ne_16_1_20110817_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7550,6595],"proj:bbox":[457906,3422435,464501,3429985],"proj:transform":[1,0,457906,0,-1,3429985,0,0,1],"datetime":"2011-08-17T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.371596,30.934797],[-87.37186,31.002921],[-87.440942,31.002704],[-87.440629,30.93458],[-87.371596,30.934797]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008705_ne_16_1_20110817.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008705_ne_16_1_20110817.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008705_ne_16_1_20110817.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.440942,30.93458,-87.371596,31.002921],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008705_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7553,6599],"proj:bbox":[451935,3422457,458534,3430010],"proj:transform":[1,0,451935,0,-1,3430010,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.434056,30.934801],[-87.434365,31.002952],[-87.503488,31.002701],[-87.503131,30.93455],[-87.434056,30.934801]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008705_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008705_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008705_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.503488,30.93455,-87.434056,31.002952],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008706_ne_16_1_20110817_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7542,6587],"proj:bbox":[469847,3422402,476434,3429944],"proj:transform":[1,0,469847,0,-1,3429944,0,0,1],"datetime":"2011-08-17T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.246684,30.934798],[-87.246859,31.002851],[-87.315859,31.0027],[-87.315635,30.934648],[-87.246684,30.934798]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008706_ne_16_1_20110817.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008706_ne_16_1_20110817.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008706_ne_16_1_20110817.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.315859,30.934648,-87.246684,31.002851],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008706_nw_16_1_20110817_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7546,6591],"proj:bbox":[463876,3422417,470467,3429963],"proj:transform":[1,0,463876,0,-1,3429963,0,0,1],"datetime":"2011-08-17T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.309145,30.934799],[-87.309365,31.002887],[-87.378406,31.002704],[-87.378137,30.934615],[-87.309145,30.934799]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008706_nw_16_1_20110817.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008706_nw_16_1_20110817.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008706_nw_16_1_20110817.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.378406,30.934615,-87.309145,31.002887],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008707_ne_16_1_20110824_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7536,6579],"proj:bbox":[481788,3422382,488367,3429918],"proj:transform":[1,0,481788,0,-1,3429918,0,0,1],"datetime":"2011-08-24T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.121772,30.934795],[-87.121858,31.002794],[-87.190775,31.002711],[-87.190639,30.934712],[-87.121772,30.934795]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008707_ne_16_1_20110824.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008707_ne_16_1_20110824.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008707_ne_16_1_20110824.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.190775,30.934712,-87.121772,31.002794],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008707_nw_16_1_20110824_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7539,6584],"proj:bbox":[475817,3422390,482401,3429929],"proj:transform":[1,0,475817,0,-1,3429929,0,0,1],"datetime":"2011-08-24T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.184223,30.934794],[-87.184354,31.00282],[-87.253322,31.002703],[-87.253142,30.934677],[-87.184223,30.934794]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008707_nw_16_1_20110824.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008707_nw_16_1_20110824.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008707_nw_16_1_20110824.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.253322,30.934677,-87.184223,31.00282],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008708_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7529,6571],"proj:bbox":[493729,3422375,500300,3429904],"proj:transform":[1,0,493729,0,-1,3429904,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-86.99686,30.934789],[-86.996857,31.002726],[-87.06569,31.002709],[-87.065644,30.934773],[-86.99686,30.934789]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008708_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008708_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008708_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.06569,30.934773,-86.996857,31.002726],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008708_nw_16_1_20110824_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7532,6576],"proj:bbox":[487758,3422377,494334,3429909],"proj:transform":[1,0,487758,0,-1,3429909,0,0,1],"datetime":"2011-08-24T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.059311,30.934794],[-87.059353,31.002757],[-87.128238,31.002707],[-87.128147,30.934744],[-87.059311,30.934794]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008708_nw_16_1_20110824.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008708_nw_16_1_20110824.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008708_nw_16_1_20110824.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.128238,30.934744,-87.059311,31.002757],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008709_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7577,6633],"proj:bbox":[410024,3408849,416657,3416426],"proj:transform":[1,0,410024,0,-1,3416426,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.871271,30.80981],[-87.871889,30.878173],[-87.941273,30.877687],[-87.940605,30.809325],[-87.871271,30.80981]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008709_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.941273,30.809325,-87.871271,30.878173],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008709_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7580,6638],"proj:bbox":[404045,3408898,410683,3416478],"proj:transform":[1,0,404045,0,-1,3416478,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.933721,30.809817],[-87.934384,30.878206],[-88.003818,30.877686],[-88.003106,30.809299],[-87.933721,30.809817]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008709_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-88.003818,30.809299,-87.933721,30.878206],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008709_se_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7576,6637],"proj:bbox":[409966,3401923,416603,3409499],"proj:transform":[1,0,409966,0,-1,3409499,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.871272,30.747317],[-87.871889,30.815671],[-87.941269,30.815185],[-87.940603,30.746832],[-87.871272,30.747317]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_se_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008709_se_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_se_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.941269,30.746832,-87.871272,30.815671],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008709_sw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7580,6642],"proj:bbox":[403983,3401971,410625,3409551],"proj:transform":[1,0,403983,0,-1,3409551,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.933724,30.747315],[-87.934385,30.815704],[-88.003816,30.815185],[-88.003106,30.746797],[-87.933724,30.747315]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_sw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008709_sw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_sw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-88.003816,30.746797,-87.933724,30.815704],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008710_ne_16_1_20110731_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7569,6626],"proj:bbox":[421981,3408763,428607,3416332],"proj:transform":[1,0,421981,0,-1,3416332,0,0,1],"datetime":"2011-07-31T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.746349,30.809814],[-87.746878,30.878106],[-87.81619,30.877688],[-87.815612,30.809396],[-87.746349,30.809814]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_ne_16_1_20110731.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008710_ne_16_1_20110731.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_ne_16_1_20110731.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.81619,30.809396,-87.746349,30.878106],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008710_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7573,6630],"proj:bbox":[416002,3408804,422632,3416377],"proj:transform":[1,0,416002,0,-1,3416377,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.80881,30.809809],[-87.809384,30.878137],[-87.878737,30.877684],[-87.878114,30.809358],[-87.80881,30.809809]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008710_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.878737,30.809358,-87.80881,30.878137],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008710_se_16_1_20110731_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7569,6630],"proj:bbox":[421930,3401836,428560,3409405],"proj:transform":[1,0,421930,0,-1,3409405,0,0,1],"datetime":"2011-07-31T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.746358,30.74731],[-87.746885,30.815603],[-87.816194,30.815185],[-87.815618,30.746893],[-87.746358,30.74731]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_se_16_1_20110731.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008710_se_16_1_20110731.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_se_16_1_20110731.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.816194,30.746893,-87.746358,30.815603],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008710_sw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7572,6634],"proj:bbox":[415948,3401878,422582,3409450],"proj:transform":[1,0,415948,0,-1,3409450,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.80881,30.747315],[-87.809382,30.815634],[-87.878732,30.815182],[-87.878111,30.746864],[-87.80881,30.747315]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_sw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008710_sw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_sw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.878732,30.746864,-87.80881,30.815634],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008711_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7563,6618],"proj:bbox":[433938,3408689,440556,3416252],"proj:transform":[1,0,433938,0,-1,3416252,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.621436,30.809805],[-87.621876,30.878045],[-87.691106,30.877694],[-87.690617,30.809455],[-87.621436,30.809805]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008711_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.691106,30.809455,-87.621436,30.878045],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008711_nw_16_1_20110731_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7566,6622],"proj:bbox":[427959,3408724,434581,3416290],"proj:transform":[1,0,427959,0,-1,3416290,0,0,1],"datetime":"2011-07-31T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.683898,30.809806],[-87.684382,30.878073],[-87.753654,30.877688],[-87.75312,30.809423],[-87.683898,30.809806]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_nw_16_1_20110731.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008711_nw_16_1_20110731.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_nw_16_1_20110731.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.753654,30.809423,-87.683898,30.878073],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008711_se_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7562,6622],"proj:bbox":[433895,3401763,440517,3409325],"proj:transform":[1,0,433895,0,-1,3409325,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.621442,30.74731],[-87.62188,30.815542],[-87.691108,30.815191],[-87.69062,30.74696],[-87.621442,30.74731]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_se_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008711_se_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_se_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.691108,30.74696,-87.621442,30.815542],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008711_sw_16_1_20110731_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7566,6626],"proj:bbox":[427913,3401798,434539,3409364],"proj:transform":[1,0,427913,0,-1,3409364,0,0,1],"datetime":"2011-07-31T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.683895,30.747312],[-87.684378,30.815579],[-87.753646,30.815194],[-87.753114,30.746928],[-87.683895,30.747312]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_sw_16_1_20110731.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008711_sw_16_1_20110731.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_sw_16_1_20110731.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.753646,30.746928,-87.683895,30.815579],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008712_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7560,6615],"proj:bbox":[439916,3408657,446531,3416217],"proj:transform":[1,0,439916,0,-1,3416217,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.558973,30.809801],[-87.559369,30.878015],[-87.628569,30.877697],[-87.628124,30.809484],[-87.558973,30.809801]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008712_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008712_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008712_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.628569,30.809484,-87.558973,30.878015],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008712_se_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7556,6614],"proj:bbox":[445860,3401702,452474,3409258],"proj:transform":[1,0,445860,0,-1,3409258,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.496524,30.747298],[-87.496874,30.815477],[-87.566019,30.815193],[-87.56562,30.747015],[-87.496524,30.747298]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008712_se_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008712_se_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008712_se_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.566019,30.747015,-87.496524,30.815477],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008712_sw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7559,6618],"proj:bbox":[439878,3401731,446496,3409290],"proj:transform":[1,0,439878,0,-1,3409290,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.558978,30.747305],[-87.559372,30.815511],[-87.628559,30.815194],[-87.628115,30.746989],[-87.558978,30.747305]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008712_sw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008712_sw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008712_sw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.628559,30.746989,-87.558978,30.815511],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008717_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7576,6641],"proj:bbox":[409908,3394996,416549,3402572],"proj:transform":[1,0,409908,0,-1,3402572,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.871274,30.684813],[-87.871889,30.753168],[-87.941266,30.752684],[-87.940602,30.68433],[-87.871274,30.684813]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008717_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.941266,30.68433,-87.871274,30.753168],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008717_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7580,6646],"proj:bbox":[403921,3395044,410567,3402624],"proj:transform":[1,0,403921,0,-1,3402624,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.933727,30.684813],[-87.934386,30.753202],[-88.003814,30.752684],[-88.003106,30.684295],[-87.933727,30.684813]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008717_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-88.003814,30.684295,-87.933727,30.753202],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008717_se_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7576,6645],"proj:bbox":[409850,3388069,416495,3395645],"proj:transform":[1,0,409850,0,-1,3395645,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.871277,30.62231],[-87.871891,30.690665],[-87.941265,30.690181],[-87.940603,30.621827],[-87.871277,30.62231]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_se_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008717_se_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_se_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.941265,30.621827,-87.871277,30.690665],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008717_sw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7579,6649],"proj:bbox":[403860,3388118,410509,3395697],"proj:transform":[1,0,403860,0,-1,3395697,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.933732,30.622318],[-87.934389,30.6907],[-88.003804,30.690182],[-88.003098,30.621802],[-87.933732,30.622318]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_sw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008717_sw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_sw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-88.003804,30.621802,-87.933732,30.6907],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008718_ne_16_1_20110731_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7570,6634],"proj:bbox":[421880,3394909,428514,3402479],"proj:transform":[1,0,421880,0,-1,3402479,0,0,1],"datetime":"2011-07-31T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.746357,30.684806],[-87.746883,30.753109],[-87.816189,30.752692],[-87.815614,30.68439],[-87.746357,30.684806]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_ne_16_1_20110731.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008718_ne_16_1_20110731.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_ne_16_1_20110731.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.816189,30.68439,-87.746357,30.753109],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008718_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7573,6637],"proj:bbox":[415894,3394951,422531,3402524],"proj:transform":[1,0,415894,0,-1,3402524,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.808821,30.684811],[-87.809392,30.75314],[-87.878728,30.752689],[-87.878109,30.684361],[-87.808821,30.684811]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008718_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.878728,30.684361,-87.808821,30.75314],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008718_se_16_1_20110731_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7569,6638],"proj:bbox":[421830,3387983,428468,3395552],"proj:transform":[1,0,421830,0,-1,3395552,0,0,1],"datetime":"2011-07-31T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.746357,30.62231],[-87.746882,30.690605],[-87.816185,30.690188],[-87.815611,30.621895],[-87.746357,30.62231]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_se_16_1_20110731.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008718_se_16_1_20110731.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_se_16_1_20110731.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.816185,30.621895,-87.746357,30.690605],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008718_sw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7573,6641],"proj:bbox":[415840,3388024,422481,3395597],"proj:transform":[1,0,415840,0,-1,3395597,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.808823,30.622307],[-87.809392,30.690637],[-87.878725,30.690186],[-87.878107,30.621858],[-87.808823,30.622307]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_sw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008718_sw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_sw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.878725,30.621858,-87.808823,30.690637],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008719_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7563,6626],"proj:bbox":[433853,3394836,440479,3402399],"proj:transform":[1,0,433853,0,-1,3402399,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.621438,30.684805],[-87.621875,30.753047],[-87.6911,30.752696],[-87.690613,30.684456],[-87.621438,30.684805]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008719_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.6911,30.684456,-87.621438,30.753047],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008719_nw_16_1_20110731_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7566,6629],"proj:bbox":[427867,3394871,434496,3402437],"proj:transform":[1,0,427867,0,-1,3402437,0,0,1],"datetime":"2011-07-31T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.683903,30.684807],[-87.684385,30.753075],[-87.753639,30.752691],[-87.753109,30.684424],[-87.683903,30.684807]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_nw_16_1_20110731.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008719_nw_16_1_20110731.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_nw_16_1_20110731.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.753639,30.684424,-87.683903,30.753075],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008719_se_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7562,6630],"proj:bbox":[433810,3387910,440440,3395472],"proj:transform":[1,0,433810,0,-1,3395472,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.621445,30.622309],[-87.621882,30.690542],[-87.691103,30.690192],[-87.690618,30.62196],[-87.621445,30.622309]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_se_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008719_se_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_se_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.691103,30.62196,-87.621445,30.690542],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008719_sw_16_1_20110731_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7565,6634],"proj:bbox":[427820,3387945,434454,3395510],"proj:transform":[1,0,427820,0,-1,3395510,0,0,1],"datetime":"2011-07-31T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.683901,30.622311],[-87.684382,30.69057],[-87.753644,30.690187],[-87.753115,30.621929],[-87.683901,30.622311]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_sw_16_1_20110731.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008719_sw_16_1_20110731.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_sw_16_1_20110731.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.753644,30.621929,-87.683901,30.69057],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008720_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7556,6618],"proj:bbox":[445825,3394776,452443,3402332],"proj:transform":[1,0,445825,0,-1,3402332,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.496527,30.684801],[-87.496877,30.752981],[-87.566019,30.752698],[-87.565621,30.684519],[-87.496527,30.684801]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008720_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.566019,30.684519,-87.496527,30.752981],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008720_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7560,6622],"proj:bbox":[439839,3394804,446461,3402364],"proj:transform":[1,0,439839,0,-1,3402364,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.558983,30.6848],[-87.559376,30.753015],[-87.62856,30.752699],[-87.628117,30.684484],[-87.558983,30.6848]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008720_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.62856,30.684484,-87.558983,30.753015],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008720_se_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7555,6622],"proj:bbox":[445790,3387850,452412,3395405],"proj:transform":[1,0,445790,0,-1,3395405,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.496532,30.622304],[-87.49688,30.690476],[-87.56602,30.690193],[-87.565623,30.622022],[-87.496532,30.622304]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_se_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008720_se_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_se_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.56602,30.622022,-87.496532,30.690476],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008720_sw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7559,6626],"proj:bbox":[439800,3387878,446426,3395437],"proj:transform":[1,0,439800,0,-1,3395437,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.558988,30.622303],[-87.559381,30.69051],[-87.628562,30.690194],[-87.62812,30.621988],[-87.558988,30.622303]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_sw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008720_sw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_sw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.628562,30.621988,-87.558988,30.69051],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008721_ne_16_1_20110817_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7549,6611],"proj:bbox":[457797,3394729,464408,3402278],"proj:transform":[1,0,457797,0,-1,3402278,0,0,1],"datetime":"2011-08-17T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.371606,30.684794],[-87.371867,30.752912],[-87.440937,30.752696],[-87.440628,30.684579],[-87.371606,30.684794]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_ne_16_1_20110817.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008721_ne_16_1_20110817.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_ne_16_1_20110817.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.440937,30.684579,-87.371606,30.752912],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008721_nw_16_1_20110817_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7552,6614],"proj:bbox":[451811,3394751,458425,3402303],"proj:transform":[1,0,451811,0,-1,3402303,0,0,1],"datetime":"2011-08-17T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.434072,30.684799],[-87.434377,30.752944],[-87.503478,30.752694],[-87.503125,30.68455],[-87.434072,30.684799]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_nw_16_1_20110817.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008721_nw_16_1_20110817.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_nw_16_1_20110817.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.503478,30.68455,-87.434072,30.752944],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008721_se_16_1_20110817_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7549,6614],"proj:bbox":[457770,3387803,464384,3395352],"proj:transform":[1,0,457770,0,-1,3395352,0,0,1],"datetime":"2011-08-17T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.371617,30.622297],[-87.371878,30.690415],[-87.440935,30.690199],[-87.440626,30.622081],[-87.371617,30.622297]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_se_16_1_20110817.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008721_se_16_1_20110817.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_se_16_1_20110817.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.440935,30.622081,-87.371617,30.690415],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008721_sw_16_1_20110817_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7552,6618],"proj:bbox":[451780,3387825,458398,3395377],"proj:transform":[1,0,451780,0,-1,3395377,0,0,1],"datetime":"2011-08-17T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.434074,30.622302],[-87.434379,30.690447],[-87.503478,30.690198],[-87.503124,30.622053],[-87.434074,30.622302]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_sw_16_1_20110817.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008721_sw_16_1_20110817.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_sw_16_1_20110817.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.503478,30.622053,-87.434074,30.690447],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008725_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7576,6649],"proj:bbox":[409792,3381143,416441,3388719],"proj:transform":[1,0,409792,0,-1,3388719,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.871282,30.559814],[-87.871893,30.628171],[-87.941265,30.627687],[-87.940604,30.559332],[-87.871282,30.559814]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008725_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008725_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008725_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.941265,30.559332,-87.871282,30.628171],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008725_se_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7576,6652],"proj:bbox":[409735,3374216,416387,3381792],"proj:transform":[1,0,409735,0,-1,3381792,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.871287,30.497309],[-87.871897,30.565666],[-87.941255,30.565183],[-87.940596,30.496828],[-87.871287,30.497309]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008725_se_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008725_se_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008725_se_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.941255,30.496828,-87.871287,30.565666],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008726_ne_16_1_20110731_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7569,6641],"proj:bbox":[421780,3381056,428421,3388625],"proj:transform":[1,0,421780,0,-1,3388625,0,0,1],"datetime":"2011-07-31T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.746368,30.559805],[-87.746892,30.6281],[-87.816182,30.627684],[-87.815609,30.55939],[-87.746368,30.559805]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_ne_16_1_20110731.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008726_ne_16_1_20110731.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_ne_16_1_20110731.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.816182,30.55939,-87.746368,30.6281],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008726_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7572,6645],"proj:bbox":[415786,3381098,422431,3388670],"proj:transform":[1,0,415786,0,-1,3388670,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.808825,30.559811],[-87.809393,30.628132],[-87.878723,30.627682],[-87.878107,30.559362],[-87.808825,30.559811]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008726_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.878723,30.559362,-87.808825,30.628132],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008726_se_16_1_20110731_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7569,6645],"proj:bbox":[421730,3374130,428375,3381699],"proj:transform":[1,0,421730,0,-1,3381699,0,0,1],"datetime":"2011-07-31T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.74637,30.497308],[-87.746892,30.565604],[-87.816179,30.565188],[-87.815608,30.496894],[-87.74637,30.497308]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_se_16_1_20110731.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008726_se_16_1_20110731.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_se_16_1_20110731.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.816179,30.496894,-87.74637,30.565604],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008726_sw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7572,6649],"proj:bbox":[415732,3374172,422381,3381744],"proj:transform":[1,0,415732,0,-1,3381744,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.808828,30.497315],[-87.809395,30.565637],[-87.878723,30.565187],[-87.878108,30.496867],[-87.808828,30.497315]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_sw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008726_sw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_sw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.878723,30.496867,-87.808828,30.565637],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008727_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7563,6633],"proj:bbox":[433768,3380983,440401,3388546],"proj:transform":[1,0,433768,0,-1,3388546,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.621453,30.559803],[-87.621889,30.628045],[-87.691097,30.627696],[-87.690613,30.559454],[-87.621453,30.559803]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008727_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.691097,30.559454,-87.621453,30.628045],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008727_nw_16_1_20110731_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7566,6637],"proj:bbox":[427774,3381018,434411,3388584],"proj:transform":[1,0,427774,0,-1,3388584,0,0,1],"datetime":"2011-07-31T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.683911,30.559805],[-87.68439,30.628074],[-87.753639,30.627692],[-87.753111,30.559423],[-87.683911,30.559805]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_nw_16_1_20110731.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008727_nw_16_1_20110731.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_nw_16_1_20110731.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.753639,30.559423,-87.683911,30.628074],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008727_se_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7562,6637],"proj:bbox":[433726,3374057,440363,3381619],"proj:transform":[1,0,433726,0,-1,3381619,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.621451,30.497305],[-87.621886,30.565539],[-87.691091,30.565191],[-87.690608,30.496957],[-87.621451,30.497305]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_se_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008727_se_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_se_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.691091,30.496957,-87.621451,30.565539],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008727_sw_16_1_20110731_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7565,6641],"proj:bbox":[427728,3374092,434369,3381657],"proj:transform":[1,0,427728,0,-1,3381657,0,0,1],"datetime":"2011-07-31T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.683911,30.497308],[-87.684389,30.565569],[-87.753635,30.565186],[-87.753109,30.496927],[-87.683911,30.497308]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_sw_16_1_20110731.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008727_sw_16_1_20110731.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_sw_16_1_20110731.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.753635,30.496927,-87.683911,30.565569],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008728_ne_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7556,6625],"proj:bbox":[445756,3380923,452381,3388479],"proj:transform":[1,0,445756,0,-1,3388479,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.496536,30.559797],[-87.496884,30.627979],[-87.56601,30.627696],[-87.565614,30.559516],[-87.496536,30.559797]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_ne_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008728_ne_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_ne_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.56601,30.559516,-87.496536,30.627979],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008728_nw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7559,6629],"proj:bbox":[439762,3380952,446391,3388511],"proj:transform":[1,0,439762,0,-1,3388511,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.558995,30.559806],[-87.559386,30.628014],[-87.628554,30.627698],[-87.628114,30.559491],[-87.558995,30.559806]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_nw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008728_nw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_nw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.628554,30.559491,-87.558995,30.628014],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008728_se_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7556,6630],"proj:bbox":[445721,3373997,452351,3381553],"proj:transform":[1,0,445721,0,-1,3381553,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.496531,30.497299],[-87.496878,30.565481],[-87.566012,30.565199],[-87.565617,30.497018],[-87.496531,30.497299]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_se_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008728_se_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_se_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.566012,30.497018,-87.496531,30.565481],"stac_extensions":["eo","projection"],"collection":"usda-naip"} -{"type":"Feature","stac_version":"1.0.0-beta.2","id":"al_m_3008728_sw_16_1_20110816_20111017","properties":{"naip:state":"al","naip:year":"2011","providers":[{"name":"USDA Farm Service Agency","roles":["producer","licensor"],"url":"https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/"}],"gsd":1,"proj:epsg":26916,"proj:shape":[7559,6633],"proj:bbox":[439724,3374025,446357,3381584],"proj:transform":[1,0,439724,0,-1,3381584,0,0,1],"datetime":"2011-08-16T00:00:00Z"},"geometry":{"type":"Polygon","coordinates":[[[-87.558991,30.497299],[-87.559382,30.565507],[-87.628547,30.565192],[-87.628108,30.496984],[-87.558991,30.497299]]]},"links":[],"assets":{"image":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_sw_16_1_20110816.tif","type":"image/tiff; application=geotiff; profile=cloud-optimized","title":"RGBIR COG tile","eo:bands":[{"name":"Red","common_name":"red"},{"name":"Green","common_name":"green"},{"name":"Blue","common_name":"blue"},{"name":"NIR","common_name":"nir","description":"near-infrared"}],"roles":["data"]},"metadata":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008728_sw_16_1_20110816.txt","type":"text/plain","title":"FGDC Metdata","roles":["metadata"]},"thumbnail":{"href":"https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_sw_16_1_20110816.200.jpg","type":"image/jpeg","title":"Thumbnail","roles":["thumbnail"]}},"bbox":[-87.628547,30.496984,-87.558991,30.565507],"stac_extensions":["eo","projection"],"collection":"usda-naip"} +{"id": "pgstac-test-item-0003", "bbox": [-85.379245, 30.933949, -85.308201, 31.003555], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008506_nw_16_1_20110825.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008506_nw_16_1_20110825.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008506_nw_16_1_20110825.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.309412, 30.933949], [-85.308201, 31.002658], [-85.378084, 31.003555], [-85.379245, 30.934843], [-85.309412, 30.933949]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-25T00:00:00Z", "naip:year": "2011", "proj:bbox": [654842, 3423507, 661516, 3431125], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7618, 6674], "eo:cloud_cover": 28, "proj:transform": [1, 0, 654842, 0, -1, 3431125, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0004", "bbox": [-87.190775, 30.934712, -87.121772, 31.002794], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008707_ne_16_1_20110824.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008707_ne_16_1_20110824.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008707_ne_16_1_20110824.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.121772, 30.934795], [-87.121858, 31.002794], [-87.190775, 31.002711], [-87.190639, 30.934712], [-87.121772, 30.934795]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-24T00:00:00Z", "naip:year": "2011", "proj:bbox": [481788, 3422382, 488367, 3429918], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7536, 6579], "eo:cloud_cover": 23, "proj:transform": [1, 0, 481788, 0, -1, 3429918, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0005", "bbox": [-87.128238, 30.934744, -87.059311, 31.002757], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008708_nw_16_1_20110824.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008708_nw_16_1_20110824.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008708_nw_16_1_20110824.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.059311, 30.934794], [-87.059353, 31.002757], [-87.128238, 31.002707], [-87.128147, 30.934744], [-87.059311, 30.934794]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-24T00:00:00Z", "naip:year": "2011", "proj:bbox": [487758, 3422377, 494334, 3429909], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7532, 6576], "eo:cloud_cover": 3, "proj:transform": [1, 0, 487758, 0, -1, 3429909, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0006", "bbox": [-87.253322, 30.934677, -87.184223, 31.00282], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008707_nw_16_1_20110824.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008707_nw_16_1_20110824.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008707_nw_16_1_20110824.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.184223, 30.934794], [-87.184354, 31.00282], [-87.253322, 31.002703], [-87.253142, 30.934677], [-87.184223, 30.934794]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-24T00:00:00Z", "naip:year": "2011", "proj:bbox": [475817, 3422390, 482401, 3429929], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7539, 6584], "eo:cloud_cover": 100, "proj:transform": [1, 0, 475817, 0, -1, 3429929, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0007", "bbox": [-87.440935, 30.622081, -87.371617, 30.690415], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_se_16_1_20110817.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008721_se_16_1_20110817.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_se_16_1_20110817.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.371617, 30.622297], [-87.371878, 30.690415], [-87.440935, 30.690199], [-87.440626, 30.622081], [-87.371617, 30.622297]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-17T00:00:00Z", "naip:year": "2011", "proj:bbox": [457770, 3387803, 464384, 3395352], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7549, 6614], "eo:cloud_cover": 59, "proj:transform": [1, 0, 457770, 0, -1, 3395352, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0008", "bbox": [-87.503478, 30.622053, -87.434074, 30.690447], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_sw_16_1_20110817.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008721_sw_16_1_20110817.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_sw_16_1_20110817.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.434074, 30.622302], [-87.434379, 30.690447], [-87.503478, 30.690198], [-87.503124, 30.622053], [-87.434074, 30.622302]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-17T00:00:00Z", "naip:year": "2011", "proj:bbox": [451780, 3387825, 458398, 3395377], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7552, 6618], "eo:cloud_cover": 64, "proj:transform": [1, 0, 451780, 0, -1, 3395377, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0009", "bbox": [-87.503478, 30.68455, -87.434072, 30.752944], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_nw_16_1_20110817.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008721_nw_16_1_20110817.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_nw_16_1_20110817.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.434072, 30.684799], [-87.434377, 30.752944], [-87.503478, 30.752694], [-87.503125, 30.68455], [-87.434072, 30.684799]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-17T00:00:00Z", "naip:year": "2011", "proj:bbox": [451811, 3394751, 458425, 3402303], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7552, 6614], "eo:cloud_cover": 61, "proj:transform": [1, 0, 451811, 0, -1, 3402303, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0010", "bbox": [-87.440937, 30.684579, -87.371606, 30.752912], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_ne_16_1_20110817.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008721_ne_16_1_20110817.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008721_ne_16_1_20110817.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.371606, 30.684794], [-87.371867, 30.752912], [-87.440937, 30.752696], [-87.440628, 30.684579], [-87.371606, 30.684794]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-17T00:00:00Z", "naip:year": "2011", "proj:bbox": [457797, 3394729, 464408, 3402278], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7549, 6611], "eo:cloud_cover": 31, "proj:transform": [1, 0, 457797, 0, -1, 3402278, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0011", "bbox": [-87.315859, 30.934648, -87.246684, 31.002851], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008706_ne_16_1_20110817.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008706_ne_16_1_20110817.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008706_ne_16_1_20110817.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.246684, 30.934798], [-87.246859, 31.002851], [-87.315859, 31.0027], [-87.315635, 30.934648], [-87.246684, 30.934798]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-17T00:00:00Z", "naip:year": "2011", "proj:bbox": [469847, 3422402, 476434, 3429944], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7542, 6587], "eo:cloud_cover": 41, "proj:transform": [1, 0, 469847, 0, -1, 3429944, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0012", "bbox": [-87.440942, 30.93458, -87.371596, 31.002921], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008705_ne_16_1_20110817.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008705_ne_16_1_20110817.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008705_ne_16_1_20110817.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.371596, 30.934797], [-87.37186, 31.002921], [-87.440942, 31.002704], [-87.440629, 30.93458], [-87.371596, 30.934797]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-17T00:00:00Z", "naip:year": "2011", "proj:bbox": [457906, 3422435, 464501, 3429985], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7550, 6595], "eo:cloud_cover": 4, "proj:transform": [1, 0, 457906, 0, -1, 3429985, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0013", "bbox": [-87.378406, 30.934615, -87.309145, 31.002887], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008706_nw_16_1_20110817.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008706_nw_16_1_20110817.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008706_nw_16_1_20110817.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.309145, 30.934799], [-87.309365, 31.002887], [-87.378406, 31.002704], [-87.378137, 30.934615], [-87.309145, 30.934799]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-17T00:00:00Z", "naip:year": "2011", "proj:bbox": [463876, 3422417, 470467, 3429963], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7546, 6591], "eo:cloud_cover": 2, "proj:transform": [1, 0, 463876, 0, -1, 3429963, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0014", "bbox": [-87.628547, 30.496984, -87.558991, 30.565507], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_sw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008728_sw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_sw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.558991, 30.497299], [-87.559382, 30.565507], [-87.628547, 30.565192], [-87.628108, 30.496984], [-87.558991, 30.497299]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [439724, 3374025, 446357, 3381584], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7559, 6633], "eo:cloud_cover": 17, "proj:transform": [1, 0, 439724, 0, -1, 3381584, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0015", "bbox": [-86.940689, 30.934744, -86.871762, 31.002757], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008601_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008601_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008601_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.871853, 30.934744], [-86.871762, 31.002707], [-86.940647, 31.002757], [-86.940689, 30.934794], [-86.871853, 30.934744]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [505666, 3422377, 512242, 3429909], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7532, 6576], "eo:cloud_cover": 54, "proj:transform": [1, 0, 505666, 0, -1, 3429909, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0016", "bbox": [-87.003143, 30.934773, -86.93431, 31.002726], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008601_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008601_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008601_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.934356, 30.934773], [-86.93431, 31.002709], [-87.003143, 31.002726], [-87.00314, 30.934789], [-86.934356, 30.934773]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [499700, 3422375, 506271, 3429904], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7529, 6571], "eo:cloud_cover": 13, "proj:transform": [1, 0, 499700, 0, -1, 3429904, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0017", "bbox": [-86.815777, 30.934677, -86.746678, 31.00282], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008602_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008602_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008602_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.746858, 30.934677], [-86.746678, 31.002703], [-86.815646, 31.00282], [-86.815777, 30.934794], [-86.746858, 30.934677]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [517599, 3422390, 524183, 3429929], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7539, 6584], "eo:cloud_cover": 59, "proj:transform": [1, 0, 517599, 0, -1, 3429929, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0018", "bbox": [-86.878228, 30.934712, -86.809225, 31.002794], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008602_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008602_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008602_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.809361, 30.934712], [-86.809225, 31.002711], [-86.878142, 31.002794], [-86.878228, 30.934795], [-86.809361, 30.934712]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [511633, 3422382, 518212, 3429918], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7536, 6579], "eo:cloud_cover": 29, "proj:transform": [1, 0, 511633, 0, -1, 3429918, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0019", "bbox": [-87.566035, 30.934518, -87.496517, 31.002979], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008704_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008704_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008704_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.496517, 30.934802], [-87.49687, 31.002979], [-87.566035, 31.002694], [-87.565633, 30.934518], [-87.496517, 30.934802]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [445964, 3422482, 452567, 3430038], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7556, 6603], "eo:cloud_cover": 52, "proj:transform": [1, 0, 445964, 0, -1, 3430038, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0020", "bbox": [-87.62857, 30.934491, -87.558977, 31.003012], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008704_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008704_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008704_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.558977, 30.934808], [-87.559374, 31.003012], [-87.62857, 31.002694], [-87.628123, 30.934491], [-87.558977, 30.934808]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [439994, 3422511, 446600, 3430070], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7559, 6606], "eo:cloud_cover": 39, "proj:transform": [1, 0, 439994, 0, -1, 3430070, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0021", "bbox": [-87.628569, 30.871988, -87.55898, 30.940509], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008704_sw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008704_sw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008704_sw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.55898, 30.872305], [-87.559377, 30.940509], [-87.628569, 30.940191], [-87.628123, 30.871988], [-87.55898, 30.872305]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [439955, 3415584, 446565, 3423143], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7559, 6610], "eo:cloud_cover": 29, "proj:transform": [1, 0, 439955, 0, -1, 3423143, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0022", "bbox": [-87.503488, 30.93455, -87.434056, 31.002952], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008705_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008705_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008705_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.434056, 30.934801], [-87.434365, 31.002952], [-87.503488, 31.002701], [-87.503131, 30.93455], [-87.434056, 30.934801]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [451935, 3422457, 458534, 3430010], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7553, 6599], "eo:cloud_cover": 84, "proj:transform": [1, 0, 451935, 0, -1, 3430010, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0023", "bbox": [-87.06569, 30.934773, -86.996857, 31.002726], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008708_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008708_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008708_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.99686, 30.934789], [-86.996857, 31.002726], [-87.06569, 31.002709], [-87.065644, 30.934773], [-86.99686, 30.934789]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [493729, 3422375, 500300, 3429904], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7529, 6571], "eo:cloud_cover": 56, "proj:transform": [1, 0, 493729, 0, -1, 3429904, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0024", "bbox": [-87.941273, 30.809325, -87.871271, 30.878173], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008709_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.871271, 30.80981], [-87.871889, 30.878173], [-87.941273, 30.877687], [-87.940605, 30.809325], [-87.871271, 30.80981]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [410024, 3408849, 416657, 3416426], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7577, 6633], "eo:cloud_cover": 58, "proj:transform": [1, 0, 410024, 0, -1, 3416426, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0025", "bbox": [-88.003818, 30.809299, -87.933721, 30.878206], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008709_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.933721, 30.809817], [-87.934384, 30.878206], [-88.003818, 30.877686], [-88.003106, 30.809299], [-87.933721, 30.809817]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [404045, 3408898, 410683, 3416478], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7580, 6638], "eo:cloud_cover": 65, "proj:transform": [1, 0, 404045, 0, -1, 3416478, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0026", "bbox": [-87.941269, 30.746832, -87.871272, 30.815671], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_se_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008709_se_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_se_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.871272, 30.747317], [-87.871889, 30.815671], [-87.941269, 30.815185], [-87.940603, 30.746832], [-87.871272, 30.747317]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [409966, 3401923, 416603, 3409499], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7576, 6637], "eo:cloud_cover": 52, "proj:transform": [1, 0, 409966, 0, -1, 3409499, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0027", "bbox": [-88.003816, 30.746797, -87.933724, 30.815704], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_sw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008709_sw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008709_sw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.933724, 30.747315], [-87.934385, 30.815704], [-88.003816, 30.815185], [-88.003106, 30.746797], [-87.933724, 30.747315]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [403983, 3401971, 410625, 3409551], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7580, 6642], "eo:cloud_cover": 43, "proj:transform": [1, 0, 403983, 0, -1, 3409551, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0028", "bbox": [-87.878737, 30.809358, -87.80881, 30.878137], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008710_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.80881, 30.809809], [-87.809384, 30.878137], [-87.878737, 30.877684], [-87.878114, 30.809358], [-87.80881, 30.809809]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [416002, 3408804, 422632, 3416377], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7573, 6630], "eo:cloud_cover": 46, "proj:transform": [1, 0, 416002, 0, -1, 3416377, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0029", "bbox": [-87.878732, 30.746864, -87.80881, 30.815634], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_sw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008710_sw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_sw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.80881, 30.747315], [-87.809382, 30.815634], [-87.878732, 30.815182], [-87.878111, 30.746864], [-87.80881, 30.747315]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [415948, 3401878, 422582, 3409450], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7572, 6634], "eo:cloud_cover": 42, "proj:transform": [1, 0, 415948, 0, -1, 3409450, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0030", "bbox": [-87.691106, 30.809455, -87.621436, 30.878045], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008711_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.621436, 30.809805], [-87.621876, 30.878045], [-87.691106, 30.877694], [-87.690617, 30.809455], [-87.621436, 30.809805]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [433938, 3408689, 440556, 3416252], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7563, 6618], "eo:cloud_cover": 16, "proj:transform": [1, 0, 433938, 0, -1, 3416252, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0031", "bbox": [-87.691108, 30.74696, -87.621442, 30.815542], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_se_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008711_se_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_se_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.621442, 30.74731], [-87.62188, 30.815542], [-87.691108, 30.815191], [-87.69062, 30.74696], [-87.621442, 30.74731]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [433895, 3401763, 440517, 3409325], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7562, 6622], "eo:cloud_cover": 16, "proj:transform": [1, 0, 433895, 0, -1, 3409325, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0032", "bbox": [-87.628569, 30.809484, -87.558973, 30.878015], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008712_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008712_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008712_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.558973, 30.809801], [-87.559369, 30.878015], [-87.628569, 30.877697], [-87.628124, 30.809484], [-87.558973, 30.809801]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [439916, 3408657, 446531, 3416217], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7560, 6615], "eo:cloud_cover": 7, "proj:transform": [1, 0, 439916, 0, -1, 3416217, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0033", "bbox": [-87.566019, 30.747015, -87.496524, 30.815477], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008712_se_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008712_se_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008712_se_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.496524, 30.747298], [-87.496874, 30.815477], [-87.566019, 30.815193], [-87.56562, 30.747015], [-87.496524, 30.747298]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [445860, 3401702, 452474, 3409258], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7556, 6614], "eo:cloud_cover": 49, "proj:transform": [1, 0, 445860, 0, -1, 3409258, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0034", "bbox": [-87.628559, 30.746989, -87.558978, 30.815511], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008712_sw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008712_sw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008712_sw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.558978, 30.747305], [-87.559372, 30.815511], [-87.628559, 30.815194], [-87.628115, 30.746989], [-87.558978, 30.747305]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [439878, 3401731, 446496, 3409290], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7559, 6618], "eo:cloud_cover": 3, "proj:transform": [1, 0, 439878, 0, -1, 3409290, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0035", "bbox": [-87.941266, 30.68433, -87.871274, 30.753168], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008717_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.871274, 30.684813], [-87.871889, 30.753168], [-87.941266, 30.752684], [-87.940602, 30.68433], [-87.871274, 30.684813]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [409908, 3394996, 416549, 3402572], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7576, 6641], "eo:cloud_cover": 33, "proj:transform": [1, 0, 409908, 0, -1, 3402572, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0036", "bbox": [-88.003814, 30.684295, -87.933727, 30.753202], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008717_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.933727, 30.684813], [-87.934386, 30.753202], [-88.003814, 30.752684], [-88.003106, 30.684295], [-87.933727, 30.684813]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [403921, 3395044, 410567, 3402624], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7580, 6646], "eo:cloud_cover": 12, "proj:transform": [1, 0, 403921, 0, -1, 3402624, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0037", "bbox": [-87.941265, 30.621827, -87.871277, 30.690665], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_se_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008717_se_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_se_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.871277, 30.62231], [-87.871891, 30.690665], [-87.941265, 30.690181], [-87.940603, 30.621827], [-87.871277, 30.62231]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [409850, 3388069, 416495, 3395645], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7576, 6645], "eo:cloud_cover": 54, "proj:transform": [1, 0, 409850, 0, -1, 3395645, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0038", "bbox": [-88.003804, 30.621802, -87.933732, 30.6907], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_sw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008717_sw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008717_sw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.933732, 30.622318], [-87.934389, 30.6907], [-88.003804, 30.690182], [-88.003098, 30.621802], [-87.933732, 30.622318]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [403860, 3388118, 410509, 3395697], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7579, 6649], "eo:cloud_cover": 77, "proj:transform": [1, 0, 403860, 0, -1, 3395697, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0039", "bbox": [-87.878728, 30.684361, -87.808821, 30.75314], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008718_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.808821, 30.684811], [-87.809392, 30.75314], [-87.878728, 30.752689], [-87.878109, 30.684361], [-87.808821, 30.684811]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [415894, 3394951, 422531, 3402524], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7573, 6637], "eo:cloud_cover": 12, "proj:transform": [1, 0, 415894, 0, -1, 3402524, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0040", "bbox": [-87.878725, 30.621858, -87.808823, 30.690637], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_sw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008718_sw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_sw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.808823, 30.622307], [-87.809392, 30.690637], [-87.878725, 30.690186], [-87.878107, 30.621858], [-87.808823, 30.622307]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [415840, 3388024, 422481, 3395597], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7573, 6641], "eo:cloud_cover": 10, "proj:transform": [1, 0, 415840, 0, -1, 3395597, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0041", "bbox": [-87.6911, 30.684456, -87.621438, 30.753047], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008719_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.621438, 30.684805], [-87.621875, 30.753047], [-87.6911, 30.752696], [-87.690613, 30.684456], [-87.621438, 30.684805]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [433853, 3394836, 440479, 3402399], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7563, 6626], "eo:cloud_cover": 3, "proj:transform": [1, 0, 433853, 0, -1, 3402399, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0042", "bbox": [-87.691103, 30.62196, -87.621445, 30.690542], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_se_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008719_se_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_se_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.621445, 30.622309], [-87.621882, 30.690542], [-87.691103, 30.690192], [-87.690618, 30.62196], [-87.621445, 30.622309]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [433810, 3387910, 440440, 3395472], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7562, 6630], "eo:cloud_cover": 99, "proj:transform": [1, 0, 433810, 0, -1, 3395472, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0043", "bbox": [-87.566019, 30.684519, -87.496527, 30.752981], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008720_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.496527, 30.684801], [-87.496877, 30.752981], [-87.566019, 30.752698], [-87.565621, 30.684519], [-87.496527, 30.684801]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [445825, 3394776, 452443, 3402332], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7556, 6618], "eo:cloud_cover": 80, "proj:transform": [1, 0, 445825, 0, -1, 3402332, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0044", "bbox": [-87.62856, 30.684484, -87.558983, 30.753015], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008720_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.558983, 30.6848], [-87.559376, 30.753015], [-87.62856, 30.752699], [-87.628117, 30.684484], [-87.558983, 30.6848]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [439839, 3394804, 446461, 3402364], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7560, 6622], "eo:cloud_cover": 30, "proj:transform": [1, 0, 439839, 0, -1, 3402364, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0045", "bbox": [-87.56602, 30.622022, -87.496532, 30.690476], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_se_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008720_se_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_se_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.496532, 30.622304], [-87.49688, 30.690476], [-87.56602, 30.690193], [-87.565623, 30.622022], [-87.496532, 30.622304]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [445790, 3387850, 452412, 3395405], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7555, 6622], "eo:cloud_cover": 82, "proj:transform": [1, 0, 445790, 0, -1, 3395405, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0046", "bbox": [-87.628562, 30.621988, -87.558988, 30.69051], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_sw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008720_sw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008720_sw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.558988, 30.622303], [-87.559381, 30.69051], [-87.628562, 30.690194], [-87.62812, 30.621988], [-87.558988, 30.622303]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [439800, 3387878, 446426, 3395437], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7559, 6626], "eo:cloud_cover": 16, "proj:transform": [1, 0, 439800, 0, -1, 3395437, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0047", "bbox": [-87.941265, 30.559332, -87.871282, 30.628171], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008725_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008725_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008725_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.871282, 30.559814], [-87.871893, 30.628171], [-87.941265, 30.627687], [-87.940604, 30.559332], [-87.871282, 30.559814]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [409792, 3381143, 416441, 3388719], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7576, 6649], "eo:cloud_cover": 43, "proj:transform": [1, 0, 409792, 0, -1, 3388719, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0048", "bbox": [-87.941255, 30.496828, -87.871287, 30.565666], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008725_se_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008725_se_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008725_se_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.871287, 30.497309], [-87.871897, 30.565666], [-87.941255, 30.565183], [-87.940596, 30.496828], [-87.871287, 30.497309]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [409735, 3374216, 416387, 3381792], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7576, 6652], "eo:cloud_cover": 4, "proj:transform": [1, 0, 409735, 0, -1, 3381792, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0049", "bbox": [-87.878723, 30.559362, -87.808825, 30.628132], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008726_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.808825, 30.559811], [-87.809393, 30.628132], [-87.878723, 30.627682], [-87.878107, 30.559362], [-87.808825, 30.559811]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [415786, 3381098, 422431, 3388670], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7572, 6645], "eo:cloud_cover": 9, "proj:transform": [1, 0, 415786, 0, -1, 3388670, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0050", "bbox": [-87.878723, 30.496867, -87.808828, 30.565637], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_sw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008726_sw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_sw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.808828, 30.497315], [-87.809395, 30.565637], [-87.878723, 30.565187], [-87.878108, 30.496867], [-87.808828, 30.497315]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [415732, 3374172, 422381, 3381744], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7572, 6649], "eo:cloud_cover": 84, "proj:transform": [1, 0, 415732, 0, -1, 3381744, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0051", "bbox": [-87.691097, 30.559454, -87.621453, 30.628045], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008727_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.621453, 30.559803], [-87.621889, 30.628045], [-87.691097, 30.627696], [-87.690613, 30.559454], [-87.621453, 30.559803]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [433768, 3380983, 440401, 3388546], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7563, 6633], "eo:cloud_cover": 22, "proj:transform": [1, 0, 433768, 0, -1, 3388546, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0052", "bbox": [-87.691091, 30.496957, -87.621451, 30.565539], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_se_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008727_se_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_se_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.621451, 30.497305], [-87.621886, 30.565539], [-87.691091, 30.565191], [-87.690608, 30.496957], [-87.621451, 30.497305]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [433726, 3374057, 440363, 3381619], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7562, 6637], "eo:cloud_cover": 12, "proj:transform": [1, 0, 433726, 0, -1, 3381619, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0053", "bbox": [-87.56601, 30.559516, -87.496536, 30.627979], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008728_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.496536, 30.559797], [-87.496884, 30.627979], [-87.56601, 30.627696], [-87.565614, 30.559516], [-87.496536, 30.559797]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [445756, 3380923, 452381, 3388479], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7556, 6625], "eo:cloud_cover": 24, "proj:transform": [1, 0, 445756, 0, -1, 3388479, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0054", "bbox": [-87.628554, 30.559491, -87.558995, 30.628014], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008728_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.558995, 30.559806], [-87.559386, 30.628014], [-87.628554, 30.627698], [-87.628114, 30.559491], [-87.558995, 30.559806]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [439762, 3380952, 446391, 3388511], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7559, 6629], "eo:cloud_cover": 5, "proj:transform": [1, 0, 439762, 0, -1, 3388511, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0055", "bbox": [-87.566012, 30.497018, -87.496531, 30.565481], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_se_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008728_se_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008728_se_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.496531, 30.497299], [-87.496878, 30.565481], [-87.566012, 30.565199], [-87.565617, 30.497018], [-87.496531, 30.497299]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [445721, 3373997, 452351, 3381553], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7556, 6630], "eo:cloud_cover": 79, "proj:transform": [1, 0, 445721, 0, -1, 3381553, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0056", "bbox": [-87.941283, 30.934327, -87.871262, 31.003175], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008701_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.871262, 30.934813], [-87.871883, 31.003175], [-87.941283, 31.002688], [-87.940613, 30.934327], [-87.871262, 30.934813]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [410140, 3422703, 416766, 3430280], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7577, 6626], "eo:cloud_cover": 62, "proj:transform": [1, 0, 410140, 0, -1, 3430280, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0057", "bbox": [-88.003827, 30.9343, -87.93372, 31.003207], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008701_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.93372, 30.93482], [-87.934386, 31.003207], [-88.003827, 31.002686], [-88.003111, 30.9343], [-87.93372, 30.93482]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [404169, 3422752, 410799, 3430332], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7580, 6630], "eo:cloud_cover": 7, "proj:transform": [1, 0, 404169, 0, -1, 3430332, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0058", "bbox": [-87.941277, 30.871827, -87.871261, 30.940674], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_se_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008701_se_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_se_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.871261, 30.872312], [-87.87188, 30.940674], [-87.941277, 30.940187], [-87.940609, 30.871827], [-87.871261, 30.872312]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [410082, 3415776, 416712, 3423353], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7577, 6630], "eo:cloud_cover": 53, "proj:transform": [1, 0, 410082, 0, -1, 3423353, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0059", "bbox": [-88.003822, 30.8718, -87.93372, 30.940707], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_sw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008701_sw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008701_sw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.93372, 30.872319], [-87.934384, 30.940707], [-88.003822, 30.940186], [-88.003108, 30.8718], [-87.93372, 30.872319]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [404107, 3415825, 410741, 3423405], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7580, 6634], "eo:cloud_cover": 57, "proj:transform": [1, 0, 404107, 0, -1, 3423405, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0066", "bbox": [-86.441023, 30.934491, -86.37143, 31.003012], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008605_ne_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008605_ne_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008605_ne_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.371877, 30.934491], [-86.37143, 31.002694], [-86.440626, 31.003012], [-86.441023, 30.934808], [-86.371877, 30.934491]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [553400, 3422511, 560006, 3430070], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7559, 6606], "eo:cloud_cover": 86, "proj:transform": [1, 0, 553400, 0, -1, 3430070, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0060", "bbox": [-87.878739, 30.934361, -87.808804, 31.00314], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_nw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008702_nw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_nw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.808804, 30.934813], [-87.80938, 31.00314], [-87.878739, 31.002686], [-87.878114, 30.934361], [-87.808804, 30.934813]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [416111, 3422658, 422733, 3430231], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7573, 6622], "eo:cloud_cover": 70, "proj:transform": [1, 0, 416111, 0, -1, 3430231, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0061", "bbox": [-87.878743, 30.87186, -87.808801, 30.940638], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_sw_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008702_sw_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_sw_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.808801, 30.872311], [-87.809376, 30.940638], [-87.878743, 30.940186], [-87.878119, 30.87186], [-87.808801, 30.872311]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [416056, 3415731, 422683, 3423304], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7573, 6627], "eo:cloud_cover": 94, "proj:transform": [1, 0, 416056, 0, -1, 3423304, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0062", "bbox": [-87.691116, 30.934452, -87.621426, 31.003042], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_ne_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008703_ne_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_ne_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.621426, 30.934803], [-87.621868, 31.003042], [-87.691116, 31.00269], [-87.690624, 30.934452], [-87.621426, 30.934803]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [434023, 3422542, 440634, 3430105], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7563, 6611], "eo:cloud_cover": 85, "proj:transform": [1, 0, 434023, 0, -1, 3430105, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0063", "bbox": [-87.691116, 30.871958, -87.621431, 30.940539], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_se_16_1_20110816.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008703_se_16_1_20110816.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_se_16_1_20110816.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.621431, 30.872309], [-87.621872, 30.940539], [-87.691116, 30.940188], [-87.690626, 30.871958], [-87.621431, 30.872309]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-16T00:00:00Z", "naip:year": "2011", "proj:bbox": [433980, 3415616, 440595, 3423178], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7562, 6615], "eo:cloud_cover": 2, "proj:transform": [1, 0, 433980, 0, -1, 3423178, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0064", "bbox": [-86.565944, 30.93455, -86.496512, 31.002952], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008604_ne_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008604_ne_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008604_ne_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.496869, 30.93455], [-86.496512, 31.002701], [-86.565635, 31.002952], [-86.565944, 30.934801], [-86.496869, 30.93455]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [541466, 3422457, 548065, 3430010], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7553, 6599], "eo:cloud_cover": 40, "proj:transform": [1, 0, 541466, 0, -1, 3430010, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0065", "bbox": [-86.628404, 30.93458, -86.559058, 31.002921], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008604_nw_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008604_nw_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008604_nw_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.559371, 30.93458], [-86.559058, 31.002704], [-86.62814, 31.002921], [-86.628404, 30.934797], [-86.559371, 30.93458]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [535499, 3422435, 542094, 3429985], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7550, 6595], "eo:cloud_cover": 27, "proj:transform": [1, 0, 535499, 0, -1, 3429985, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0067", "bbox": [-86.503483, 30.934518, -86.433965, 31.002979], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008605_nw_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008605_nw_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008605_nw_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.434367, 30.934518], [-86.433965, 31.002694], [-86.50313, 31.002979], [-86.503483, 30.934802], [-86.434367, 30.934518]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [547433, 3422482, 554036, 3430038], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7556, 6603], "eo:cloud_cover": 35, "proj:transform": [1, 0, 547433, 0, -1, 3430038, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0068", "bbox": [-86.316114, 30.934419, -86.246339, 31.003078], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008606_ne_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008606_ne_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008606_ne_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.246875, 30.934419], [-86.246339, 31.002692], [-86.315627, 31.003078], [-86.316114, 30.934803], [-86.246875, 30.934419]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [565333, 3422577, 571948, 3430144], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7567, 6615], "eo:cloud_cover": 22, "proj:transform": [1, 0, 565333, 0, -1, 3430144, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0069", "bbox": [-86.378574, 30.934452, -86.308884, 31.003042], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008606_nw_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008606_nw_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008606_nw_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.309376, 30.934452], [-86.308884, 31.00269], [-86.378132, 31.003042], [-86.378574, 30.934803], [-86.309376, 30.934452]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [559366, 3422542, 565977, 3430105], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7563, 6611], "eo:cloud_cover": 97, "proj:transform": [1, 0, 559366, 0, -1, 3430105, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0070", "bbox": [-86.191196, 30.934361, -86.121261, 31.00314], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008607_ne_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008607_ne_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008607_ne_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.121886, 30.934361], [-86.121261, 31.002686], [-86.19062, 31.00314], [-86.191196, 30.934813], [-86.121886, 30.934361]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [577267, 3422658, 583889, 3430231], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7573, 6622], "eo:cloud_cover": 32, "proj:transform": [1, 0, 577267, 0, -1, 3430231, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0071", "bbox": [-86.253655, 30.934391, -86.183805, 31.00311], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008607_nw_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008607_nw_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008607_nw_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.184386, 30.934391], [-86.183805, 31.002691], [-86.253123, 31.00311], [-86.253655, 30.93481], [-86.184386, 30.934391]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [571300, 3422616, 577918, 3430186], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7570, 6618], "eo:cloud_cover": 68, "proj:transform": [1, 0, 571300, 0, -1, 3430186, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0072", "bbox": [-86.06628, 30.9343, -85.996173, 31.003207], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008608_ne_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008608_ne_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008608_ne_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.996889, 30.9343], [-85.996173, 31.002686], [-86.065614, 31.003207], [-86.06628, 30.93482], [-85.996889, 30.9343]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [589201, 3422752, 595831, 3430332], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7580, 6630], "eo:cloud_cover": 30, "proj:transform": [1, 0, 589201, 0, -1, 3430332, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0073", "bbox": [-86.128738, 30.934327, -86.058717, 31.003175], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008608_nw_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008608_nw_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008608_nw_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.059387, 30.934327], [-86.058717, 31.002688], [-86.128117, 31.003175], [-86.128738, 30.934813], [-86.059387, 30.934327]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [583234, 3422703, 589860, 3430280], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7577, 6626], "eo:cloud_cover": 3, "proj:transform": [1, 0, 583234, 0, -1, 3430280, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0074", "bbox": [-85.816455, 30.934167, -85.746007, 31.00333], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008502_ne_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008502_ne_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008502_ne_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.746902, 30.934167], [-85.746007, 31.002673], [-85.815609, 31.00333], [-85.816455, 30.934822], [-85.746902, 30.934167]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [613069, 3422979, 619715, 3430573], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7594, 6646], "eo:cloud_cover": 52, "proj:transform": [1, 0, 613069, 0, -1, 3430573, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0075", "bbox": [-86.003823, 30.934269, -85.933631, 31.003236], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008501_nw_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008501_nw_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008501_nw_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.934391, 30.934269], [-85.933631, 31.002681], [-86.003112, 31.003236], [-86.003823, 30.934823], [-85.934391, 30.934269]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [595168, 3422804, 601802, 3430387], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7583, 6634], "eo:cloud_cover": 8, "proj:transform": [1, 0, 595168, 0, -1, 3430387, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0076", "bbox": [-85.941366, 30.934235, -85.871089, 31.00327], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008501_ne_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008501_ne_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008501_ne_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.871894, 30.934235], [-85.871089, 31.002681], [-85.940611, 31.00327], [-85.941366, 30.934823], [-85.871894, 30.934235]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [601135, 3422859, 607773, 3430446], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7587, 6638], "eo:cloud_cover": 59, "proj:transform": [1, 0, 601135, 0, -1, 3430446, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0077", "bbox": [-86.753316, 30.934648, -86.684141, 31.002851], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008603_nw_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008603_nw_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008603_nw_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.684365, 30.934648], [-86.684141, 31.0027], [-86.753141, 31.002851], [-86.753316, 30.934798], [-86.684365, 30.934648]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [523566, 3422402, 530153, 3429944], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7542, 6587], "eo:cloud_cover": 64, "proj:transform": [1, 0, 523566, 0, -1, 3429944, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0078", "bbox": [-86.690855, 30.934615, -86.621594, 31.002887], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008603_ne_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30086/m_3008603_ne_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30086/m_3008603_ne_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-86.621863, 30.934615], [-86.621594, 31.002704], [-86.690635, 31.002887], [-86.690855, 30.934799], [-86.621863, 30.934615]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [529533, 3422417, 536124, 3429963], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7546, 6591], "eo:cloud_cover": 21, "proj:transform": [1, 0, 529533, 0, -1, 3429963, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0079", "bbox": [-85.629082, 30.934072, -85.558378, 31.003423], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008504_nw_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008504_nw_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008504_nw_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.559409, 30.934072], [-85.558378, 31.002663], [-85.628101, 31.003423], [-85.629082, 30.934829], [-85.559409, 30.934072]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [630971, 3423185, 637629, 3430789], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7604, 6658], "eo:cloud_cover": 65, "proj:transform": [1, 0, 630971, 0, -1, 3430789, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0080", "bbox": [-85.566619, 30.934046, -85.49583, 31.003456], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008504_ne_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008504_ne_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008504_ne_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.496906, 30.934046], [-85.49583, 31.002662], [-85.565593, 31.003456], [-85.566619, 30.934838], [-85.496906, 30.934046]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [636939, 3423261, 643601, 3430868], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7607, 6662], "eo:cloud_cover": 95, "proj:transform": [1, 0, 636939, 0, -1, 3430868, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0081", "bbox": [-85.753989, 30.934141, -85.683456, 31.003364], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008503_nw_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008503_nw_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008503_nw_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.684396, 30.934141], [-85.683456, 31.002673], [-85.753099, 31.003364], [-85.753989, 30.934831], [-85.684396, 30.934141]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [619037, 3423045, 625687, 3430642], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7597, 6650], "eo:cloud_cover": 39, "proj:transform": [1, 0, 619037, 0, -1, 3430642, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0082", "bbox": [-85.691535, 30.934103, -85.620917, 31.003395], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008503_ne_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008503_ne_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008503_ne_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.621902, 30.934103], [-85.620917, 31.002669], [-85.6906, 31.003395], [-85.691535, 30.934827], [-85.621902, 30.934103]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [625004, 3423113, 631658, 3430714], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7601, 6654], "eo:cloud_cover": 26, "proj:transform": [1, 0, 625004, 0, -1, 3430714, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0001", "bbox": [-85.441706, 30.933975, -85.370747, 31.003522], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008505_ne_16_1_20110825.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008505_ne_16_1_20110825.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008505_ne_16_1_20110825.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.371913, 30.933975], [-85.370747, 31.00266], [-85.440589, 31.003522], [-85.441706, 30.934836], [-85.371913, 30.933975]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-25T00:00:00Z", "naip:year": "2011", "proj:bbox": [648874, 3423421, 655544, 3431036], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7615, 6670], "eo:cloud_cover": 89, "proj:transform": [1, 0, 648874, 0, -1, 3431036, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0002", "bbox": [-85.504167, 30.934008, -85.433293, 31.003486], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008505_nw_16_1_20110825.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008505_nw_16_1_20110825.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008505_nw_16_1_20110825.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.434414, 30.934008], [-85.433293, 31.002658], [-85.503096, 31.003486], [-85.504167, 30.934834], [-85.434414, 30.934008]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-25T00:00:00Z", "naip:year": "2011", "proj:bbox": [642906, 3423339, 649572, 3430950], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7611, 6666], "eo:cloud_cover": 33, "proj:transform": [1, 0, 642906, 0, -1, 3430950, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0083", "bbox": [-85.87891, 30.934198, -85.808547, 31.003302], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008502_nw_16_1_20110815.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008502_nw_16_1_20110815.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008502_nw_16_1_20110815.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.809397, 30.934198], [-85.808547, 31.002679], [-85.87811, 31.003302], [-85.87891, 30.934819], [-85.809397, 30.934198]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-15T00:00:00Z", "naip:year": "2011", "proj:bbox": [607102, 3422917, 613744, 3430508], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7591, 6642], "eo:cloud_cover": 26, "proj:transform": [1, 0, 607102, 0, -1, 3430508, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0086", "bbox": [-87.816197, 30.87189, -87.746352, 30.940609], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_se_16_1_20110801.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008702_se_16_1_20110801.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_se_16_1_20110801.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.746352, 30.872308], [-87.746882, 30.940609], [-87.816197, 30.94019], [-87.815618, 30.87189], [-87.746352, 30.872308]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-01T00:00:00Z", "naip:year": "2011", "proj:bbox": [422031, 3415689, 428653, 3423259], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7570, 6622], "eo:cloud_cover": 40, "proj:transform": [1, 0, 422031, 0, -1, 3423259, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0087", "bbox": [-87.753661, 30.934419, -87.683886, 31.003078], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_nw_16_1_20110801.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008703_nw_16_1_20110801.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_nw_16_1_20110801.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.683886, 30.934803], [-87.684373, 31.003078], [-87.753661, 31.002692], [-87.753125, 30.934419], [-87.683886, 30.934803]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-01T00:00:00Z", "naip:year": "2011", "proj:bbox": [428052, 3422577, 434667, 3430144], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7567, 6615], "eo:cloud_cover": 36, "proj:transform": [1, 0, 428052, 0, -1, 3430144, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0088", "bbox": [-87.753652, 30.871926, -87.683891, 30.940576], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_sw_16_1_20110801.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008703_sw_16_1_20110801.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008703_sw_16_1_20110801.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.683891, 30.87231], [-87.684377, 30.940576], [-87.753652, 30.94019], [-87.753117, 30.871926], [-87.683891, 30.87231]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-01T00:00:00Z", "naip:year": "2011", "proj:bbox": [428006, 3415651, 434624, 3423217], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7566, 6618], "eo:cloud_cover": 23, "proj:transform": [1, 0, 428006, 0, -1, 3423217, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0089", "bbox": [-87.816182, 30.55939, -87.746368, 30.6281], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_ne_16_1_20110731.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008726_ne_16_1_20110731.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_ne_16_1_20110731.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.746368, 30.559805], [-87.746892, 30.6281], [-87.816182, 30.627684], [-87.815609, 30.55939], [-87.746368, 30.559805]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-07-31T00:00:00Z", "naip:year": "2011", "proj:bbox": [421780, 3381056, 428421, 3388625], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7569, 6641], "eo:cloud_cover": 36, "proj:transform": [1, 0, 421780, 0, -1, 3388625, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0090", "bbox": [-87.81619, 30.809396, -87.746349, 30.878106], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_ne_16_1_20110731.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008710_ne_16_1_20110731.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_ne_16_1_20110731.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.746349, 30.809814], [-87.746878, 30.878106], [-87.81619, 30.877688], [-87.815612, 30.809396], [-87.746349, 30.809814]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-07-31T00:00:00Z", "naip:year": "2011", "proj:bbox": [421981, 3408763, 428607, 3416332], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7569, 6626], "eo:cloud_cover": 84, "proj:transform": [1, 0, 421981, 0, -1, 3416332, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0091", "bbox": [-87.816185, 30.621895, -87.746357, 30.690605], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_se_16_1_20110731.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008718_se_16_1_20110731.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_se_16_1_20110731.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.746357, 30.62231], [-87.746882, 30.690605], [-87.816185, 30.690188], [-87.815611, 30.621895], [-87.746357, 30.62231]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-07-31T00:00:00Z", "naip:year": "2011", "proj:bbox": [421830, 3387983, 428468, 3395552], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7569, 6638], "eo:cloud_cover": 31, "proj:transform": [1, 0, 421830, 0, -1, 3395552, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0092", "bbox": [-87.816194, 30.746893, -87.746358, 30.815603], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_se_16_1_20110731.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008710_se_16_1_20110731.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008710_se_16_1_20110731.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.746358, 30.74731], [-87.746885, 30.815603], [-87.816194, 30.815185], [-87.815618, 30.746893], [-87.746358, 30.74731]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-07-31T00:00:00Z", "naip:year": "2011", "proj:bbox": [421930, 3401836, 428560, 3409405], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7569, 6630], "eo:cloud_cover": 24, "proj:transform": [1, 0, 421930, 0, -1, 3409405, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0093", "bbox": [-87.753639, 30.559423, -87.683911, 30.628074], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_nw_16_1_20110731.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008727_nw_16_1_20110731.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_nw_16_1_20110731.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.683911, 30.559805], [-87.68439, 30.628074], [-87.753639, 30.627692], [-87.753111, 30.559423], [-87.683911, 30.559805]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-07-31T00:00:00Z", "naip:year": "2011", "proj:bbox": [427774, 3381018, 434411, 3388584], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7566, 6637], "eo:cloud_cover": 61, "proj:transform": [1, 0, 427774, 0, -1, 3388584, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0094", "bbox": [-87.753654, 30.809423, -87.683898, 30.878073], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_nw_16_1_20110731.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008711_nw_16_1_20110731.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_nw_16_1_20110731.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.683898, 30.809806], [-87.684382, 30.878073], [-87.753654, 30.877688], [-87.75312, 30.809423], [-87.683898, 30.809806]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-07-31T00:00:00Z", "naip:year": "2011", "proj:bbox": [427959, 3408724, 434581, 3416290], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7566, 6622], "eo:cloud_cover": 29, "proj:transform": [1, 0, 427959, 0, -1, 3416290, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0095", "bbox": [-87.753646, 30.746928, -87.683895, 30.815579], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_sw_16_1_20110731.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008711_sw_16_1_20110731.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008711_sw_16_1_20110731.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.683895, 30.747312], [-87.684378, 30.815579], [-87.753646, 30.815194], [-87.753114, 30.746928], [-87.683895, 30.747312]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-07-31T00:00:00Z", "naip:year": "2011", "proj:bbox": [427913, 3401798, 434539, 3409364], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7566, 6626], "eo:cloud_cover": 63, "proj:transform": [1, 0, 427913, 0, -1, 3409364, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0096", "bbox": [-87.753639, 30.684424, -87.683903, 30.753075], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_nw_16_1_20110731.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008719_nw_16_1_20110731.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_nw_16_1_20110731.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.683903, 30.684807], [-87.684385, 30.753075], [-87.753639, 30.752691], [-87.753109, 30.684424], [-87.683903, 30.684807]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-07-31T00:00:00Z", "naip:year": "2011", "proj:bbox": [427867, 3394871, 434496, 3402437], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7566, 6629], "eo:cloud_cover": 26, "proj:transform": [1, 0, 427867, 0, -1, 3402437, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0097", "bbox": [-87.816189, 30.68439, -87.746357, 30.753109], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_ne_16_1_20110731.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008718_ne_16_1_20110731.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008718_ne_16_1_20110731.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.746357, 30.684806], [-87.746883, 30.753109], [-87.816189, 30.752692], [-87.815614, 30.68439], [-87.746357, 30.684806]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-07-31T00:00:00Z", "naip:year": "2011", "proj:bbox": [421880, 3394909, 428514, 3402479], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7570, 6634], "eo:cloud_cover": 1, "proj:transform": [1, 0, 421880, 0, -1, 3402479, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0098", "bbox": [-87.753644, 30.621929, -87.683901, 30.69057], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_sw_16_1_20110731.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008719_sw_16_1_20110731.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008719_sw_16_1_20110731.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.683901, 30.622311], [-87.684382, 30.69057], [-87.753644, 30.690187], [-87.753115, 30.621929], [-87.683901, 30.622311]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-07-31T00:00:00Z", "naip:year": "2011", "proj:bbox": [427820, 3387945, 434454, 3395510], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7565, 6634], "eo:cloud_cover": 73, "proj:transform": [1, 0, 427820, 0, -1, 3395510, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0099", "bbox": [-87.753635, 30.496927, -87.683911, 30.565569], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_sw_16_1_20110731.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008727_sw_16_1_20110731.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008727_sw_16_1_20110731.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.683911, 30.497308], [-87.684389, 30.565569], [-87.753635, 30.565186], [-87.753109, 30.496927], [-87.683911, 30.497308]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-07-31T00:00:00Z", "naip:year": "2011", "proj:bbox": [427728, 3374092, 434369, 3381657], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7565, 6641], "eo:cloud_cover": 90, "proj:transform": [1, 0, 427728, 0, -1, 3381657, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0084", "bbox": [-85.316796, 30.93392, -85.245667, 31.003585], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008506_ne_16_1_20110802.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30085/m_3008506_ne_16_1_20110802.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30085/m_3008506_ne_16_1_20110802.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-85.246924, 30.93392], [-85.245667, 31.002654], [-85.315589, 31.003585], [-85.316796, 30.934848], [-85.246924, 30.93392]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-02T00:00:00Z", "naip:year": "2011", "proj:bbox": [660809, 3423596, 667487, 3431217], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7621, 6678], "eo:cloud_cover": 52, "proj:transform": [1, 0, 660809, 0, -1, 3431217, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0085", "bbox": [-87.816195, 30.934391, -87.746345, 31.00311], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_ne_16_1_20110801.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008702_ne_16_1_20110801.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008702_ne_16_1_20110801.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.746345, 30.93481], [-87.746877, 31.00311], [-87.816195, 31.002691], [-87.815614, 30.934391], [-87.746345, 30.93481]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-08-01T00:00:00Z", "naip:year": "2011", "proj:bbox": [422082, 3422616, 428700, 3430186], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7570, 6618], "eo:cloud_cover": 3, "proj:transform": [1, 0, 422082, 0, -1, 3430186, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]} +{"id": "pgstac-test-item-0100", "bbox": [-87.816179, 30.496894, -87.74637, 30.565604], "type": "Feature", "links": [], "assets": {"image": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_se_16_1_20110731.tif", "type": "image/tiff; application=geotiff; profile=cloud-optimized", "roles": ["data"], "title": "RGBIR COG tile", "eo:bands": [{"name": "Red", "common_name": "red"}, {"name": "Green", "common_name": "green"}, {"name": "Blue", "common_name": "blue"}, {"name": "NIR", "common_name": "nir", "description": "near-infrared"}]}, "metadata": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_fgdc_2011/30087/m_3008726_se_16_1_20110731.txt", "type": "text/plain", "roles": ["metadata"], "title": "FGDC Metdata"}, "thumbnail": {"href": "https://naipeuwest.blob.core.windows.net/naip/v002/al/2011/al_100cm_2011/30087/m_3008726_se_16_1_20110731.200.jpg", "type": "image/jpeg", "roles": ["thumbnail"], "title": "Thumbnail"}}, "geometry": {"type": "Polygon", "coordinates": [[[-87.74637, 30.497308], [-87.746892, 30.565604], [-87.816179, 30.565188], [-87.815608, 30.496894], [-87.74637, 30.497308]]]}, "collection": "pgstac-test-collection", "properties": {"gsd": 1, "datetime": "2011-07-31T00:00:00Z", "naip:year": "2011", "proj:bbox": [421730, 3374130, 428375, 3381699], "proj:epsg": 26916, "providers": [{"url": "https://www.fsa.usda.gov/programs-and-services/aerial-photography/imagery-programs/naip-imagery/", "name": "USDA Farm Service Agency", "roles": ["producer", "licensor"]}], "naip:state": "al", "proj:shape": [7569, 6645], "eo:cloud_cover": 50, "proj:transform": [1, 0, 421730, 0, -1, 3381699, 0, 0, 1]}, "stac_version": "1.0.0-beta.2", "stac_extensions": ["eo", "projection"]}