From 23806980cc4cb7d55e2a16e0723a97e246d7e1a0 Mon Sep 17 00:00:00 2001 From: Chris Little Date: Thu, 2 Jul 2026 10:25:20 +0100 Subject: [PATCH 1/4] Create readme.adoc for CoverageJSON schema Add documentation for CoverageJSON schema components --- standard/schema/fragments/readme.adoc | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 standard/schema/fragments/readme.adoc diff --git a/standard/schema/fragments/readme.adoc b/standard/schema/fragments/readme.adoc new file mode 100644 index 000000000..de4e1932b --- /dev/null +++ b/standard/schema/fragments/readme.adoc @@ -0,0 +1,2 @@ +The various components of the CoverageJSON schema, with can be built into the CoverageJSON.json bundle and also tweaked to create the appropriate dialect of JSON Schema. +The original community CoverageJSON used DRAFT-07. The current OGC version 1.0 uses 2019. V1.0.1 will probably use dialect 2020, as mandated by OpenAPI V3.1. From 6db74160e5c147ad2b6c00f6ae55a2895dc86048 Mon Sep 17 00:00:00 2001 From: Chris Little Date: Thu, 2 Jul 2026 13:06:50 +0100 Subject: [PATCH 2/4] Added schema fragments --- standard/schema/anyAxis.json | 7 + standard/schema/coverage.json | 13 + standard/schema/coverageBase.json | 102 ++++ standard/schema/coverageCollection.json | 88 ++++ standard/schema/domain.json | 5 + standard/schema/domainBase.json | 453 ++++++++++++++++++ standard/schema/i18n.json | 13 + standard/schema/ndArray.json | 126 +++++ standard/schema/numericAxis.json | 7 + .../schema/numericRegularlySpacedAxis.json | 16 + standard/schema/numericSingleValueAxis.json | 17 + standard/schema/numericValuesAxis.json | 21 + standard/schema/observedProperty.json | 28 ++ standard/schema/parameter.json | 39 ++ standard/schema/parameterGroup.json | 31 ++ standard/schema/polygonValuesAxis.json | 37 ++ standard/schema/primitiveValuesAxis.json | 36 ++ standard/schema/referenceSystem.json | 56 +++ .../schema/referenceSystemConnection.json | 19 + standard/schema/stringSingleValueAxis.json | 17 + standard/schema/stringValuesAxis.json | 21 + standard/schema/targetConcept.json | 11 + standard/schema/tiledNdArray.json | 51 ++ standard/schema/tupleValuesAxis.json | 29 ++ standard/schema/unit.json | 36 ++ standard/schema/valuesAxis.json | 41 ++ standard/schema/valuesAxisBase.json | 30 ++ 27 files changed, 1350 insertions(+) create mode 100644 standard/schema/anyAxis.json create mode 100644 standard/schema/coverage.json create mode 100644 standard/schema/coverageBase.json create mode 100644 standard/schema/coverageCollection.json create mode 100644 standard/schema/domain.json create mode 100644 standard/schema/domainBase.json create mode 100644 standard/schema/i18n.json create mode 100644 standard/schema/ndArray.json create mode 100644 standard/schema/numericAxis.json create mode 100644 standard/schema/numericRegularlySpacedAxis.json create mode 100644 standard/schema/numericSingleValueAxis.json create mode 100644 standard/schema/numericValuesAxis.json create mode 100644 standard/schema/observedProperty.json create mode 100644 standard/schema/parameter.json create mode 100644 standard/schema/parameterGroup.json create mode 100644 standard/schema/polygonValuesAxis.json create mode 100644 standard/schema/primitiveValuesAxis.json create mode 100644 standard/schema/referenceSystem.json create mode 100644 standard/schema/referenceSystemConnection.json create mode 100644 standard/schema/stringSingleValueAxis.json create mode 100644 standard/schema/stringValuesAxis.json create mode 100644 standard/schema/targetConcept.json create mode 100644 standard/schema/tiledNdArray.json create mode 100644 standard/schema/tupleValuesAxis.json create mode 100644 standard/schema/unit.json create mode 100644 standard/schema/valuesAxis.json create mode 100644 standard/schema/valuesAxisBase.json diff --git a/standard/schema/anyAxis.json b/standard/schema/anyAxis.json new file mode 100644 index 000000000..40cbe038b --- /dev/null +++ b/standard/schema/anyAxis.json @@ -0,0 +1,7 @@ +{ + "$id": "/schemas/anyAxis", + "description" : "Validates any axis", + "if" : { "required" : [ "values" ] }, + "then": { "$ref": "/schemas/valuesAxis" }, + "else": { "$ref": "/schemas/numericRegularlySpacedAxis" } +} \ No newline at end of file diff --git a/standard/schema/coverage.json b/standard/schema/coverage.json new file mode 100644 index 000000000..20fd8b56e --- /dev/null +++ b/standard/schema/coverage.json @@ -0,0 +1,13 @@ +{ + "$id" : "/schemas/coverage", + "$ref": "/schemas/coverageBase", + "required" : [ "parameters" ], + "properties": + { + "domain": + { + "if": { "type": "object" }, + "then": { "required": [ "referencing" ] } + } + } +} diff --git a/standard/schema/coverageBase.json b/standard/schema/coverageBase.json new file mode 100644 index 000000000..8fa64cf63 --- /dev/null +++ b/standard/schema/coverageBase.json @@ -0,0 +1,102 @@ +{ + "$id" : "/schemas/coverageBase", + "description" : "A Coverage, representing a mapping from a domain to sets of data values described by parameters.", + "type" : "object", + "properties" : + { + "type" : { "const" : "Coverage" }, + "id": { "type": "string" }, + "domainType" : { "type" : "string" }, + "domain": + { + "allOf" : + [ + { + "type": [ "string", "object" ] + }, + { + "if": { "type": "object" }, + "then": { "$ref" : "/schemas/domainBase" } + } + ] + }, + "parameters": + { + "type": "object", + "patternProperties" : + { + ".+" : { "$ref": "/schemas/parameter" } + } + }, + "parameterGroups": + { + "type": "array", + "items": { "$ref": "/schemas/parameterGroup" } + }, + "ranges": + { + "type": "object", + "patternProperties" : + { + ".+" : + { + "allOf" : + [ + { + "type": [ "string", "object" ] + }, + { + "if": + { + "type": "object" + }, + "then": + { + "properties": + { + "type": + { + "enum": + [ + "NdArray", + "TiledNdArray" + ] + } + }, + "required": ["type"] + } + }, + { + "if": + { + "type": "object", + "properties" : + { + "type" : { "const" : "NdArray" } + } + }, + "then":{ "$ref": "/schemas/ndArray" } + }, + { + "if": + { + "type": "object", + "properties" : + { + "type" : { "const" : "TiledNdArray" } + } + }, + "then":{ "$ref": "/schemas/tiledNdArray" } + } + ] + } + } + }, + "rangeAlternates": + { + "type": "object" + } + }, + "required" : [ "type", "domain", "ranges" ] + +} \ No newline at end of file diff --git a/standard/schema/coverageCollection.json b/standard/schema/coverageCollection.json new file mode 100644 index 000000000..e2c8fb45a --- /dev/null +++ b/standard/schema/coverageCollection.json @@ -0,0 +1,88 @@ +{ + "$id" : "/schemas/coverageCollection", + "description": "A collection of coverage objects", + "properties": + { + "type" : { "const" : "CoverageCollection" }, + "domainType": { "type": "string" }, + "parameters": + { + "type": "object", + "patternProperties" : + { + ".+" : { "$ref": "/schemas/parameter" } + } + }, + "parameterGroups": + { + "type": "array", + "items": { "$ref": "/schemas/parameterGroup" } + }, + "referencing": + { + "type": "array", + "items": { "$ref": "/schemas/referenceSystemConnection" } + }, + "coverages": { + "type": "array", + "items": { "$ref": "/schemas/coverageBase" } + } + }, + "required" : [ "type", "coverages" ], + "allOf": + [ + { + "$comment": "If no parameters are present at collection level then each coverage must have their own", + "if": + { + "not": + { + "required": [ "parameters" ] + } + }, + "then": + { + "properties": + { + "coverages": + { + "items": + { + "required": [ "parameters" ] + } + } + } + } + }, + { + "$comment": "If no \"referencing\" member is present at collection level then each coverage domain must have its own", + "if": + { + "not": + { + "required": [ "referencing" ] + } + }, + "then": + { + "properties": + { + "coverages": + { + "items": + { + "properties": + { + "domain": + { + "if": { "type": "object" }, + "then": { "required": [ "referencing" ] } + } + } + } + } + } + } + } + ] +} diff --git a/standard/schema/domain.json b/standard/schema/domain.json new file mode 100644 index 000000000..8cf2a4ec5 --- /dev/null +++ b/standard/schema/domain.json @@ -0,0 +1,5 @@ +{ + "$id" : "/schemas/domain", + "$ref": "/schemas/domainBase", + "required" : [ "referencing" ] +} diff --git a/standard/schema/domainBase.json b/standard/schema/domainBase.json new file mode 100644 index 000000000..b5795a6b0 --- /dev/null +++ b/standard/schema/domainBase.json @@ -0,0 +1,453 @@ +{ + "$id" : "/schemas/domainBase", + "description" : "A Domain, which defines a set of positions and their extent in one or more referencing systems", + "type" : "object", + "properties" : + { + "type" : { "const" : "Domain" }, + "domainType" : { "type" : "string" }, + "axes" : + { + "type" : "object", + "description" : "Set of Axis objects, keyed by axis identifier", + "minProperties" : 1, + "patternProperties" : + { + ".+" : { "$ref" : "/schemas/anyAxis" } + } + }, + "referencing" : + { + "type" : "array", + "items" : { "$ref" : "/schemas/referenceSystemConnection" } + } + }, + "required" : [ "type", "axes" ], + "dependentSchemas": + { + "domainType": + { + "allOf": + [ + { + "if": { "properties" : { "domainType" : { "const" : "Grid" } } }, + "then": + { + "description" : "Grid domain: x and y are required, z and t optional", + "properties" : + { + "axes" : + { + "properties" : + { + "x" : { "$ref" : "/schemas/numericAxis" }, + "y" : { "$ref" : "/schemas/numericAxis" }, + "z" : { "$ref" : "/schemas/numericAxis" }, + "t" : { "$ref" : "/schemas/stringValuesAxis" } + }, + "required" : [ "x", "y" ], + "additionalProperties" : false + } + } + } + }, + { + "if": { "properties" : { "domainType" : { "const" : "Trajectory" } } }, + "then": + { + "description" : "Trajectory domain: mandatory composite axis and optional z axis", + "properties" : + { + "axes" : + { + "properties" : + { + "composite" : + { + "allOf" : + [ + { "$ref": "/schemas/tupleValuesAxis" }, + { + "properties" : + { + "values" : + { + "items" : + { + "$comment" : "In a Trajectory, tuples always have 3 (txy) or 4 (txyz) values", + "minItems" : 3, + "maxItems" : 4 + } + }, + "coordinates": + { + "enum": + [ + ["t", "x", "y", "z"], + ["t", "x", "y"] + ] + } + } + } + ] + }, + "z" : { "$ref" : "/schemas/numericSingleValueAxis"} + }, + "required" : [ "composite" ], + "additionalProperties" : false + } + } + } + }, + { + "if": { "properties" : { "domainType" : { "const" : "VerticalProfile" } } }, + "then": + { + "description" : "Vertical Profile domain: mandatory x, y and z axis and optional t axis", + "properties" : + { + "axes" : + { + "properties" : + { + "x" : { "$ref" : "/schemas/numericSingleValueAxis"}, + "y" : { "$ref" : "/schemas/numericSingleValueAxis"}, + "z" : { "$ref" : "/schemas/numericAxis" }, + "t" : { "$ref" : "/schemas/stringSingleValueAxis" } + }, + "required" : [ "x", "y", "z" ], + "additionalProperties" : false + } + } + } + }, + { + "if": { "properties" : { "domainType" : { "const" : "Point" } } }, + "then": + { + "description" : "Point domain: mandatory x and y axis, optional z and t axis", + "properties" : + { + "axes" : + { + "properties" : + { + "x" : { "$ref" : "/schemas/numericSingleValueAxis" }, + "y" : { "$ref" : "/schemas/numericSingleValueAxis" }, + "z" : { "$ref" : "/schemas/numericSingleValueAxis" }, + "t" : { "$ref" : "/schemas/stringSingleValueAxis" } + }, + "required" : [ "x", "y" ], + "additionalProperties" : false + } + } + } + }, + { + "if": { "properties" : { "domainType" : { "const" : "PointSeries" } } }, + "then": + { + "description" : "PointSeries domain: mandatory x, y and t axis, optional z axis", + "properties" : + { + "axes" : + { + "properties" : + { + "x" : { "$ref" : "/schemas/numericSingleValueAxis" }, + "y" : { "$ref" : "/schemas/numericSingleValueAxis" }, + "z" : { "$ref" : "/schemas/numericSingleValueAxis" }, + "t" : { "$ref" : "/schemas/stringValuesAxis" } + }, + "required" : [ "x", "y", "t" ], + "additionalProperties" : false + } + } + } + }, + { + "if": { "properties" : { "domainType" : { "const" : "MultiPoint" } } }, + "then": + { + "description" : "MultiPoint domain: mandatory composite axis, optional t axis", + "properties" : + { + "axes" : + { + "properties" : + { + "composite" : + { + "allOf" : + [ + { "$ref": "/schemas/tupleValuesAxis" }, + { + "properties" : + { + "values" : + { + "items" : + { + "$comment" : "In a MultiPoint, tuples always have 2 (xy) or 3 values (xyz)", + "minItems" : 2, + "maxItems" : 3 + } + }, + "coordinates": + { + "enum": + [ + ["x", "y", "z"], + ["x", "y"] + ] + } + } + } + ] + }, + "t" : { "$ref" : "/schemas/stringSingleValueAxis" } + }, + "required" : [ "composite" ], + "additionalProperties" : false + } + } + } + }, + { + "if": { "properties" : { "domainType" : { "const" : "MultiPointSeries" } } }, + "then": + { + "description" : "MultiPointSeries domain: mandatory composite and t axes", + "properties" : + { + "axes" : + { + "properties" : + { + "composite" : + { + "allOf" : + [ + { "$ref": "/schemas/tupleValuesAxis" }, + { + "properties" : + { + "values" : + { + "items" : + { + "$comment" : "In a MultiPointSeries, tuples always have 2 (xy) or 3 values (xyz)", + "minItems" : 2, + "maxItems" : 3 + } + }, + "coordinates": + { + "enum": + [ + ["x", "y", "z"], + ["x", "y"] + ] + } + } + } + ] + }, + "t" : { "$ref" : "/schemas/stringValuesAxis" } + }, + "required" : [ "composite", "t" ], + "additionalProperties" : false + } + } + } + }, + { + "if": { "properties" : { "domainType" : { "const" : "Section" } } }, + "then": + { + "description" : "Section domain: mandatory composite and z axes", + "properties" : + { + "axes" : + { + "properties" : + { + "composite" : + { + "allOf" : + [ + { "$ref": "/schemas/tupleValuesAxis" }, + { + "properties" : + { + "values" : + { + "items" : + { + "$comment" : "In a Section, tuples always have 3 values (txy)", + "minItems" : 3, + "maxItems" : 3 + } + }, + "coordinates": + { + "const": ["t", "x", "y"] + } + } + } + ] + }, + "z" : { "$ref" : "/schemas/numericAxis" } + }, + "required" : [ "composite", "z" ], + "additionalProperties" : false + } + } + } + }, + { + "if": { "properties" : { "domainType" : { "const" : "Polygon" } } }, + "then": + { + "description" : "Polygon domain: mandatory composite axis, optional z and t axes", + "properties" : + { + "axes" : + { + "properties" : + { + "composite" : + { + "allOf" : + [ + { "$ref": "/schemas/polygonValuesAxis" }, + { + "properties" : + { + "values" : + { + "$comment" : "There can only be one polygon in the axis", + "maxItems" : 1 + }, + "coordinates": { "const" : ["x", "y"] } + } + } + ] + }, + "z" : { "$ref" : "/schemas/numericSingleValueAxis" }, + "t" : { "$ref" : "/schemas/stringSingleValueAxis" } + }, + "required" : [ "composite" ], + "additionalProperties" : false + } + } + } + }, + { + "if": { "properties" : { "domainType" : { "const" : "PolygonSeries" } } }, + "then": + { + "description" : "PolygonSeries domain: mandatory composite axis, optional z and t axes", + "properties" : + { + "axes" : + { + "properties" : + { + "composite" : + { + "allOf" : + [ + { "$ref": "/schemas/polygonValuesAxis" }, + { + "properties" : + { + "values" : + { + "$comment" : "There can only be one polygon in the axis", + "maxItems" : 1 + }, + "coordinates": { "const" : ["x", "y"] } + } + } + ] + }, + "z" : { "$ref" : "/schemas/numericSingleValueAxis" }, + "t" : { "$ref" : "/schemas/stringValuesAxis" } + }, + "required" : [ "composite" ], + "additionalProperties" : false + } + } + } + }, + { + "if": { "properties" : { "domainType" : { "const" : "MultiPolygon" } } }, + "then": + { + "description" : "MultiPolygon domain: mandatory composite axis, optional z and t axes", + "properties" : + { + "axes" : + { + "properties" : + { + "composite" : + { + "allOf" : + [ + { "$ref": "/schemas/polygonValuesAxis" }, + { + "properties" : + { + "coordinates": { "const" : ["x", "y"] } + } + } + ] + }, + "z" : { "$ref" : "/schemas/numericSingleValueAxis" }, + "t" : { "$ref" : "/schemas/stringSingleValueAxis" } + }, + "required" : [ "composite" ], + "additionalProperties" : false + } + } + } + }, + { + "if": { "properties" : { "domainType" : { "const" : "MultiPolygonSeries" } } }, + "then": + { + "description" : "MultiPolygonSeries domain: mandatory composite axis, optional z and t axes", + "properties" : + { + "axes" : + { + "properties" : + { + "composite" : + { + "allOf" : + [ + { "$ref": "/schemas/polygonValuesAxis" }, + { + "properties" : + { + "coordinates": { "const" : ["x", "y"] } + } + } + ] + }, + "z" : { "$ref" : "/schemas/numericSingleValueAxis" }, + "t" : { "$ref" : "/schemas/stringValuesAxis" } + }, + "required" : [ "composite" ], + "additionalProperties" : false + } + } + } + } + ] + } + } +} \ No newline at end of file diff --git a/standard/schema/i18n.json b/standard/schema/i18n.json new file mode 100644 index 000000000..e3a62eb2a --- /dev/null +++ b/standard/schema/i18n.json @@ -0,0 +1,13 @@ +{ + "$id": "/schemas/i18n", + "type" : "object", + "description" : "Object representing an internationalised string where keys are BCP 47 language tags.", + "patternProperties" : + { + "^(((([A-Za-z]{2,3}(-([A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-([A-Za-z]{4}))?(-([A-Za-z]{2}|[0-9]{3}))?(-([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-([0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*))$" : + { + "type" : "string" + } + }, + "additionalProperties": false +} \ No newline at end of file diff --git a/standard/schema/ndArray.json b/standard/schema/ndArray.json new file mode 100644 index 000000000..a440aa7f8 --- /dev/null +++ b/standard/schema/ndArray.json @@ -0,0 +1,126 @@ +{ + "$id": "/schemas/ndArray", + "type" : "object", + "description" : "Object representing a multidimensional (>= 0D) array with named axes, encoded as a flat one-dimensional array in row-major order", + "properties" : + { + "type" : { "const" : "NdArray" }, + "dataType" : + { + "enum": [ "float", "integer", "string" ] + }, + "shape" : + { + "type" : "array", + "items" : { "type" : "number" } + }, + "axisNames" : + { + "type" : "array", + "items" : { "type" : "string" }, + "uniqueItems" : true + }, + "values" : + { + "type" : "array", + "minItems" : 1 + } + }, + "allOf": + [ + { + "if" : + { + "properties" : + { + "dataType" : { "const" : "float" } + } + }, + "then" : + { + "properties" : + { + "values" : { + "items" : { "type" : ["number", "null"] } + } + } + } + }, + { + "if" : + { + "properties" : + { + "dataType" : { "const" : "integer" } + } + }, + "then" : + { + "properties" : + { + "values" : + { + "items" : { "type" : ["integer", "null"] } + } + } + } + }, + { + "if" : + { + "properties" : + { + "dataType" : { "const" : "string" } + } + }, + "then" : + { + "properties" : + { + "values" : + { + "items" : { "type" : ["string", "null"] } + } + } + } + }, + { + "if" : + { + "anyOf": + [ + { + "properties" : + { + "values" : { "minItems": 2 } + } + }, + { + "properties" : + { + "shape" : { "minItems": 1 } + }, + "required" : ["shape"] + }, + { + "properties" : + { + "axisNames" : { "minItems": 1 } + }, + "required" : ["axisNames"] + } + ] + }, + "then" : + { + "properties" : + { + "shape" : { "minItems" : 1 }, + "axisNames" : { "minItems" : 1 } + }, + "required": ["shape", "axisNames"] + } + } + ], + "required" : [ "type", "dataType", "values" ] +} \ No newline at end of file diff --git a/standard/schema/numericAxis.json b/standard/schema/numericAxis.json new file mode 100644 index 000000000..c161b4e62 --- /dev/null +++ b/standard/schema/numericAxis.json @@ -0,0 +1,7 @@ +{ + "$id": "/schemas/numericAxis", + "description" : "Simple axis with numeric values", + "if" : { "required" : [ "values" ] }, + "then": { "$ref" : "/schemas/numericValuesAxis" }, + "else": { "$ref" : "/schemas/numericRegularlySpacedAxis" } +} \ No newline at end of file diff --git a/standard/schema/numericRegularlySpacedAxis.json b/standard/schema/numericRegularlySpacedAxis.json new file mode 100644 index 000000000..41d8ff2b2 --- /dev/null +++ b/standard/schema/numericRegularlySpacedAxis.json @@ -0,0 +1,16 @@ +{ + "$id": "/schemas/numericRegularlySpacedAxis", + "description" : "A regularly-spaced numeric axis", + "properties" : + { + "start" : { "type" : "number" }, + "stop" : { "type" : "number" }, + "num" : + { + "type" : "integer", + "minimum" : 1 + } + }, + "required" : [ "start", "stop", "num" ], + "additionalProperties" : false +} \ No newline at end of file diff --git a/standard/schema/numericSingleValueAxis.json b/standard/schema/numericSingleValueAxis.json new file mode 100644 index 000000000..b3afcf9ba --- /dev/null +++ b/standard/schema/numericSingleValueAxis.json @@ -0,0 +1,17 @@ +{ + "$id": "/schemas/numericSingleValueAxis", + "description" : "Axis defined by single numeric value", + "allOf" : + [ + { "$ref": "/schemas/numericValuesAxis" }, + { + "properties" : + { + "values" : + { + "maxItems" : 1 + } + } + } + ] +} \ No newline at end of file diff --git a/standard/schema/numericValuesAxis.json b/standard/schema/numericValuesAxis.json new file mode 100644 index 000000000..684582363 --- /dev/null +++ b/standard/schema/numericValuesAxis.json @@ -0,0 +1,21 @@ +{ + "$id": "/schemas/numericValuesAxis", + "description" : "Axis defined by list of numeric axis values and optional bounds", + "allOf" : [ + { "$ref": "/schemas/valuesAxisBase" }, + { + "properties" : + { + "values" : + { + "items" : { "type" : "number" } + }, + "bounds" : + { + "items" : { "type" : "number" } + } + }, + "additionalProperties" : false + } + ] +} \ No newline at end of file diff --git a/standard/schema/observedProperty.json b/standard/schema/observedProperty.json new file mode 100644 index 000000000..5cbde5991 --- /dev/null +++ b/standard/schema/observedProperty.json @@ -0,0 +1,28 @@ +{ + "$id": "/schemas/observedProperty", + "type" : "object", + "description" : "A definition of the quantity being measured.", + "properties" : + { + "id" : { "type" : "string" }, + "label" : { "$ref" : "/schemas/i18n" }, + "description" : { "$ref" : "/schemas/i18n" }, + "categories" : + { + "type" : "array", + "items" : + { + "type" : "object", + "properties" : + { + "id" : { "type" : "string" }, + "label" : { "$ref" : "/schemas/i18n" }, + "description" : { "$ref" : "/schemas/i18n" } + }, + "required" : [ "id", "label" ] + }, + "minItems" : 1 + } + }, + "required" : [ "label" ] +} \ No newline at end of file diff --git a/standard/schema/parameter.json b/standard/schema/parameter.json new file mode 100644 index 000000000..daeb6732f --- /dev/null +++ b/standard/schema/parameter.json @@ -0,0 +1,39 @@ +{ + "$id": "/schemas/parameter", + "type" : "object", + "description" : "Represents metadata about the values of the coverage", + "properties" : + { + "id": { "type": "string" }, + "type": + { + "description": "Type of the parameter object, must be \"Parameter\"", + "const": "Parameter" + }, + "description": { "$ref" : "/schemas/i18n" }, + "observedProperty": { "$ref" : "/schemas/observedProperty" }, + "unit": { "$ref" : "/schemas/unit" }, + "categoryEncoding" : + { + "type" : "object", + "description" : "Maps IDs of categories in the observedProperty to range values", + "patternProperties" : + { + ".+" : + { + "oneOf" : + [ + { "type" : "integer" }, + { + "type" : "array", + "items" : { "type" : "integer" }, + "minItems" : 1, + "uniqueItems" : true + } + ] + } + } + } + }, + "required": [ "type", "observedProperty" ] +} \ No newline at end of file diff --git a/standard/schema/parameterGroup.json b/standard/schema/parameterGroup.json new file mode 100644 index 000000000..5abccb044 --- /dev/null +++ b/standard/schema/parameterGroup.json @@ -0,0 +1,31 @@ +{ + "$id": "/schemas/parameterGroup", + "type" : "object", + "description" : "Represents logical groups of parameters", + "properties" : + { + "type": + { + "description": "Type of the parameter group object, must be \"ParameterGroup\"", + "const": "ParameterGroup" + }, + "id": { "type": "string" }, + "label" : { "$ref" : "/schemas/i18n" }, + "description": { "$ref" : "/schemas/i18n" }, + "observedProperty": { "$ref" : "/schemas/observedProperty" }, + "members": + { + "type": "array", + "items": { "type": "string" }, + "minItems": 1, + "uniqueItems": true + } + + }, + "required": [ "type", "members" ], + "anyOf": + [ + { "required": [ "label" ] }, + { "required": [ "observedProperty" ]} + ] +} \ No newline at end of file diff --git a/standard/schema/polygonValuesAxis.json b/standard/schema/polygonValuesAxis.json new file mode 100644 index 000000000..16bba8be9 --- /dev/null +++ b/standard/schema/polygonValuesAxis.json @@ -0,0 +1,37 @@ +{ + "$id": "/schemas/polygonValuesAxis", + "description" : "Polygon-based axis", + "allOf" : [ + { "$ref": "/schemas/valuesAxisBase" }, + { + "properties" : + { + "dataType" : { "const" : "polygon" }, + "values" : + { + "items" : + { + "description" : "A GeoJSON polygon", + "type" : "array", + "items" : + { + "type" : "array", + "items" : + { + "description" : "The inner array: the coordinates themselves", + "type" : "array", + "items" : { "type" : "number" }, + "minItems" : 2 + }, + "minItems" : 1 + }, + "minItems" : 1 + } + }, + "coordinates": { } + }, + "required" : [ "dataType", "values", "coordinates" ], + "additionalProperties" : false + } + ] +} \ No newline at end of file diff --git a/standard/schema/primitiveValuesAxis.json b/standard/schema/primitiveValuesAxis.json new file mode 100644 index 000000000..a7136a4f2 --- /dev/null +++ b/standard/schema/primitiveValuesAxis.json @@ -0,0 +1,36 @@ +{ + "$id": "/schemas/primitiveValuesAxis", + "description" : "Validates any axis with primitive values", + "allOf" : + [ + { "$ref" : "/schemas/valuesAxisBase" }, + { + "$comment": "This redundant branch exists to fail early with succinct errors", + "properties" : + { + "values" : + { + "items" : + { + "oneOf" : + [ + { "type" : "number" }, + { "type" : "string" } + ] + } + } + } + }, + { + "if" : + { + "properties" : + { + "values" : { "items" : { "type" : "number" } } + } + }, + "then": { "$ref" : "/schemas/numericValuesAxis" }, + "else": { "$ref" : "/schemas/stringValuesAxis" } + } + ] +} \ No newline at end of file diff --git a/standard/schema/referenceSystem.json b/standard/schema/referenceSystem.json new file mode 100644 index 000000000..b8c1eae09 --- /dev/null +++ b/standard/schema/referenceSystem.json @@ -0,0 +1,56 @@ +{ + "$id": "/schemas/referenceSystem", + "type" : "object", + "properties" : + { + "type" : { "type": "string" } + }, + "required" : [ "type" ], + "allOf" : + [ + { + "if": { "properties" : { "type" : { "const" : "TemporalRS" } } }, + "then": + { + "description" : "Temporal reference system", + "properties" : + { + "calendar" : + { + "type" : "string", + "oneOf" : + [ + { "const" : "Gregorian" }, + { "pattern": "^https?://" } + ] + }, + "timeScale" : { "type" : "string" } + }, + "required" : [ "calendar" ] + } + }, + { + "if": { "properties" : { "type" : { "const" : "IdentifierRS" } } }, + "then": + { + "description" : "An identifier-based reference system", + "properties" : + { + "id" : { "type" : "string" }, + "label" : { "$ref" : "/schemas/i18n" }, + "description" : { "$ref" : "/schemas/i18n" }, + "targetConcept" : { "$ref" : "/schemas/targetConcept" }, + "identifiers" : + { + "type" : "object", + "patternProperties" : + { + ".+" : { "$ref" : "/schemas/targetConcept" } + } + } + }, + "required" : [ "targetConcept" ] + } + } + ] +} \ No newline at end of file diff --git a/standard/schema/referenceSystemConnection.json b/standard/schema/referenceSystemConnection.json new file mode 100644 index 000000000..e17d4366f --- /dev/null +++ b/standard/schema/referenceSystemConnection.json @@ -0,0 +1,19 @@ +{ + "$id" : "/schemas/referenceSystemConnection", + "description" : "Reference System Connection object: connects coordinates to reference systems", + "type" : "object", + "properties" : + { + "coordinates" : + { + "type" : "array", + "items" : { "type" : "string" }, + "minItems" : 1 + }, + "system" : + { + "$ref" : "/schemas/referenceSystem" + } + }, + "required" : [ "coordinates", "system" ] +} \ No newline at end of file diff --git a/standard/schema/stringSingleValueAxis.json b/standard/schema/stringSingleValueAxis.json new file mode 100644 index 000000000..e13bbac63 --- /dev/null +++ b/standard/schema/stringSingleValueAxis.json @@ -0,0 +1,17 @@ +{ + "$id": "/schemas/stringSingleValueAxis", + "description" : "Axis defined by single string value", + "allOf" : + [ + { "$ref": "/schemas/stringValuesAxis" }, + { + "properties" : + { + "values" : + { + "maxItems" : 1 + } + } + } + ] +} \ No newline at end of file diff --git a/standard/schema/stringValuesAxis.json b/standard/schema/stringValuesAxis.json new file mode 100644 index 000000000..4aa31ccb1 --- /dev/null +++ b/standard/schema/stringValuesAxis.json @@ -0,0 +1,21 @@ +{ + "$id": "/schemas/stringValuesAxis", + "description" : "Simple axis with string values (e.g. time strings)", + "allOf" : [ + { "$ref": "/schemas/valuesAxisBase" }, + { + "properties" : + { + "values" : + { + "items" : { "type" : "string" } + }, + "bounds" : + { + "items" : { "type" : "string" } + } + }, + "additionalProperties" : false + } + ] +} \ No newline at end of file diff --git a/standard/schema/targetConcept.json b/standard/schema/targetConcept.json new file mode 100644 index 000000000..d01af474b --- /dev/null +++ b/standard/schema/targetConcept.json @@ -0,0 +1,11 @@ +{ + "$id": "/schemas/targetConcept", + "description" : "A concept in an identifier-based reference system", + "properties" : + { + "id" : { "type" : "string" }, + "label" : { "$ref" : "/schemas/i18n" }, + "description" : { "$ref" : "/schemas/i18n" } + }, + "required" : [ "label" ] +} \ No newline at end of file diff --git a/standard/schema/tiledNdArray.json b/standard/schema/tiledNdArray.json new file mode 100644 index 000000000..13d16a00d --- /dev/null +++ b/standard/schema/tiledNdArray.json @@ -0,0 +1,51 @@ +{ + "$id": "/schemas/tiledNdArray", + "type" : "object", + "description" : "Object representing a multidimensional (>= 1D) array with named axes split up into sets of linked NdArray documents", + "properties" : + { + "type" : { "const" : "TiledNdArray" }, + "dataType" : + { + "enum": [ "float", "integer", "string" ] + }, + "shape" : + { + "type" : "array", + "items" : { "type" : "number" }, + "minItems" : 1 + }, + "axisNames" : + { + "type" : "array", + "items" : { "type" : "string" }, + "minItems" : 1, + "uniqueItems" : true + }, + "tileSets" : + { + "type" : "array", + "minItems" : 1, + "items": + { + "type" : "object", + "properties": + { + "tileShape": + { + "type" : "array", + "items" : { "type" : ["number", "null"] }, + "minItems" : 1 + }, + "urlTemplate": + { + "type" : "string", + "description": "RFC 6570 Level 1 URI template" + } + }, + "required" : [ "tileShape", "urlTemplate" ] + } + } + }, + "required" : [ "type", "dataType", "shape", "axisNames", "tileSets" ] +} \ No newline at end of file diff --git a/standard/schema/tupleValuesAxis.json b/standard/schema/tupleValuesAxis.json new file mode 100644 index 000000000..5c5fbc62d --- /dev/null +++ b/standard/schema/tupleValuesAxis.json @@ -0,0 +1,29 @@ +{ + "$id": "/schemas/tupleValuesAxis", + "description" : "Tuple-based axis", + "allOf" : [ + { "$ref": "/schemas/valuesAxisBase" }, + { + "properties" : + { + "dataType" : { "const" : "tuple" }, + "values" : + { + "items" : + { + "description" : "A tuple of axis values (numbers or strings)", + "type" : "array", + "items" : + { + "type": [ "number", "string" ] + }, + "minItems" : 2 + } + }, + "coordinates": { } + }, + "required" : [ "dataType", "values", "coordinates" ], + "additionalProperties" : false + } +] +} \ No newline at end of file diff --git a/standard/schema/unit.json b/standard/schema/unit.json new file mode 100644 index 000000000..b34d50e49 --- /dev/null +++ b/standard/schema/unit.json @@ -0,0 +1,36 @@ +{ + "$id": "/schemas/unit", + "type" : "object", + "description" : "The units of measure", + "properties" : + { + "id" : { "type" : "string" }, + "label" : { "$ref" : "/schemas/i18n" }, + "symbol" : + { + "allOf": + [ + { + "type": [ "string", "object" ] + }, + { + "if": { "type": "object" }, + "then": + { + "properties" : + { + "type" : { "type" : "string" }, + "value" : { "type" : "string" } + }, + "required" : [ "type", "value" ] + } + } + ] + } + }, + "anyOf" : + [ + { "required" : [ "label" ] }, + { "required" : [ "symbol" ] } + ] +} \ No newline at end of file diff --git a/standard/schema/valuesAxis.json b/standard/schema/valuesAxis.json new file mode 100644 index 000000000..5c0c81244 --- /dev/null +++ b/standard/schema/valuesAxis.json @@ -0,0 +1,41 @@ +{ + "$id": "/schemas/valuesAxis", + "description" : "Validates any values-based axis", + "allOf" : + [ + { "$ref": "/schemas/valuesAxisBase" }, + { + "if": { "not": { "required": [ "dataType" ] } }, + "then": { "$ref" : "/schemas/primitiveValuesAxis" } + } + ], + "dependentSchemas": + { + "dataType": + { + "allOf": + [ + { + "if" : + { + "properties" : + { + "dataType" : { "const": "tuple" } + } + }, + "then": { "$ref" : "/schemas/tupleValuesAxis" } + }, + { + "if" : + { + "properties" : + { + "dataType" : { "const": "polygon" } + } + }, + "then": { "$ref" : "/schemas/polygonValuesAxis" } + } + ] + } + } +} \ No newline at end of file diff --git a/standard/schema/valuesAxisBase.json b/standard/schema/valuesAxisBase.json new file mode 100644 index 000000000..ba251c862 --- /dev/null +++ b/standard/schema/valuesAxisBase.json @@ -0,0 +1,30 @@ +{ + "$id": "/schemas/valuesAxisBase", + "$comment" : "Base schema for values-based axis schemas", + "properties" : + { + "dataType" : { + "type" : "string", + "not" : { "const": "primitive" } + }, + "values" : + { + "type" : "array", + "minItems" : 1, + "uniqueItems" : true + }, + "coordinates" : + { + "type" : "array", + "items" : { "type" : "string" }, + "minItems" : 2 + }, + "bounds" : + { + "description" : "Optional axis bounds. Must be twice as long (and same data type) as \"values\"", + "type" : "array", + "minItems" : 2 + } + }, + "required" : [ "values" ] +} \ No newline at end of file From eb540d76eb4deecb05b104daf0201c0a596ae3ef Mon Sep 17 00:00:00 2001 From: Chris Little Date: Thu, 2 Jul 2026 13:10:39 +0100 Subject: [PATCH 3/4] Delete standard/schema/fragments directory --- standard/schema/fragments/readme.adoc | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 standard/schema/fragments/readme.adoc diff --git a/standard/schema/fragments/readme.adoc b/standard/schema/fragments/readme.adoc deleted file mode 100644 index de4e1932b..000000000 --- a/standard/schema/fragments/readme.adoc +++ /dev/null @@ -1,2 +0,0 @@ -The various components of the CoverageJSON schema, with can be built into the CoverageJSON.json bundle and also tweaked to create the appropriate dialect of JSON Schema. -The original community CoverageJSON used DRAFT-07. The current OGC version 1.0 uses 2019. V1.0.1 will probably use dialect 2020, as mandated by OpenAPI V3.1. From 85b06db8887027ad6f9783bc5f843e5d7c5fa0d2 Mon Sep 17 00:00:00 2001 From: Chris Little Date: Thu, 2 Jul 2026 13:29:27 +0100 Subject: [PATCH 4/4] Add README for CoverageJSON schema components . --- standard/schema/README.ADOC | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 standard/schema/README.ADOC diff --git a/standard/schema/README.ADOC b/standard/schema/README.ADOC new file mode 100644 index 000000000..0ea459f29 --- /dev/null +++ b/standard/schema/README.ADOC @@ -0,0 +1,3 @@ +The various components of the CoverageJSON schema, which can be built into the CoverageJSON.json bundle and also tweaked to create the appropriate dialect of JSON Schema. +The original community-based CoverageJSON used dialect DRAFT-07. The current OGC version 1.0 uses 2019-09. V1.0.1 will probably use dialect 2020-12, as required by OpenAPI V3.1. +In the future, IETF will probably define a standardised JSON Schema.