From b12ef31e4f5b5e161d369cea8199727df31f8e97 Mon Sep 17 00:00:00 2001 From: Rob Atkinson Date: Fri, 13 Dec 2024 18:29:41 +1100 Subject: [PATCH] Move SOSA ontology, rules and tests out of the API/JSON binding --- _sources/all/bblock.json | 8 +- _sources/sosa-spec-examples/bblock.json | 31 +++++++ _sources/sosa-spec-examples/closure.ttl | 1 + _sources/sosa-spec-examples/description.md | 5 ++ _sources/sosa-spec-examples/examples.yaml | 16 ++++ _sources/sosa/bblock.json | 7 +- _sources/sosa/examples/place-expressions.ttl | 0 _sources/sosa/rules.shacl | 95 ++++++++++++++++++++ bblocks-config.yaml | 9 +- build.sh | 2 + view.sh | 1 + 11 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 _sources/sosa-spec-examples/bblock.json create mode 100644 _sources/sosa-spec-examples/closure.ttl create mode 100644 _sources/sosa-spec-examples/description.md create mode 100644 _sources/sosa-spec-examples/examples.yaml delete mode 100644 _sources/sosa/examples/place-expressions.ttl create mode 100644 _sources/sosa/rules.shacl create mode 100644 build.sh create mode 100644 view.sh diff --git a/_sources/all/bblock.json b/_sources/all/bblock.json index bf94cae..6222289 100644 --- a/_sources/all/bblock.json +++ b/_sources/all/bblock.json @@ -1,5 +1,6 @@ { - "name": "Cross Domain Model - All modules", + "name": "Cross Domain Model (Complete)", + "highlighted": true, "abstract": "All modules of the Cross Domain model", "status": "under-development", "dateTimeAddition": "2023-09-18T00:00:00Z", @@ -12,12 +13,13 @@ "ogc.model.cross-domain.sosa", "ogc.model.cross-domain.prov", "ogc.model.cross-domain.geosparql", - "ogc.model.cross-domain.datacube" + "ogc.model.cross-domain.datacube", + "ogc.geo.geodcat.geodcat" ], "sources": [ ], "scope": "dev", "tags": [ - "Closure" + "Closure", "Semantic Model" ] } diff --git a/_sources/sosa-spec-examples/bblock.json b/_sources/sosa-spec-examples/bblock.json new file mode 100644 index 0000000..53a16e6 --- /dev/null +++ b/_sources/sosa-spec-examples/bblock.json @@ -0,0 +1,31 @@ +{ + "name": "SOSA Examples", + "highlighted": true, + "abstract": "This Building Block identifies examples from the SOSA specification and supports validation of these examples", + "status": "under-development", + "dateTimeAddition": "2023-04-13T00:00:00Z", + "itemClass": "schema", + "register": "ogc-building-block-register", + "version": "1.0", + "dateOfLastChange": "2023-04-13", + "sources": [ + { + "title": "Semantic Sensor Network Ontology", + "link": "https://www.w3.org/TR/vocab-ssn/" + } + ], + "dependsOn": [ + "ogc.model.cross-domain.sosa" + ], + "maturity": "development", + "scope": "development", + "tags": [ + "sosa", + "ssn", + "observations", + "o&m", + "OMS" + ], + "group": "SOSA", + "highlighted": false +} diff --git a/_sources/sosa-spec-examples/closure.ttl b/_sources/sosa-spec-examples/closure.ttl new file mode 100644 index 0000000..f2be8e5 --- /dev/null +++ b/_sources/sosa-spec-examples/closure.ttl @@ -0,0 +1 @@ + a . \ No newline at end of file diff --git a/_sources/sosa-spec-examples/description.md b/_sources/sosa-spec-examples/description.md new file mode 100644 index 0000000..dfab378 --- /dev/null +++ b/_sources/sosa-spec-examples/description.md @@ -0,0 +1,5 @@ +## SOSA Specification Examples + +This building block runs tests against the SOSA specification examples. + +As TTL files these examples are validated against the SHACL rules inherited from the building blocks for elements of the specification diff --git a/_sources/sosa-spec-examples/examples.yaml b/_sources/sosa-spec-examples/examples.yaml new file mode 100644 index 0000000..8d67ec6 --- /dev/null +++ b/_sources/sosa-spec-examples/examples.yaml @@ -0,0 +1,16 @@ +prefixes: + ex: http://example.org/sosa/ + qudt: http://qudt.org/ + qudt-1-1: http://qudt.org/ + qunit: http://qudt.org/vocab/unit/ + rdfs: http://www.w3.org/2000/01/rdf-schema# + xsd: http://www.w3.org/2001/XMLSchema# + sh: http://www.w3.org/ns/shacl# + owl: http://www.w3.org/2002/07/owl# + sosa: http://www.w3.org/ns/sosa/ + ssn-system: http://www.w3.org/ns/ssn/systems/ +examples: + - title: Example ice-core.ttl + snippets: + - language: ttl + ref: https://w3c.github.io/sdw-sosa-ssn/ssn/rdf/examples/ice-core.ttl diff --git a/_sources/sosa/bblock.json b/_sources/sosa/bblock.json index b42a818..7b3ad8c 100644 --- a/_sources/sosa/bblock.json +++ b/_sources/sosa/bblock.json @@ -1,5 +1,6 @@ { "name": "SOSA/SSN", + "highlighted": true, "abstract": "Sensors, Observations, Sampling and Actuation (ISO 19156 Observations and Measurements) Ontology ", "status": "under-development", "dateTimeAddition": "2023-09-18T00:00:00Z", @@ -9,7 +10,7 @@ "dateOfLastChange": "2023-09-18", "link": "https://github.com/opengeospatial/bblock-template", "dependsOn": [ - ], + ], "sources": [ { "title": "SOSA/SSN Specification", @@ -17,5 +18,7 @@ } ], "scope": "dev", - "tags": ["DCAT", "profile"] + "tags": [ + "OMS" + ] } diff --git a/_sources/sosa/examples/place-expressions.ttl b/_sources/sosa/examples/place-expressions.ttl deleted file mode 100644 index e69de29..0000000 diff --git a/_sources/sosa/rules.shacl b/_sources/sosa/rules.shacl new file mode 100644 index 0000000..e3b4c3a --- /dev/null +++ b/_sources/sosa/rules.shacl @@ -0,0 +1,95 @@ +@prefix rdf: . +@prefix rdfs: . +@prefix sh: . +@prefix xsd: . +@prefix geojson: . +@prefix sosa: . +@base . + +<#testRequiredTime> + a sh:NodeShape ; + sh:targetClass sosa:Observation ; + sh:targetSubjectsOf sosa:hasResult, sosa:hasSimpleResult ; + sh:message "sosa:resultTime or sosa:phenomenonTime is required, and no more than 1 of each is allowed" ; + sh:or ( [ sh:path ( [ sh:zeroOrMorePath [ sh:oneOrMorePath [ sh:inversePath sosa:hasMember ] ] ] + sosa:phenomenonTime ) ; + sh:minCount 1 ; + sh:maxCount 1 ; ] [ sh:path ( [ sh:zeroOrMorePath [ sh:oneOrMorePath [ sh:inversePath + geojson:features ] ] ] + sosa:phenomenonTime ) ; + sh:minCount 1 ; + sh:maxCount 1 ; ] [ sh:path ( [ sh:zeroOrMorePath [ sh:oneOrMorePath + [ sh:inversePath + sosa:hasMember ] ] ] + sosa:resultTime ) ; + sh:minCount 1 ; + sh:maxCount 1 ; ] [ sh:path ( [ sh:zeroOrMorePath + [ sh:oneOrMorePath + [ sh:inversePath + geojson:features ] ] ] + sosa:resultTime ) ; + sh:minCount 1 ; + sh:maxCount 1 ; ] ) ; +. + +<#testObservedProperty> + a sh:NodeShape ; + sh:targetClass sosa:Observation ; + sh:targetSubjectsOf sosa:hasResult, sosa:hasSimpleResult ; + sh:message "Exactly 1 of sosa:observedProperty is required" ; + sh:property [ sh:path ( [ sh:zeroOrMorePath [ sh:oneOrMorePath [ sh:alternativePath ( [ sh:inversePath + geojson:features ] + [ sh:inversePath + sosa:hasMember ] ) ] ] ] + sosa:observedProperty ) ; + sh:minCount 1 ; + sh:maxCount 1 ; ] ; +. + + +<#testFeatureOfInterest> + a sh:NodeShape ; + sh:targetClass sosa:Observation ; + sh:targetSubjectsOf sosa:hasResult, sosa:hasSimpleResult ; + sh:property [ sh:path ( [ sh:zeroOrMorePath [ sh:oneOrMorePath [ sh:alternativePath ( [ sh:inversePath + geojson:features ] + [ sh:inversePath + sosa:hasMember ] ) ] ] ] + [ sh:alternativePath ( sosa:hasFeatureOfInterest [ sh:inversePath + sosa:isFeatureOfInterestOf ] ) ] ) ; + sh:minCount 1 ; + sh:maxCount 1 ; ] ; + sh:message "Exactly one feature of interest (sosa:hasFeatureOfInterest/sosa:isFeatureOfInterestOf) is required" ; +. + +<#testResult> + a sh:NodeShape ; + sh:targetClass sosa:Observation ; + sh:targetSubjectsOf sosa:hasResult, sosa:hasSimpleResult ; + sh:property [ sh:path [ sh:alternativePath ( sosa:hasResult sosa:hasSimpleResult ) ] ; + sh:minCount 1 ; + sh:maxCount 1 ; ] ; + sh:message "Exactly one of sosa:hasResult or sosa:hasSimpleResult is required per observation" ; +. + + +<#testSimpleResultLiteral> + a sh:NodeShape ; + sh:targetObjectsOf sosa:hasSimpleResult ; + sh:nodeKind sh:IRIOrLiteral ; + sh:message "sosa:hasSimpleResult is a simple Literal" ; +. + +<#testResultNotEmptyNode> + a sh:NodeShape ; + sh:targetSubjectsOf sosa:hasResult-Disabled ; + sh:message "sosa:hasResult not a blank node" ; + sh:sparql [ sh:select """ + PREFIX geojson: + SELECT $this (sosa:hasResult as ?path) ?value + WHERE { + $this sosa:hasResult ?value . + FILTER NOT EXISTS { ?value ?p ?o } + } + """ ; ] +. diff --git a/bblocks-config.yaml b/bblocks-config.yaml index cf691c9..8db82f6 100644 --- a/bblocks-config.yaml +++ b/bblocks-config.yaml @@ -3,14 +3,14 @@ name: Cross-domain model # Short abstract for this collection (optional) abstract: | - Defines a cross-domain semantic model by articulating a series of profiles and dependencies on available standards and a minimum set of constraints for application in the spatio-temporal domain. + Defines a reusable baseline "cross-domain semantic model" by defining a series of profiles and dependencies on available standards and where appropriate a set of constraints for application of such standards in the spatio-temporal domain. # Description for this collection (optional) description: | - These building blocks allow for transparent reuse of a range of semantic models published by OGC and other international standards organisations that may be used to define semantics models for application domains. + These models are defined as ["building blocks"](https://ogcincubator.github.io/bblocks-docs/) to allow for transparent reuse of a range of semantic models published by OGC and other international standards organisations (SDO) that may be used to define semantic models for application domains in a consistent and interoperable way. - Application domains will typically define profiles of these core models to meet specific needs. Infrastructures may define profiles to support commonality of implementation necessary to exploit infrastructure services. + Application domains will typically define profiles of these core models to meet specific needs. Infrastructures supporting application domains may define more general profiles to support commonality of implementation necessary to exploit infrastructure services. The Cross-domain model underpins proposed domain models for Agriculture, Oceans and AG4DG. By defining these models using this common cross-domain model the interoperability between such domains is enhanced, and made transparent to applications. @@ -25,7 +25,7 @@ description: | This will dramatically reduce the complexity of defining and testing domain models in a consistent fashion. Many such restrictions will relate to the way these models are combined - - for example the way GeoDCAT, PROV, RDF-Datacube and SOSA may be combined to standardised the way observational data is described using available standards. + for example the way GeoDCAT, PROV, RDF-Datacube and SOSA may be combined to standardise the way observational data is described using available standards. # Customize the following prefix (will be prepended to the path of the building blocks): identifier-prefix: ogc.model.cross-domain. @@ -33,6 +33,7 @@ identifier-prefix: ogc.model.cross-domain. # List of imports ("default" is an alias for the main OGC Building Blocks Register) imports: - default + - https://ogcincubator.github.io/geodcat-ogcapi-records/ # SPARQL configuration (optional) diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..e797fa2 --- /dev/null +++ b/build.sh @@ -0,0 +1,2 @@ +# Process building blocks +docker run --pull=always --rm --workdir /workspace -v "$(pwd):/workspace" ghcr.io/opengeospatial/bblocks-postprocess --clean true --base-url http://localhost:9090/register/ \ No newline at end of file diff --git a/view.sh b/view.sh new file mode 100644 index 0000000..4dbaa8b --- /dev/null +++ b/view.sh @@ -0,0 +1 @@ +docker run --rm --pull=always -v "$(pwd):/register" -p 9090:9090 ghcr.io/ogcincubator/bblocks-viewer \ No newline at end of file