Skip to content

Commit

Permalink
feat: Create asset summaries (#157)
Browse files Browse the repository at this point in the history
* feat: Require 'linz:asset_summaries' root property

* feat: Require asset summary 'created' propert

* feat: require asset summary created 'minimum' property

* feat: require asset summary created minimum property be a string

* feat: require asset summary created minimum property be a datetime

* feat: require asset summary created minimum property be a UTC datetime

* refactor: Pull out UTC datetime definition

* docs: Set asset/metadata summary created/updated titles

* feat: require asset summary created 'maximum' property

* feat: require asset summary created maximum property be a UTC datetime

* feat: require asset summary 'updated' property

* feat: require asset summary updated 'minimum' property

* feat: require asset summary updated minimum property be a UTC datetime

* feat: require asset summary updated 'maximum' property

* feat: require asset summary updated maximum property be a UTC datetime

* docs: Move asset summary documentation to right property
  • Loading branch information
l0b0 authored Nov 24, 2021
1 parent 56e130e commit 497c182
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 36 deletions.
34 changes: 20 additions & 14 deletions extensions/linz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,28 +63,34 @@ See [ISO/IEC 13249-3:2016(en)](https://www.iso.org/obp/ui/#!iso:std:60343:en) fo

## Collection Fields

| Field Name | Type | Description |
| ---------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| title | string | **REQUIRED**. Collection title. |
| linz:geospatial_type | string | **REQUIRED**. A general description of the type of content that can be found in the dataset. See the [list of accepted geospatial types](#geospatial-types). |
| linz:history | string | **REQUIRED**. A descriptive statement about the lineage/history of a dataset |
| linz:lifecycle | string | **REQUIRED**. Lifecycle Status of Collection. Must be one of `under development`, `preview`, `ongoing`, `completed`, `deprecated`. |
| linz:providers | LINZ Provider Object | **REQUIRED**. The object provides information about a provider with additional roles defined by Toitū Te Whenua LINZ. A provider is any of the organizations that captures or processes the content of the assets and therefore influences the data offered by the STAC implementation. See [LINZ Provider Object](#linz-provider-object). |
| providers | Provider Object | **REQUIRED**. The object provides information about a provider. A provider is any of the organizations that captures or processes the content of the assets and therefore influences the data offered by the STAC implementation. See [Provider Object](#provider-object). |
| linz:security_classification | string | **REQUIRED**. New Zealand Government [Security Classification](https://www.digital.govt.nz/standards-and-guidance/governance/managing-online-channels/security-and-privacy-for-websites/foundations/classify-information/). Must be one of `unclassified`, `in-confidence`, `sensitive`, `restricted`, `confidential`, `secret` or `top-secret`. |
| linz:update_frequency | string | Recommended. Indicates how frequently an updated dataset may be distributed to the publication platform. Must follow the format for durations as defined in [RFC3339](https://datatracker.ietf.org/doc/html/rfc3339#appendix-A). For example, `P3D` expresses a duration of 3 days. |
| processing:software | Map<string, string> | Recommended. The software and versions which were used to generate the dataset. See [reference](https://github.com/stac-extensions/processing). |

### Collection Summaries Object Fields
| Field Name | Type | Description |
| ---------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| title | string | **REQUIRED**. Collection title. |
| linz:asset_summaries | Map<string, Map<string, string>> | **REQUIRED**. See [Custom Collection Summaries Object Fields](#custom-collection-summaries-object-fields). |
| linz:geospatial_type | string | **REQUIRED**. A general description of the type of content that can be found in the dataset. See the [list of accepted geospatial types](#geospatial-types). |
| linz:history | string | **REQUIRED**. A descriptive statement about the lineage/history of a dataset |
| linz:lifecycle | string | **REQUIRED**. Lifecycle Status of Collection. Must be one of `under development`, `preview`, `ongoing`, `completed`, `deprecated`. |
| linz:providers | LINZ Provider Object | **REQUIRED**. The object provides information about a provider with additional roles defined by Toitū Te Whenua LINZ. A provider is any of the organizations that captures or processes the content of the assets and therefore influences the data offered by the STAC implementation. See [LINZ Provider Object](#linz-provider-object). |
| providers | Provider Object | **REQUIRED**. The object provides information about a provider. A provider is any of the organizations that captures or processes the content of the assets and therefore influences the data offered by the STAC implementation. See [Provider Object](#provider-object). |
| linz:security_classification | string | **REQUIRED**. New Zealand Government [Security Classification](https://www.digital.govt.nz/standards-and-guidance/governance/managing-online-channels/security-and-privacy-for-websites/foundations/classify-information/). Must be one of `unclassified`, `in-confidence`, `sensitive`, `restricted`, `confidential`, `secret` or `top-secret`. |
| linz:update_frequency | string | Recommended. Indicates how frequently an updated dataset may be distributed to the publication platform. Must follow the format for durations as defined in [RFC3339](https://datatracker.ietf.org/doc/html/rfc3339#appendix-A). For example, `P3D` expresses a duration of 3 days. |
| processing:software | Map<string, string> | Recommended. The software and versions which were used to generate the dataset. See [reference](https://github.com/stac-extensions/processing). |

### Custom Collection Summaries Object Fields

| Field Name | Type | Description |
| --------------- | --------- | -------------------------------------------------------------------- |
| title | string | **REQUIRED**. Collection title. |
| created/minimum | date-time | **REQUIRED**. Earliest [asset created value](#asset-fields), in UTC. |
| created/maximum | date-time | **REQUIRED**. Latest [asset created value](#asset-fields), in UTC. |
| updated/minimum | date-time | **REQUIRED**. Earliest [asset updated value](#asset-fields), in UTC. |
| updated/maximum | date-time | **REQUIRED**. Latest [asset updated value](#asset-fields), in UTC. |

### Collection Summaries Object Fields

| Field Name | Type | Description |
| ---------- | ------ | ------------------------------- |
| title | string | **REQUIRED**. Collection title. |

### LINZ Provider Object Fields

This expands on the [provider object in the STAC spec](https://github.com/radiantearth/stac-spec/blob/v1.0.0/item-spec/common-metadata.md#provider-object). Only differences from that definition are mentioned here.
Expand Down
10 changes: 10 additions & 0 deletions extensions/linz/examples/collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@
"title": "A title",
"description": "A description",
"license": "Apache-2.0",
"linz:asset_summaries": {
"created": {
"minimum": "1999-01-01T00:00:00Z",
"maximum": "2010-01-01T00:00:00Z"
},
"updated": {
"minimum": "1999-01-01T00:00:00Z",
"maximum": "2010-01-01T00:00:00Z"
}
},
"linz:lifecycle": "under development",
"linz:providers": [
{
Expand Down
69 changes: 47 additions & 22 deletions extensions/linz/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
{
"type": "object",
"required": [
"linz:asset_summaries",
"linz:geospatial_type",
"linz:history",
"linz:lifecycle",
Expand Down Expand Up @@ -131,15 +132,11 @@
"properties": {
"created": {
"title": "Creation time",
"type": "string",
"format": "date-time",
"pattern": "(\\+00:00|Z)$"
"$ref": "#/definitions/utc_datetime"
},
"updated": {
"title": "Last update time",
"type": "string",
"format": "date-time",
"pattern": "(\\+00:00|Z)$"
"$ref": "#/definitions/utc_datetime"
},
"linz:language": {
"title": "IETF RFC 5646 language tag",
Expand Down Expand Up @@ -940,6 +937,37 @@
}
}
},
"linz:asset_summaries": {
"required": ["created", "updated"],
"properties": {
"created": {
"required": ["minimum", "maximum"],
"properties": {
"minimum": {
"title": "Earliest asset creation time",
"$ref": "#/definitions/utc_datetime"
},
"maximum": {
"title": "Latest asset creation time",
"$ref": "#/definitions/utc_datetime"
}
}
},
"updated": {
"required": ["minimum", "maximum"],
"properties": {
"minimum": {
"title": "Earliest asset updated time",
"$ref": "#/definitions/utc_datetime"
},
"maximum": {
"title": "Latest asset updated time",
"$ref": "#/definitions/utc_datetime"
}
}
}
}
},
"linz:geospatial_type": {},
"linz:history": {
"title": "History",
Expand Down Expand Up @@ -1047,16 +1075,12 @@
"required": ["minimum", "maximum"],
"properties": {
"minimum": {
"title": "Earliest asset creation time",
"type": "string",
"format": "date-time",
"pattern": "(\\+00:00|Z)$"
"title": "Earliest metadata creation time",
"$ref": "#/definitions/utc_datetime"
},
"maximum": {
"title": "Latest asset creation time",
"type": "string",
"format": "date-time",
"pattern": "(\\+00:00|Z)$"
"title": "Latest metadata creation time",
"$ref": "#/definitions/utc_datetime"
}
}
},
Expand All @@ -1065,16 +1089,12 @@
"required": ["minimum", "maximum"],
"properties": {
"minimum": {
"title": "Earliest asset updated time",
"type": "string",
"format": "date-time",
"pattern": "(\\+00:00|Z)$"
"title": "Earliest metadata updated time",
"$ref": "#/definitions/utc_datetime"
},
"maximum": {
"title": "Latest asset updated time",
"type": "string",
"format": "date-time",
"pattern": "(\\+00:00|Z)$"
"title": "Latest metadata updated time",
"$ref": "#/definitions/utc_datetime"
}
}
}
Expand All @@ -1089,6 +1109,11 @@
"^(?!linz:)": {}
},
"additionalProperties": false
},
"utc_datetime": {
"type": "string",
"format": "date-time",
"pattern": "(\\+00:00|Z)$"
}
}
}
87 changes: 87 additions & 0 deletions extensions/linz/tests/linz_collection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,93 @@ o.spec('LINZ collection', () => {
).equals(true)(JSON.stringify(validate.errors));
});

o("Example without the mandatory 'linz:asset_summaries' property should fail validation", async () => {
// given
const example = JSON.parse(await fs.readFile(examplePath));
delete example['linz:asset_summaries'];

// when
let valid = validate(example);

// then
o(valid).equals(false);
o(
validate.errors.some(
(error) => error.instancePath === '' && error.message === "must have required property 'linz:asset_summaries'",
),
).equals(true)(JSON.stringify(validate.errors));
});

o("Asset summary without the mandatory 'created'/'updated' properties should fail validation", async () => {
for (const property of ['created', 'updated']) {
// given
const example = JSON.parse(await fs.readFile(examplePath));
delete example['linz:asset_summaries'][property];

// when
let valid = validate(example);

// then
o(valid).equals(false);
o(
validate.errors.some(
(error) =>
error.instancePath === '/linz:asset_summaries' &&
error.message === `must have required property '${property}'`,
),
).equals(true)(JSON.stringify(validate.errors));
}
});

o(
"Asset summary created/updated without the mandatory 'minimum'/'maximum' properties should fail validation",
async () => {
for (const outerProperty of ['created', 'updated']) {
for (const innerProperty of ['minimum', 'maximum']) {
// given
const example = JSON.parse(await fs.readFile(examplePath));
delete example['linz:asset_summaries'][outerProperty][innerProperty];

// when
let valid = validate(example);

// then
o(valid).equals(false);
o(
validate.errors.some(
(error) =>
error.instancePath === `/linz:asset_summaries/${outerProperty}` &&
error.message === `must have required property '${innerProperty}'`,
),
).equals(true)(JSON.stringify(validate.errors));
}
}
},
);

o("Asset summary created/updated with invalid 'minimum'/'maximum' value should fail validation", async () => {
for (const outerProperty of ['created', 'updated']) {
for (const innerProperty of ['minimum', 'maximum']) {
// given
const example = JSON.parse(await fs.readFile(examplePath));
example['linz:asset_summaries'][outerProperty][innerProperty] = '1999-01-01T00:00:00';

// when
let valid = validate(example);

// then
o(valid).equals(false);
o(
validate.errors.some(
(error) =>
error.instancePath === `/linz:asset_summaries/${outerProperty}/${innerProperty}` &&
error.message === 'must match pattern "(\\+00:00|Z)$"',
),
).equals(true)(JSON.stringify(validate.errors));
}
}
});

o("Example without the mandatory 'linz:history' field should fail validation", async () => {
// given
const example = JSON.parse(await fs.readFile(examplePath));
Expand Down

0 comments on commit 497c182

Please sign in to comment.