From 545a90dd0098d08e55b4aa68505efacaa51f2e2d Mon Sep 17 00:00:00 2001 From: Simon Oakes Date: Tue, 20 Jan 2026 12:58:04 +0000 Subject: [PATCH 1/2] Add API property to determine whether to enclose describe query results. --- .../java/com/epimorphics/lda/core/View.java | 25 +- .../com/epimorphics/lda/specs/APISpec.java | 7 + .../lda/vocabularies/ELDA_API.java | 4 +- .../lda/core/EncloseDescribeApiTest.java | 46 ++ .../lda/core/EncloseDescribeTest.java | 87 +++ elda-lda/src/test/resources/view/api.ttl | 51 ++ .../src/test/resources/view/bw_closure.ttl | 28 + .../resources/view/bw_reverse_closure.ttl | 511 ++++++++++++++++++ 8 files changed, 752 insertions(+), 7 deletions(-) create mode 100644 elda-lda/src/test/java/com/epimorphics/lda/core/EncloseDescribeApiTest.java create mode 100644 elda-lda/src/test/java/com/epimorphics/lda/core/EncloseDescribeTest.java create mode 100644 elda-lda/src/test/resources/view/api.ttl create mode 100644 elda-lda/src/test/resources/view/bw_closure.ttl create mode 100644 elda-lda/src/test/resources/view/bw_reverse_closure.ttl diff --git a/elda-lda/src/main/java/com/epimorphics/lda/core/View.java b/elda-lda/src/main/java/com/epimorphics/lda/core/View.java index feacabfaa..d3d1625f5 100755 --- a/elda-lda/src/main/java/com/epimorphics/lda/core/View.java +++ b/elda-lda/src/main/java/com/epimorphics/lda/core/View.java @@ -29,6 +29,7 @@ import org.apache.jena.query.Query; import org.apache.jena.rdf.model.*; import org.apache.jena.shared.PrefixMapping; +import org.apache.jena.sparql.util.Closure; import org.apache.jena.vocabulary.RDF; import org.apache.jena.vocabulary.RDFS; import org.slf4j.Logger; @@ -293,19 +294,19 @@ void endGraph(StringBuilder sb) { } } - public String fetchDescriptions(Controls c, State s) { + public String fetchDescriptions(Controls c, State s, boolean encloseDescribe) { Times t = c.times; switch (type) { case T_DESCRIBE: { String detailsQuery = fetchByGivenPropertyChains(s, chains); - String describeQuery = describeBySelectedItems(s, s.roots); + String describeQuery = describeBySelectedItems(s, s.roots, encloseDescribe); t.addToViewQuerySize(detailsQuery); t.addToViewQuerySize(describeQuery); return describeQuery; } case T_ALL: { - String detailsQuery = describeBySelectedItems(s, s.roots); + String detailsQuery = describeBySelectedItems(s, s.roots, encloseDescribe); String chainsQuery = fetchByGivenPropertyChains(s, chains); addAllObjectLabels(s); t.addToViewQuerySize(detailsQuery); @@ -360,10 +361,22 @@ public String fetchByGivenPropertyChains(State st, List chains) { return queryString; } - private String describeBySelectedItems(State s, List allRoots) { + private String describeBySelectedItems(State s, List allRoots, boolean encloseDescribe) { String query = createDescribeQueryForItems(s, allRoots); Query describeQuery = QueryUtil.create(query); - for (Source x : s.sources) s.m.add(x.executeDescribe(describeQuery)); + for (Source x : s.sources) { + Model m = s.m; + Model description = x.executeDescribe(describeQuery); + if (encloseDescribe) { + for (Resource root : allRoots) { + Resource res = root.inModel(description); + Model closure = Closure.closure(res, false); + m.add(closure); + } + } else { + m.add(description); + } + } return query.toString(); } @@ -449,7 +462,7 @@ public static String buildFetchLabelsQuery(State s, List properties) { List sources = spec.getDescribeSources(); return this.isTemplateView() ? this.viewByTemplate(roots, m, spec, sources, graphName) - : this.fetchDescriptions(c, new View.State(roots, m, sources, vars, graphName)); + : this.fetchDescriptions(c, new View.State(roots, m, sources, vars, graphName), spec.getEncloseDescribe()); } public String viewByTemplate(List roots, Model m, APISpec spec, List sources, String graphName) { diff --git a/elda-lda/src/main/java/com/epimorphics/lda/specs/APISpec.java b/elda-lda/src/main/java/com/epimorphics/lda/specs/APISpec.java index 9169b04f9..b1b6c5dd4 100755 --- a/elda-lda/src/main/java/com/epimorphics/lda/specs/APISpec.java +++ b/elda-lda/src/main/java/com/epimorphics/lda/specs/APISpec.java @@ -102,6 +102,8 @@ public class APISpec extends SpecCommon { protected final boolean purging; + protected final boolean encloseDescribe; + protected final Boolean enableForwardHeaders; protected final MetaConfig metaConfig; @@ -150,6 +152,7 @@ public APISpec(MetaConfig mc, String prefixPath, String appName, FileManager fm, this.enableCounting = RDFUtils.getOptionalBooleanValue(root, ELDA_API.enableCounting, Boolean.FALSE); this.propertyExpiryTimes = PropertyExpiryTimes.assemble(root.getModel()); this.enableForwardHeaders = RDFUtils.getBooleanValue(root, ELDA_API.enableForwardHeaders, true); + this.encloseDescribe = RDFUtils.getBooleanValue(root, ELDA_API.encloseDescribe, false); // this.metaConfig = new MetaConfig(root, mc); // @@ -396,4 +399,8 @@ public String getGraphTemplate() { public Boolean getEnableForwardHeaders() { return enableForwardHeaders; } + + public Boolean getEncloseDescribe() { + return encloseDescribe; + } } diff --git a/elda-lda/src/main/java/com/epimorphics/lda/vocabularies/ELDA_API.java b/elda-lda/src/main/java/com/epimorphics/lda/vocabularies/ELDA_API.java index 5219d2aa0..fd4e16b1e 100644 --- a/elda-lda/src/main/java/com/epimorphics/lda/vocabularies/ELDA_API.java +++ b/elda-lda/src/main/java/com/epimorphics/lda/vocabularies/ELDA_API.java @@ -94,7 +94,9 @@ public class ELDA_API extends API { /**

*/ public static final Property enableForwardHeaders = M_MODEL.createProperty( "http://www.epimorphics.com/vocabularies/lda#enableForwardHeaders" ); - + + public static final Property encloseDescribe = M_MODEL.createProperty( "http://www.epimorphics.com/vocabularies/lda#encloseDescribe" ); + /**

*/ public static final Property enhanceViewWith = M_MODEL.createProperty( "http://www.epimorphics.com/vocabularies/lda#enhanceViewWith" ); diff --git a/elda-lda/src/test/java/com/epimorphics/lda/core/EncloseDescribeApiTest.java b/elda-lda/src/test/java/com/epimorphics/lda/core/EncloseDescribeApiTest.java new file mode 100644 index 000000000..ca1623ff4 --- /dev/null +++ b/elda-lda/src/test/java/com/epimorphics/lda/core/EncloseDescribeApiTest.java @@ -0,0 +1,46 @@ +package com.epimorphics.lda.core; + +import com.epimorphics.lda.specs.APISpec; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.util.FileManager; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; + +import static org.apache.jena.rdf.model.ModelFactory.createDefaultModel; +import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; + +public class EncloseDescribeApiTest { + + private Model readFromResource(String path) { + Model model = createDefaultModel(); + try { + try (InputStream input = this.getClass().getResource(path).openStream()) { + model.read(input, "", "TTL"); + } + } catch (IOException ioe) { + fail(ioe.getMessage()); + } + + return model; + } + + @Test + public void apiSpec_withEncloseDescribe() { + Model model = readFromResource("/view/api.ttl"); + Resource api = model.getResource("http://www.epimorphics.com/tools/example#encloseDescribe"); + APISpec spec = new APISpec(mock(FileManager.class), api, mock(ModelLoader.class)); + assertTrue(spec.getEncloseDescribe()); + } + + @Test + public void apiSpec_withoutEncloseDescribe() { + Model model = readFromResource("/view/api.ttl"); + Resource api = model.getResource("http://www.epimorphics.com/tools/example#default"); + APISpec spec = new APISpec(mock(FileManager.class), api, mock(ModelLoader.class)); + assertFalse(spec.getEncloseDescribe()); + } +} diff --git a/elda-lda/src/test/java/com/epimorphics/lda/core/EncloseDescribeTest.java b/elda-lda/src/test/java/com/epimorphics/lda/core/EncloseDescribeTest.java new file mode 100644 index 000000000..f703791d7 --- /dev/null +++ b/elda-lda/src/test/java/com/epimorphics/lda/core/EncloseDescribeTest.java @@ -0,0 +1,87 @@ +package com.epimorphics.lda.core; + +import com.epimorphics.lda.sources.Source; +import com.epimorphics.lda.support.Controls; +import com.epimorphics.lda.support.Times; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Resource; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import static org.apache.jena.rdf.model.ModelFactory.createDefaultModel; +import static org.apache.jena.rdf.model.ResourceFactory.createResource; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class EncloseDescribeTest { + private final Controls c = new Controls(false, mock(Times.class)); + private final Source s = mock(Source.class); + + private Model readFromResource(String path) { + Model model = createDefaultModel(); + try { + try (InputStream input = this.getClass().getResource(path).openStream()) { + model.read(input, "", "TTL"); + } + } catch (IOException ioe) { + fail(ioe.getMessage()); + } + + return model; + } + + private void assertIsomorphic(Model expected, Model actual) { + if (!expected.isIsomorphicWith(actual)) { + assertEquals(expected, actual); + } + } + + @Test + public void describeView_fetchDescriptions_withReverseClosure_returnsForwardClosure() { + Model describe = readFromResource("/view/bw_reverse_closure.ttl"); + when(s.executeDescribe(any())).thenReturn(describe); + + View v = new View("test", View.Type.T_DESCRIBE); + + List roots = List.of(createResource("http://environment.data.gov.uk/id/bathing-water/")); + Model result = createDefaultModel(); + List sources = List.of(s); + VarSupply vs = mock(VarSupply.class); + + View.State state = new View.State(roots, result, sources, vs, "#graph"); + + + v.fetchDescriptions(c, state, true); + + Model expected = readFromResource("/view/bw_closure.ttl"); + assertIsomorphic(expected, result); + } + + @Test + public void allView_fetchDescriptions_withReverseClosure_returnsForwardClosure() { + Model describe = readFromResource("/view/bw_reverse_closure.ttl"); + when(s.executeDescribe(any())).thenReturn(describe); + when(s.executeConstruct(any())).thenReturn(createDefaultModel()); + + View v = new View("test", View.Type.T_ALL); + + List roots = List.of(createResource("http://environment.data.gov.uk/id/bathing-water/")); + Model result = createDefaultModel(); + List sources = List.of(s); + VarSupply vs = mock(VarSupply.class); + + View.State state = new View.State(roots, result, sources, vs, "#graph"); + + + v.fetchDescriptions(c, state, true); + + Model expected = readFromResource("/view/bw_closure.ttl"); + assertIsomorphic(expected, result); + } +} diff --git a/elda-lda/src/test/resources/view/api.ttl b/elda-lda/src/test/resources/view/api.ttl new file mode 100644 index 000000000..d27c2f523 --- /dev/null +++ b/elda-lda/src/test/resources/view/api.ttl @@ -0,0 +1,51 @@ +## Common prefixes. +@prefix rdf: . +@prefix rdfs: . +@prefix owl: . +@prefix foaf: . +@prefix xsd: . +@prefix api: . +@prefix skos: . +@prefix geo: . +@prefix spatialrelations: . +@prefix admingeo: . +@prefix qb: . +@prefix time: . +@prefix interval: . +@prefix dgu: . +@prefix bw: . +@prefix bwsp: . +@prefix bwq: . +@prefix bwq-iss: . +@prefix bw-def: . +@prefix ef-def: . +@prefix dct: . +@prefix t: . +@prefix dgu: . +@prefix void: . +@prefix elda: . +@prefix : . + +:encloseDescribe + a api:API ; + api:sparqlEndpoint ; + api:endpoint t:bathingWaters ; + elda:encloseDescribe true ; + . + +:default + a api:API ; + api:sparqlEndpoint ; + api:endpoint t:bathingWaters ; + . + +t:bathingWaters + a api:ListEndpoint ; + api:uriTemplate "/doc/bathing-water" ; + api:exampleRequestPath "/doc/bathing-water" ; + api:viewer api:describeViewer; + api:defaultViewer api:describeViewer; + api:selector [ + api:filter "type=BathingWater" ; + # api:sort "samplingPoint.samplePointNotation"; + ] . \ No newline at end of file diff --git a/elda-lda/src/test/resources/view/bw_closure.ttl b/elda-lda/src/test/resources/view/bw_closure.ttl new file mode 100644 index 000000000..51593cd9b --- /dev/null +++ b/elda-lda/src/test/resources/view/bw_closure.ttl @@ -0,0 +1,28 @@ +@prefix void: . +@prefix onsadmingeo: . +@prefix def-geom: . +@prefix xsd: . +@prefix rdfs: . +@prefix spatialrelations: . +@prefix def-ef: . +@prefix dgu: . +@prefix osadmingeo: . +@prefix rdf: . +@prefix bw: . +@prefix dcterms: . +@prefix geometry: . +@prefix api: . +@prefix foaf: . +@prefix def-bw: . + +bw: a void:Dataset , dgu:URIset ; + rdfs:label "Bathing waters monitored by the Environment Agency for England and Wales."@en ; + dcterms:description "URI Set of Bathing Waters in England and Wales monitored by the Environment Agency for compliance with the EU Bathing Water Directive"@en ; + dcterms:license ; + dcterms:modified "2025-11-25T09:05:57.727Z"^^xsd:dateTime , "2014-06-30T15:53:44.397Z"^^xsd:dateTime ; + dcterms:source , ; + void:dataDump ; + void:uriRegexPattern "http://environment.data.gov.uk/id/bathing-water/.*" ; + void:vocabulary , geometry: , osadmingeo: , def-bw: , spatialrelations: , dgu: , onsadmingeo: , def-ef: , , , def-geom: ; + dgu:itemType def-bw:BathingWater ; + dgu:status . \ No newline at end of file diff --git a/elda-lda/src/test/resources/view/bw_reverse_closure.ttl b/elda-lda/src/test/resources/view/bw_reverse_closure.ttl new file mode 100644 index 000000000..da7d68d1f --- /dev/null +++ b/elda-lda/src/test/resources/view/bw_reverse_closure.ttl @@ -0,0 +1,511 @@ +@prefix void: . +@prefix geometry: . +@prefix osadmingeo: . +@prefix onsadmingeo: . +@prefix owl: . +@prefix def-geom: . +@prefix xsd: . +@prefix def-bwp: . +@prefix skos: . +@prefix rdfs: . +@prefix spatialrelations: . +@prefix def-ef: . +@prefix def-bwq: . +@prefix geo: . +@prefix def-zoi: . +@prefix chterms: . +@prefix dgu: . +@prefix bw: . +@prefix rdf: . +@prefix dcterms: . +@prefix api: . +@prefix def-stp: . +@prefix def-bw: . + + + skos:prefLabel "Good"@en . + + + rdfs:label "Map bounds for Druridge Bay South"@en . + + + skos:prefLabel "Zone of influence at Amble Links"@en . + +bw:ukc2106-04400 a def-bw:CoastalBathingWater , def-bw:BathingWater ; + def-bwp:latestBathingWaterProfile + ; + def-bwq:latestComplianceAssessment + ; + def-bwq:latestSampleAssessment ; + def-bw:appointedSewerageUndertaker + ; + def-bw:eubwidNotation "ukc2106-04400"^^def-bw:eubwid ; + def-bw:regionalOrganization ; + def-bw:sedimentTypesPresent def-bw:sand-sediment ; + def-bw:waterQualityImpactedByHeavyRain + false ; + def-bw:yearDesignated ; + def-stp:latestRiskPrediction ; + def-geom:envelope ; + def-ef:samplingPoint ; + def-zoi:zoneOfInfluence ; + dgu:uriSet bw: ; + onsadmingeo:country ; + onsadmingeo:district , ; + owl:sameAs bw:newbiggin-north ; + skos:prefLabel "Newbiggin North"@en . + + + skos:prefLabel "Northumberland"@en . + + + skos:prefLabel "Zone of influence at Bamburgh Castle"@en . + + + skos:prefLabel "North East"@en . + + + rdfs:label "Map bounds for Warkworth"@en . + + + def-stp:expiresAt "2025-10-02T08:29:00"^^xsd:dateTime ; + def-stp:riskLevel def-stp:normal . + + + skos:prefLabel "Excellent"@en . + +bw:ukc2101-04250 a def-bw:BathingWater , def-bw:CoastalBathingWater ; + def-bwp:latestBathingWaterProfile + ; + def-bwq:latestComplianceAssessment + ; + def-bwq:latestSampleAssessment ; + def-bw:appointedSewerageUndertaker + ; + def-bw:eubwidNotation "ukc2101-04250"^^def-bw:eubwid ; + def-bw:regionalOrganization ; + def-bw:sedimentTypesPresent def-bw:sand-sediment ; + def-bw:waterQualityImpactedByHeavyRain + false ; + def-bw:yearDesignated ; + def-stp:latestRiskPrediction ; + def-geom:envelope ; + def-ef:samplingPoint ; + def-zoi:zoneOfInfluence ; + dgu:uriSet bw: ; + onsadmingeo:country ; + onsadmingeo:district , ; + owl:sameAs bw:amble-links ; + skos:prefLabel "Amble Links"@en . + + + def-stp:expiresAt "2025-10-02T08:29:00"^^xsd:dateTime ; + def-stp:riskLevel def-stp:normal . + + + skos:prefLabel "Zone of influence at Seahouses North"@en . + +bw: rdfs:label "Bathing waters monitored by the Environment Agency for England and Wales."@en . + + + def-bwq:complianceClassification + . + + + rdfs:label "Map bounds for Low Newton"@en . + + + rdfs:label "Map bounds for Newbiggin North"@en . + + + spatialrelations:easting "428500"^^xsd:decimal ; + spatialrelations:northing "603600"^^xsd:decimal ; + geo:lat 55.32564590871283 ; + geo:long -1.552397954526308 ; + skos:prefLabel "Sampling point at Amble Links"@en . + + + def-stp:expiresAt "2025-10-02T08:29:00"^^xsd:dateTime ; + def-stp:riskLevel def-stp:normal . + + + skos:prefLabel "Zone of influence at Beadnell"@en . + + + def-bwq:complianceClassification + . + + + skos:prefLabel "Zone of influence at Spittal"@en . + + + def-bwq:complianceClassification + . + + + def-bwq:complianceClassification + . + + + rdfs:label "Map bounds for Druridge Bay North"@en . + + + spatialrelations:easting "423300"^^xsd:decimal ; + spatialrelations:northing "628400"^^xsd:decimal ; + geo:lat 55.548750892712384 ; + geo:long -1.632288132669377 ; + skos:prefLabel "Sampling point at Beadnell"@en . + + + spatialrelations:easting "421100"^^xsd:decimal ; + spatialrelations:northing "633000"^^xsd:decimal ; + geo:lat 55.59018054023254 ; + geo:long -1.666807530612919 ; + skos:prefLabel "Sampling point at Seahouses North"@en . + + + def-bwq:complianceClassification + . + +bw:ukc2101-04200 a def-bw:BathingWater , def-bw:CoastalBathingWater ; + def-bwp:latestBathingWaterProfile + ; + def-bwq:latestComplianceAssessment + ; + def-bwq:latestSampleAssessment ; + def-bw:appointedSewerageUndertaker + ; + def-bw:eubwidNotation "ukc2101-04200"^^def-bw:eubwid ; + def-bw:regionalOrganization ; + def-bw:sedimentTypesPresent def-bw:sand-sediment ; + def-bw:waterQualityImpactedByHeavyRain + false ; + def-bw:yearDesignated ; + def-stp:latestRiskPrediction ; + def-geom:envelope ; + def-ef:samplingPoint ; + def-zoi:zoneOfInfluence ; + dgu:uriSet bw: ; + onsadmingeo:country ; + onsadmingeo:district , ; + owl:sameAs bw:warkworth ; + skos:prefLabel "Warkworth"@en . + +bw:ukc2104-04300 a def-bw:BathingWater , def-bw:CoastalBathingWater ; + def-bwp:latestBathingWaterProfile + ; + def-bwq:latestComplianceAssessment + ; + def-bwq:latestSampleAssessment ; + def-bw:appointedSewerageUndertaker + ; + def-bw:eubwidNotation "ukc2104-04300"^^def-bw:eubwid ; + def-bw:regionalOrganization ; + def-bw:sedimentTypesPresent def-bw:sand-sediment ; + def-bw:waterQualityImpactedByHeavyRain + false ; + def-bw:yearDesignated ; + def-stp:latestRiskPrediction ; + def-geom:envelope ; + def-ef:samplingPoint ; + def-zoi:zoneOfInfluence ; + dgu:uriSet bw: ; + onsadmingeo:country ; + onsadmingeo:district , ; + owl:sameAs bw:druridge-bay-south ; + skos:prefLabel "Druridge Bay South"@en . + + + spatialrelations:easting "431280"^^xsd:decimal ; + spatialrelations:northing "587900"^^xsd:decimal ; + geo:lat 55.18440846275651 ; + geo:long -1.51032213701256 ; + skos:prefLabel "Sampling point at Newbiggin North"@en . + + + spatialrelations:easting "418500"^^xsd:decimal ; + spatialrelations:northing "635300"^^xsd:decimal ; + geo:lat 55.610951487599735 ; + geo:long -1.707902922897897 ; + skos:prefLabel "Sampling point at Bamburgh Castle"@en . + + + spatialrelations:easting "429100"^^xsd:decimal ; + spatialrelations:northing "594100"^^xsd:decimal ; + geo:lat 55.2402505449666 ; + geo:long -1.543920718052364 ; + skos:prefLabel "Sampling point at Druridge Bay South"@en . + + + spatialrelations:easting "400800"^^xsd:decimal ; + spatialrelations:northing "651500"^^xsd:decimal ; + geo:lat 55.756856682381226 ; + geo:long -1.988831300159957 ; + skos:prefLabel "Sampling point at Spittal"@en . + + + def-bwq:complianceClassification + . + + + spatialrelations:easting "425920"^^xsd:decimal ; + spatialrelations:northing "606429"^^xsd:decimal ; + geo:lat 55.35120750368777 ; + geo:long -1.592797501571366 ; + skos:prefLabel "Sampling point at Warkworth"@en . + +bw:ukc2101-04000 a def-bw:CoastalBathingWater , def-bw:BathingWater ; + def-bwp:latestBathingWaterProfile + ; + def-bwq:latestComplianceAssessment + ; + def-bwq:latestSampleAssessment ; + def-bw:appointedSewerageUndertaker + ; + def-bw:eubwidNotation "ukc2101-04000"^^def-bw:eubwid ; + def-bw:regionalOrganization ; + def-bw:sedimentTypesPresent def-bw:sand-sediment ; + def-bw:waterQualityImpactedByHeavyRain + false ; + def-bw:yearDesignated ; + def-stp:latestRiskPrediction ; + def-geom:envelope ; + def-ef:samplingPoint ; + def-zoi:zoneOfInfluence ; + dgu:uriSet bw: ; + onsadmingeo:country ; + onsadmingeo:district , ; + owl:sameAs bw:low-newton ; + skos:prefLabel "Low Newton"@en . + + + def-stp:expiresAt "2025-10-02T08:29:00"^^xsd:dateTime ; + def-stp:riskLevel def-stp:normal . + + + def-bwq:complianceClassification + . + + + def-bwq:complianceClassification + . + + + rdfs:label "Map bounds for Amble Links"@en . + + + spatialrelations:easting "424380"^^xsd:decimal ; + spatialrelations:northing "624450"^^xsd:decimal ; + geo:lat 55.513207709216196 ; + geo:long -1.615516489199073 ; + skos:prefLabel "Sampling point at Low Newton"@en . + + + skos:prefLabel "Zone of influence at Druridge Bay South"@en . + + + chterms:companyProfile ; + skos:prefLabel "Northumbrian Water Limited"@en . + + + rdfs:label "Map bounds for Bamburgh Castle"@en . + + + def-stp:expiresAt "2025-10-02T08:29:00"^^xsd:dateTime ; + def-stp:riskLevel def-stp:normal . + + + skos:prefLabel "Zone of influence at Warkworth"@en . + +bw:ukc2102-03900 a def-bw:CoastalBathingWater , def-bw:BathingWater ; + def-bwp:latestBathingWaterProfile + ; + def-bwq:latestComplianceAssessment + ; + def-bwq:latestSampleAssessment ; + def-bw:appointedSewerageUndertaker + ; + def-bw:eubwidNotation "ukc2102-03900"^^def-bw:eubwid ; + def-bw:regionalOrganization ; + def-bw:sedimentTypesPresent def-bw:sand-sediment ; + def-bw:waterQualityImpactedByHeavyRain + false ; + def-bw:yearDesignated ; + def-stp:latestRiskPrediction ; + def-geom:envelope ; + def-ef:samplingPoint ; + def-zoi:zoneOfInfluence ; + dgu:uriSet bw: ; + onsadmingeo:country ; + onsadmingeo:district , ; + owl:sameAs bw:beadnell ; + skos:prefLabel "Beadnell"@en . + + + def-stp:expiresAt "2025-10-02T08:29:00"^^xsd:dateTime ; + def-stp:riskLevel def-stp:normal . + +bw:ukc2102-03800 a def-bw:BathingWater , def-bw:CoastalBathingWater ; + def-bwp:latestBathingWaterProfile + ; + def-bwq:latestComplianceAssessment + ; + def-bwq:latestSampleAssessment ; + def-bw:appointedSewerageUndertaker + ; + def-bw:eubwidNotation "ukc2102-03800"^^def-bw:eubwid ; + def-bw:regionalOrganization ; + def-bw:sedimentTypesPresent def-bw:sand-sediment ; + def-bw:waterQualityImpactedByHeavyRain + false ; + def-bw:yearDesignated ; + def-stp:latestRiskPrediction ; + def-geom:envelope ; + def-ef:samplingPoint ; + def-zoi:zoneOfInfluence ; + dgu:uriSet bw: ; + onsadmingeo:country ; + onsadmingeo:district , ; + owl:sameAs bw:seahouses-north ; + skos:prefLabel "Seahouses North"@en . + + + rdfs:label "Map bounds for Seahouses North"@en . + + + def-stp:expiresAt "2025-10-02T08:29:00"^^xsd:dateTime ; + def-stp:riskLevel def-stp:normal . + +def-stp:normal skos:prefLabel "normal"@en . + +bw:ukc2102-03700 a def-bw:BathingWater , def-bw:CoastalBathingWater ; + def-bwp:latestBathingWaterProfile + ; + def-bwq:latestComplianceAssessment + ; + def-bwq:latestSampleAssessment ; + def-bw:appointedSewerageUndertaker + ; + def-bw:eubwidNotation "ukc2102-03700"^^def-bw:eubwid ; + def-bw:regionalOrganization ; + def-bw:sedimentTypesPresent def-bw:sand-sediment ; + def-bw:waterQualityImpactedByHeavyRain + false ; + def-bw:yearDesignated ; + def-stp:latestRiskPrediction ; + def-geom:envelope ; + def-ef:samplingPoint ; + def-zoi:zoneOfInfluence ; + dgu:uriSet bw: ; + onsadmingeo:country ; + onsadmingeo:district , ; + owl:sameAs bw:bamburgh-castle ; + skos:prefLabel "Bamburgh Castle"@en . + + + skos:prefLabel "Zone of influence at Low Newton"@en . + + + def-stp:expiresAt "2025-10-02T08:29:00"^^xsd:dateTime ; + def-stp:riskLevel def-stp:normal . + + + def-stp:expiresAt "2025-10-02T08:29:00"^^xsd:dateTime ; + def-stp:riskLevel def-stp:normal . + + + skos:prefLabel "Zone of influence at Newbiggin North"@en . + + + def-stp:expiresAt "2025-10-02T08:29:00"^^xsd:dateTime ; + def-stp:riskLevel def-stp:normal . + + + rdfs:label "Companies House profile for Northumbrian Water Limited"@en . + +bw:ukc2102-03600 a def-bw:CoastalBathingWater , def-bw:BathingWater ; + def-bwp:latestBathingWaterProfile + ; + def-bwq:latestComplianceAssessment + ; + def-bwq:latestSampleAssessment ; + def-bw:appointedSewerageUndertaker + ; + def-bw:eubwidNotation "ukc2102-03600"^^def-bw:eubwid ; + def-bw:regionalOrganization ; + def-bw:sedimentTypesPresent def-bw:sand-sediment ; + def-bw:waterQualityImpactedByHeavyRain + true ; + def-bw:yearDesignated ; + def-stp:latestRiskPrediction ; + def-geom:envelope ; + def-ef:samplingPoint ; + def-zoi:zoneOfInfluence ; + dgu:uriSet bw: ; + onsadmingeo:country ; + onsadmingeo:district , ; + owl:sameAs bw:spittal ; + skos:prefLabel "Spittal"@en . + + + skos:prefLabel "England"@en . + + + rdfs:label "Map bounds for Beadnell"@en . + + + rdfs:label "Map bounds for Spittal"@en . + + + def-bwq:complianceClassification + . + +bw:ukc2104-04280 a def-bw:CoastalBathingWater , def-bw:BathingWater ; + def-bwp:latestBathingWaterProfile + ; + def-bwq:latestComplianceAssessment + ; + def-bwq:latestSampleAssessment ; + def-bw:appointedSewerageUndertaker + ; + def-bw:eubwidNotation "ukc2104-04280"^^def-bw:eubwid ; + def-bw:regionalOrganization ; + def-bw:sedimentTypesPresent def-bw:sand-sediment ; + def-bw:waterQualityImpactedByHeavyRain + false ; + def-bw:yearDesignated ; + def-stp:latestRiskPrediction ; + def-geom:envelope ; + def-ef:samplingPoint ; + def-zoi:zoneOfInfluence ; + dgu:uriSet bw: ; + onsadmingeo:country ; + onsadmingeo:district , ; + owl:sameAs bw:druridge-bay-north ; + skos:prefLabel "Druridge Bay North"@en . + + + skos:prefLabel "Zone of influence at Druridge Bay North"@en . + + + def-bwq:complianceClassification + . + + + spatialrelations:easting "427500"^^xsd:decimal ; + spatialrelations:northing "599750"^^xsd:decimal ; + geo:lat 55.29110916206403 ; + geo:long -1.568532719733309 ; + skos:prefLabel "Sampling point at Druridge Bay North"@en . + +bw: a void:Dataset , dgu:URIset ; + rdfs:label "Bathing waters monitored by the Environment Agency for England and Wales."@en ; + dcterms:description "URI Set of Bathing Waters in England and Wales monitored by the Environment Agency for compliance with the EU Bathing Water Directive"@en ; + dcterms:license ; + dcterms:modified "2025-11-25T09:05:57.727Z"^^xsd:dateTime , "2014-06-30T15:53:44.397Z"^^xsd:dateTime ; + dcterms:source , ; + void:dataDump ; + void:uriRegexPattern "http://environment.data.gov.uk/id/bathing-water/.*" ; + void:vocabulary , geometry: , osadmingeo: , def-bw: , spatialrelations: , dgu: , onsadmingeo: , def-ef: , , , def-geom: ; + dgu:itemType def-bw:BathingWater ; + dgu:status . \ No newline at end of file From 1ab941a979acd9693afe193219c4d2913dd24b5b Mon Sep 17 00:00:00 2001 From: Simon Oakes Date: Tue, 20 Jan 2026 13:04:36 +0000 Subject: [PATCH 2/2] Add encloseDescribe property to API vocab --- vocabs/elda_api.ttl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vocabs/elda_api.ttl b/vocabs/elda_api.ttl index 4b2999402..b46add059 100755 --- a/vocabs/elda_api.ttl +++ b/vocabs/elda_api.ttl @@ -125,6 +125,10 @@ elda:enableForwardHeaders a rdf:Property ; rdfs:comment "" . +elda:encloseDescribe a rdf:Property + ; rdfs:comment "Determine whether to apply a forward closure to describe query results." + . + elda:enhanceViewWith a rdf:Property ; rdfs:comment "" .