From a32463a4debe3366f9612c27f8279cad6ab8d3b0 Mon Sep 17 00:00:00 2001 From: Matthias Mohr Date: Thu, 1 Aug 2024 12:56:31 +0200 Subject: [PATCH] Improved and stricter schema --- CHANGELOG.md | 1 + examples/collection.json | 30 +-- examples/item.json | 44 ++--- json-schema/schema.json | 391 +++++++++++++++++++++++++-------------- 4 files changed, 285 insertions(+), 181 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f49806..b450ee6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Clarified how the coverages `eo:cloud_cover` and `eo:snow_cover` should be computed +- Improved and stricter schema ## [v1.1.0] - 2023-02-10 diff --git a/examples/collection.json b/examples/collection.json index 8bb6350..a182157 100644 --- a/examples/collection.json +++ b/examples/collection.json @@ -76,20 +76,6 @@ } ] }, - "links": [ - { - "rel": "root", - "href": "./collection.json", - "type": "application/json", - "title": "Simple Example Collection" - }, - { - "rel": "item", - "href": "./item.json", - "type": "application/geo+json", - "title": "20201211_223832_CS2" - } - ], "item_assets": { "analytic": { "type": "image/tiff; application=geotiff; profile=cloud-optimized", @@ -162,5 +148,19 @@ } ] } - } + }, + "links": [ + { + "rel": "root", + "href": "./collection.json", + "type": "application/json", + "title": "Simple Example Collection" + }, + { + "rel": "item", + "href": "./item.json", + "type": "application/geo+json", + "title": "20201211_223832_CS2" + } + ] } diff --git a/examples/item.json b/examples/item.json index ef2d1f2..54f48a4 100644 --- a/examples/item.json +++ b/examples/item.json @@ -5,6 +5,7 @@ ], "type": "Feature", "id": "20201211_223832_CS2", + "collection": "eo-collection", "bbox": [ 172.91173669923782, 1.3438851951615003, @@ -50,27 +51,6 @@ "eo:cloud_cover": 1.2, "eo:snow_cover": 0 }, - "collection": "eo-collection", - "links": [ - { - "rel": "root", - "href": "./collection.json", - "type": "application/json", - "title": "Simple Example Collection" - }, - { - "rel": "parent", - "href": "./collection.json", - "type": "application/json", - "title": "Simple Example Collection" - }, - { - "rel": "collection", - "href": "./collection.json", - "type": "application/json", - "title": "Simple Example Collection" - } - ], "assets": { "analytic": { "href": "https://storage.googleapis.com/open-cogs/stac-examples/20201211_223832_CS2_analytic.tif", @@ -147,5 +127,25 @@ } ] } - } + }, + "links": [ + { + "rel": "root", + "href": "./collection.json", + "type": "application/json", + "title": "Simple Example Collection" + }, + { + "rel": "parent", + "href": "./collection.json", + "type": "application/json", + "title": "Simple Example Collection" + }, + { + "rel": "collection", + "href": "./collection.json", + "type": "application/json", + "title": "Simple Example Collection" + } + ] } \ No newline at end of file diff --git a/json-schema/schema.json b/json-schema/schema.json index 6fda721..2c20add 100644 --- a/json-schema/schema.json +++ b/json-schema/schema.json @@ -2,11 +2,9 @@ "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://stac-extensions.github.io/eo/v2.0.0-beta.1/schema.json#", "title": "EO Extension", - "description": "STAC EO Extension for STAC Items.", + "description": "STAC EO Extension for STAC Items and STAC Collections.", "type": "object", - "required": [ - "stac_extensions" - ], + "required": ["stac_extensions", "type"], "properties": { "stac_extensions": { "type": "array", @@ -15,209 +13,314 @@ } } }, - "oneOf": [ + "allOf": [ { - "$comment": "This is the schema for STAC Items.", - "type": "object", - "required": [ - "type", - "properties", - "assets" - ], - "properties": { - "type": { - "const": "Feature" - }, + "$comment": "Items", + "if": { "properties": { - "$ref": "#/definitions/fields" - }, - "assets": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/fields" + "type": { + "const": "Feature" } } }, - "anyOf": [ - { - "properties": { + "then": { + "allOf": [ + { "properties": { - "$ref": "#/definitions/require_any_or_bands" + "properties": { + "$ref": "#/definitions/validate_properties" + } } + }, + { + "$ref": "#/definitions/validate_assets" } - }, - { - "$ref": "#/definitions/require_in_assets" - } - ] + ], + "anyOf": [ + { + "required": ["properties"], + "properties": { + "properties": { + "$ref": "#/definitions/require_properties" + } + } + }, + { + "$ref": "#/definitions/require_assets" + } + ] + } }, { - "$comment": "This is the schema for STAC Collections.", - "type": "object", - "required": [ - "type" - ], - "properties": { - "type": { - "const": "Collection" - }, - "assets": { - "$ref": "#/definitions/fields" - }, - "item_assets": { - "$ref": "#/definitions/fields" + "$comment": "Collections", + "if": { + "properties": { + "type": { + "const": "Collection" + } } }, - "anyOf": [ - { - "$ref": "#/definitions/require_in_item_assets" - }, - { - "$ref": "#/definitions/require_in_assets" - }, - { - "properties": { - "summaries": { - "$ref": "#/definitions/require_any_or_bands" + "then": { + "allOf": [ + { + "$ref": "#/definitions/validate_assets" + }, + { + "properties": { + "item_assets": { + "additionalProperties": { + "$ref": "#/definitions/validate_properties" + } + } + } + }, + { + "properties": { + "summaries": { + "type": "object", + "$comment": "We can't properly validate summary objects types (min/max or schemas) yet.", + "allOf": [ + { + "$ref": "#/definitions/validate_bands" + }, + { + "properties": { + "eo:cloud_cover": { + "type": ["array", "object"], + "items": { + "$ref": "#/definitions/eo:cloud_cover" + } + } + } + }, + { + "properties": { + "eo:common_name": { + "type": ["array", "object"], + "items": { + "$ref": "#/definitions/eo:common_name" + } + } + } + }, + { + "properties": { + "eo:center_wavelength": { + "type": ["array", "object"], + "items": { + "$ref": "#/definitions/eo:center_wavelength" + } + } + } + }, + { + "properties": { + "eo:full_width_half_max": { + "type": ["array", "object"], + "items": { + "$ref": "#/definitions/eo:full_width_half_max" + } + } + } + }, + { + "properties": { + "eo:solar_illumination": { + "type": ["array", "object"], + "items": { + "$ref": "#/definitions/eo:solar_illumination" + } + } + } + } + ] + } } } - } - ] + ], + "anyOf": [ + { + "$ref": "#/definitions/require_assets" + }, + { + "required": ["item_assets"], + "properties": { + "item_assets": { + "$ref": "#/definitions/asset_contains" + } + } + }, + { + "required": ["summaries"], + "properties": { + "summaries": { + "$ref": "#/definitions/require_properties" + } + } + } + ] + } } ], "definitions": { - "require_any_or_bands": { + "require_properties": { "anyOf": [ { - "$ref": "#/definitions/require_any" + "$ref": "#/definitions/require_fields" }, { "$ref": "#/definitions/require_in_bands" } ] }, - "require_any": { - "anyOf": [ - {"required": ["eo:cloud_cover"]}, - {"required": ["eo:snow_cover"]}, - {"required": ["eo:common_name"]}, - {"required": ["eo:center_wavelength"]}, - {"required": ["eo:full_width_half_max"]}, - {"required": ["eo:solar_illumination"]} - ] - }, - "require_in_bands": { - "required": [ - "bands" - ], + "validate_bands": { + "type": "object", "properties": { "bands": { "type": "array", - "contains": { - "$ref": "#/definitions/require_any" + "items": { + "$ref": "#/definitions/fields" } } } }, - "require_in_assets": { - "required": [ - "assets" - ], + "validate_properties": { + "allOf": [ + { + "$ref": "#/definitions/fields" + }, + { + "$ref": "#/definitions/validate_bands" + } + ] + }, + "require_assets": { + "required": ["assets"], "properties": { "assets": { - "not": { - "additionalProperties": { - "not": { - "$ref": "#/definitions/require_any_or_bands" - } - } - } + "$ref": "#/definitions/asset_contains" } } }, - "require_in_item_assets": { - "required": [ - "item_assets" - ], + "validate_assets": { "properties": { - "item_assets": { - "not": { - "additionalProperties": { - "not": { - "$ref": "#/definitions/require_any_or_bands" - } - } + "assets": { + "additionalProperties": { + "$ref": "#/definitions/validate_properties" } } } }, - "fields": { + "asset_contains": { "type": "object", + "not": { + "additionalProperties": { + "not": { + "$ref": "#/definitions/require_properties" + } + } + } + }, + "require_in_bands": { + "required": ["bands"], "properties": { "bands": { "type": "array", - "items": { - "$ref": "#/definitions/fields" + "contains": { + "$ref": "#/definitions/require_fields" } - }, + } + } + }, + "require_fields": { + "anyOf": [ + { "required": ["eo:cloud_cover"] }, + { "required": ["eo:snow_cover"] }, + { "required": ["eo:common_name"] }, + { "required": ["eo:center_wavelength"] }, + { "required": ["eo:full_width_half_max"] }, + { "required": ["eo:solar_illumination"] } + ] + }, + "fields": { + "type": "object", + "properties": { "eo:cloud_cover": { - "title": "Cloud Cover", - "type": "number", - "minimum": 0, - "maximum": 100 + "$ref": "#/definitions/eo:cloud_cover" }, "eo:snow_cover": { - "title": "Snow and Ice Cover", - "type": "number", - "minimum": 0, - "maximum": 100 + "$ref": "#/definitions/eo:snow_cover" }, "eo:common_name": { - "title": "Common Name of the band", - "type": "string", - "enum": [ - "pan", - "coastal", - "blue", - "green", - "green05", - "yellow", - "red", - "rededge", - "rededge071", - "rededge075", - "rededge078", - "nir", - "nir08", - "nir09", - "cirrus", - "swir16", - "swir22", - "lwir", - "lwir11", - "lwir12" - ] + "$ref": "#/definitions/eo:common_name" }, "eo:center_wavelength": { - "title": "Center Wavelength", - "type": "number", - "minimumExclusive": 0 + "$ref": "#/definitions/eo:center_wavelength" }, "eo:full_width_half_max": { - "title": "Full Width Half Max (FWHM)", - "type": "number", - "minimumExclusive": 0 + "$ref": "#/definitions/eo:full_width_half_max" }, "eo:solar_illumination": { - "title": "Solar Illumination", - "type": "number", - "minimum": 0 + "$ref": "#/definitions/eo:solar_illumination" } }, "patternProperties": { "^(?!eo:)": {} }, "additionalProperties": false + }, + "eo:cloud_cover": { + "title": "Cloud Cover", + "type": "number", + "minimum": 0, + "maximum": 100 + }, + "eo:snow_cover": { + "title": "Snow and Ice Cover", + "type": "number", + "minimum": 0, + "maximum": 100 + }, + "eo:common_name": { + "title": "Common Name of the band", + "type": "string", + "enum": [ + "pan", + "coastal", + "blue", + "green", + "green05", + "yellow", + "red", + "rededge", + "rededge071", + "rededge075", + "rededge078", + "nir", + "nir08", + "nir09", + "cirrus", + "swir16", + "swir22", + "lwir", + "lwir11", + "lwir12" + ] + }, + "eo:center_wavelength": { + "title": "Center Wavelength", + "type": "number", + "minimumExclusive": 0 + }, + "eo:full_width_half_max": { + "title": "Full Width Half Max (FWHM)", + "type": "number", + "minimumExclusive": 0 + }, + "eo:solar_illumination": { + "title": "Solar Illumination", + "type": "number", + "minimum": 0 } } -} \ No newline at end of file +}