From 26110e391fe19398dc721bf0be74bc85c1b9e027 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Tue, 5 Dec 2023 09:10:24 +0100 Subject: [PATCH 1/9] #1582 (#9399) - added GeoJson as supported GFI output format --- .../featureinfo/FeatureInfoContext.java | 3 + .../featureinfo/FeatureInfoManager.java | 7 +++ .../GeoJsonFeatureInfoSerializer.java | 41 ++++++++++++++ .../GeoJsonFeatureInfoSerializerTest.java | 55 +++++++++++++++++++ .../serializing/featurecollection.gml | 2 +- .../utils/StandardFeatureInfoContext.java | 17 ++++++ .../wms/controller/WMSController.java | 3 + .../services/wms/wms_configuration.xsd | 1 + 8 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializer.java create mode 100644 deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializerTest.java diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoContext.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoContext.java index af701a69f1..bf993f5db0 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoContext.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoContext.java @@ -42,6 +42,7 @@ import java.io.IOException; import java.io.OutputStream; +import java.io.Writer; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; @@ -52,6 +53,8 @@ public interface FeatureInfoContext { XMLStreamWriter getXmlWriter() throws IOException, XMLStreamException; + Writer getWriter() throws IOException; + void sendRedirect(String location) throws IOException; } diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoManager.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoManager.java index 142727e708..b96c4032a8 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoManager.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoManager.java @@ -52,6 +52,7 @@ Occam Labs UG (haftungsbeschränkt) import org.deegree.featureinfo.serializing.FeatureInfoGmlWriter; import org.deegree.featureinfo.serializing.FeatureInfoSerializer; +import org.deegree.featureinfo.serializing.GeoJsonFeatureInfoSerializer; import org.deegree.featureinfo.serializing.PlainTextFeatureInfoSerializer; import org.deegree.featureinfo.serializing.TemplateFeatureInfoSerializer; import org.deegree.featureinfo.serializing.XsltFeatureInfoSerializer; @@ -112,6 +113,12 @@ public void addOrReplaceXsltFormat(String format, URL xsltUrl, GMLVersion versio featureInfoSerializers.put(format, xslt); } + public void addOrReplaceGeoJsonFormat(String format) { + LOG.debug("Adding GeoJson feature info format"); + GeoJsonFeatureInfoSerializer geoJsonSerializer = new GeoJsonFeatureInfoSerializer(); + featureInfoSerializers.put(format, geoJsonSerializer); + } + public Set getSupportedFormats() { return featureInfoSerializers.keySet(); } diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializer.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializer.java new file mode 100644 index 0000000000..fa7d3acc11 --- /dev/null +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializer.java @@ -0,0 +1,41 @@ +package org.deegree.featureinfo.serializing; + +import org.deegree.cs.exceptions.TransformationException; +import org.deegree.cs.exceptions.UnknownCRSException; +import org.deegree.feature.Feature; +import org.deegree.feature.FeatureCollection; +import org.deegree.featureinfo.FeatureInfoContext; +import org.deegree.featureinfo.FeatureInfoParams; +import org.deegree.geojson.GeoJsonFeatureWriter; +import org.deegree.geojson.GeoJsonWriter; +import org.slf4j.Logger; + +import java.io.IOException; + +import static org.slf4j.LoggerFactory.getLogger; + +/** + * {@link FeatureInfoSerializer} to serialize feature info result as GeoJson. + * + * @author Lyn Goltz + */ +public class GeoJsonFeatureInfoSerializer implements FeatureInfoSerializer { + + private static final Logger LOG = getLogger(GeoJsonFeatureInfoSerializer.class); + + @Override + public void serialize(FeatureInfoParams params, FeatureInfoContext context) { + try (GeoJsonFeatureWriter geoJsonStreamWriter = new GeoJsonWriter(context.getWriter(), null)) { + geoJsonStreamWriter.startFeatureCollection(); + FeatureCollection featureCollection = params.getFeatureCollection(); + for (Feature feature : featureCollection) { + geoJsonStreamWriter.write(feature); + } + geoJsonStreamWriter.endFeatureCollection(); + } + catch (IOException | TransformationException | UnknownCRSException e) { + LOG.error("GeoJson GFI response could not be written", e); + } + } + +} diff --git a/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializerTest.java b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializerTest.java new file mode 100644 index 0000000000..e23d771afd --- /dev/null +++ b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializerTest.java @@ -0,0 +1,55 @@ +package org.deegree.featureinfo.serializing; + +import org.deegree.feature.FeatureCollection; +import org.deegree.featureinfo.FeatureInfoContext; +import org.deegree.featureinfo.FeatureInfoParams; +import org.deegree.gml.GMLInputFactory; +import org.deegree.gml.GMLStreamReader; +import org.deegree.gml.GMLVersion; +import org.junit.Test; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +/** + * @author Lyn Goltz + */ +public class GeoJsonFeatureInfoSerializerTest { + + @Test + public void testSerialize() throws Exception { + StringWriter writer = new StringWriter(); + GeoJsonFeatureInfoSerializer serializer = new GeoJsonFeatureInfoSerializer(); + FeatureInfoParams params = createParams(); + FeatureInfoContext context = mockContext(writer); + serializer.serialize(params, context); + + String geoJson = writer.toString(); + assertTrue(geoJson.contains("\"type\":")); + assertTrue(geoJson.contains("\"FeatureCollection\"")); + assertTrue(geoJson.contains("AdministrativeUnit_10044117")); + } + + private FeatureInfoParams createParams() throws Exception { + URL resource = TemplateFeatureInfoSerializer.class.getResource("featurecollection.gml"); + GMLStreamReader gmlStreamReader = GMLInputFactory.createGMLStreamReader(GMLVersion.GML_32, resource); + Map nsBindings = new HashMap<>(); + FeatureCollection col = gmlStreamReader.readFeatureCollection(); + return new FeatureInfoParams(nsBindings, col, "text/html", true, null, null, null); + } + + private FeatureInfoContext mockContext(Writer writer) throws IOException { + FeatureInfoContext mock = mock(FeatureInfoContext.class); + when(mock.getWriter()).thenReturn(writer); + return mock; + } + +} diff --git a/deegree-core/deegree-core-featureinfo/src/test/resources/org/deegree/featureinfo/serializing/featurecollection.gml b/deegree-core/deegree-core-featureinfo/src/test/resources/org/deegree/featureinfo/serializing/featurecollection.gml index c5e330ecb1..aba355900f 100644 --- a/deegree-core/deegree-core-featureinfo/src/test/resources/org/deegree/featureinfo/serializing/featurecollection.gml +++ b/deegree-core/deegree-core-featureinfo/src/test/resources/org/deegree/featureinfo/serializing/featurecollection.gml @@ -168,7 +168,7 @@ - + diff --git a/deegree-services/deegree-services-commons/src/main/java/org/deegree/services/controller/utils/StandardFeatureInfoContext.java b/deegree-services/deegree-services-commons/src/main/java/org/deegree/services/controller/utils/StandardFeatureInfoContext.java index d2dd6aa51a..b2f5a1efef 100644 --- a/deegree-services/deegree-services-commons/src/main/java/org/deegree/services/controller/utils/StandardFeatureInfoContext.java +++ b/deegree-services/deegree-services-commons/src/main/java/org/deegree/services/controller/utils/StandardFeatureInfoContext.java @@ -42,6 +42,7 @@ import java.io.IOException; import java.io.OutputStream; +import java.io.Writer; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; @@ -56,6 +57,8 @@ public class StandardFeatureInfoContext implements FeatureInfoContext { private XMLStreamWriter xmlWriter = null; + private Writer writer = null; + private boolean redirected = false; public StandardFeatureInfoContext(HttpResponseBuffer response) { @@ -98,6 +101,20 @@ public XMLStreamWriter getXmlWriter() throws IOException, XMLStreamException { return xmlWriter = response.getXMLWriter(); } + @Override + public Writer getWriter() throws IOException { + if (writer != null) { + return writer; + } + if (redirected) { + throw new IllegalStateException("sendRedirect() already called for FeatureInfoContext"); + } + if (outputStream != null) { + throw new IllegalStateException("getOutputStream() already called for FeatureInfoContext"); + } + return writer = response.getWriter(); + } + @Override public void sendRedirect(String location) throws IOException { diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java index 40dbf0b0b6..3a37acebb7 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java @@ -1025,6 +1025,9 @@ else if (t.getXSLTFile() != null) { featureInfoManager.addOrReplaceXsltFormat(t.getFormat(), metadata.getLocation().resolveToUrl(xsltFile.getValue()), version, workspace); } + else if (t.isGeoJson() != null && t.isGeoJson()) { + featureInfoManager.addOrReplaceGeoJsonFormat(t.getFormat()); + } else if (t.getSerializer() != null) { Serializer serializer = t.getSerializer(); diff --git a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd index d4510132c4..51f6cc3112 100644 --- a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd +++ b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd @@ -109,6 +109,7 @@ + From 304819701e6e4b85f8141807c1d9d3683324e1a3 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Mon, 18 Dec 2023 14:32:55 +0100 Subject: [PATCH 2/9] #1582 (#9399) - use empty element --- .../java/org/deegree/services/wms/controller/WMSController.java | 2 +- .../META-INF/schemas/services/wms/wms_configuration.xsd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java index 3a37acebb7..a3b3109641 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java @@ -1025,7 +1025,7 @@ else if (t.getXSLTFile() != null) { featureInfoManager.addOrReplaceXsltFormat(t.getFormat(), metadata.getLocation().resolveToUrl(xsltFile.getValue()), version, workspace); } - else if (t.isGeoJson() != null && t.isGeoJson()) { + else if (t.getGeoJson() != null) { featureInfoManager.addOrReplaceGeoJsonFormat(t.getFormat()); } else if (t.getSerializer() != null) { diff --git a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd index 51f6cc3112..83891ac506 100644 --- a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd +++ b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd @@ -109,7 +109,7 @@ - + From 5c144ac18ef59a12a8cd7b0523b11a45da558673 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Tue, 19 Dec 2023 14:04:01 +0100 Subject: [PATCH 3/9] #1582 (#9399) - added skipGeometries to GeoJsonWriter --- .../org/deegree/geojson/GeoJsonWriter.java | 22 ++++++++++-- .../geojson/GeoJsonFeatureWriterTest.java | 34 +++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/deegree-core/deegree-core-base/src/main/java/org/deegree/geojson/GeoJsonWriter.java b/deegree-core/deegree-core-base/src/main/java/org/deegree/geojson/GeoJsonWriter.java index 0d1fe55b3e..ec118a8939 100644 --- a/deegree-core/deegree-core-base/src/main/java/org/deegree/geojson/GeoJsonWriter.java +++ b/deegree-core/deegree-core-base/src/main/java/org/deegree/geojson/GeoJsonWriter.java @@ -29,7 +29,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.stream.Collectors; /** @@ -44,7 +43,7 @@ public class GeoJsonWriter extends JsonWriter implements GeoJsonFeatureWriter, G private static final Logger LOG = LoggerFactory.getLogger(GeoJsonWriter.class); - private final GeoJsonGeometryWriter geoJsonGeometryWriter; + private GeoJsonGeometryWriter geoJsonGeometryWriter; private final ICRS crs; @@ -58,10 +57,25 @@ public class GeoJsonWriter extends JsonWriter implements GeoJsonFeatureWriter, G * @throws UnknownCRSException if "crs:84" is not known as CRS (should never happen) */ public GeoJsonWriter(Writer writer, ICRS crs) throws UnknownCRSException { + this(writer, crs, false); + } + + /** + * Instantiates a new {@link GeoJsonWriter}. + * @param writer the writer to write the GeoJSON into, never null + * @param crs the target crs of the geometries, may be null, then + * "EPSG:4326" will be used + * @param skipGeometries true if geometries should not be exported, + * false otherwise + * @throws UnknownCRSException if "crs:84" is not known as CRS (should never happen) + */ + public GeoJsonWriter(Writer writer, ICRS crs, boolean skipGeometries) throws UnknownCRSException { super(writer); setIndent(" "); setHtmlSafe(true); - this.geoJsonGeometryWriter = new GeoJsonGeometryWriter(this, crs); + if (!skipGeometries) { + this.geoJsonGeometryWriter = new GeoJsonGeometryWriter(this, crs); + } this.crs = crs; } @@ -119,6 +133,8 @@ public void writeSingleFeature(Feature feature) throws IOException, UnknownCRSEx } private void writeGeometry(Feature feature) throws IOException, UnknownCRSException, TransformationException { + if (geoJsonGeometryWriter == null) + return; List geometryProperties = feature.getGeometryProperties(); if (geometryProperties.isEmpty()) { name("geometry").nullValue(); diff --git a/deegree-core/deegree-core-base/src/test/java/org/deegree/geojson/GeoJsonFeatureWriterTest.java b/deegree-core/deegree-core-base/src/test/java/org/deegree/geojson/GeoJsonFeatureWriterTest.java index 818e1e1f93..f9029054ba 100644 --- a/deegree-core/deegree-core-base/src/test/java/org/deegree/geojson/GeoJsonFeatureWriterTest.java +++ b/deegree-core/deegree-core-base/src/test/java/org/deegree/geojson/GeoJsonFeatureWriterTest.java @@ -16,6 +16,7 @@ import static com.jayway.jsonpath.matchers.JsonPathMatchers.hasNoJsonPath; import static org.hamcrest.CoreMatchers.hasItem; import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertThat; /** @@ -56,6 +57,39 @@ public void testWrite() throws Exception { } + @Test + public void testWrite_skipGeometries() throws Exception { + StringWriter featureAsJson = new StringWriter(); + GeoJsonWriter geoJsonFeatureWriter = new GeoJsonWriter(featureAsJson, null, true); + Feature cadastralZoning = parseFeature("CadastralZoning.gml"); + + geoJsonFeatureWriter.startFeatureCollection(); + geoJsonFeatureWriter.write(cadastralZoning); + geoJsonFeatureWriter.endFeatureCollection(); + + String featureCollection = featureAsJson.toString(); + + assertThat(featureCollection, JsonPathMatchers.isJson()); + assertThat(featureCollection, hasJsonPath("$.type", is("FeatureCollection"))); + assertThat(featureCollection, hasJsonPath("$.features.length()", is(1))); + assertThat(featureCollection, hasJsonPath("$.features[0].type", is("Feature"))); + assertThat(featureCollection, hasNoJsonPath("$.features[0].srsName")); + assertThat(featureCollection, hasJsonPath("$.features[0].id", is("CP_CADASTRALZONING_Bundesland_02"))); + assertThat(featureCollection, not(hasJsonPath("$.features[0].geometry"))); + assertThat(featureCollection, hasJsonPath("$.features[0].properties.label", is("02"))); + assertThat(featureCollection, hasJsonPath("$.features[0].properties.originalMapScaleDenominator", is(10))); + assertThat(featureCollection, + hasJsonPath("$.features[0].properties.beginLifespanVersion", is("2009-12-15T08:04:54Z"))); + assertThat(featureCollection, hasJsonPath("$.features[0].properties.estimatedAccuracy.uom", is("m"))); + assertThat(featureCollection, hasJsonPath("$.features[0].properties.inspireId.Identifier.localId", + is("urn:adv:oid:DEHHALKA10000005"))); + assertThat(featureCollection, hasJsonPath( + "$.features[0].properties.name.GeographicalName.spelling.SpellingOfName.text", is("Hamburg"))); + assertThat(featureCollection, + hasJsonPath("$.features[0].properties.levelName.LocalisedCharacterString.value", is("Bundesland"))); + + } + @Test public void testWrite_SingleFeature() throws Exception { StringWriter featureAsJson = new StringWriter(); From 497db2b559b17b5dce9c0ab8a4f7bd9ee68349c4 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Tue, 19 Dec 2023 14:06:30 +0100 Subject: [PATCH 4/9] #1582 (#9399) - implemented allowOtherCrsThanWGS84 and allowExportOfGeometries of GeoJson GFI output --- .../featureinfo/FeatureInfoManager.java | 25 ++++--- .../featureinfo/FeatureInfoParams.java | 12 ++- .../GeoJsonFeatureInfoSerializer.java | 27 ++++++- .../GeoJsonFeatureInfoSerializerTest.java | 73 ++++++++++++++++++- .../TemplateFeatureInfoSerializerTest.java | 2 +- .../protocol/wms/ops/GetFeatureInfo.java | 47 +++++++----- .../wms/controller/WMSController.java | 21 +++--- .../services/wms/wms_configuration.xsd | 9 ++- .../wmts/controller/FeatureInfoFetcher.java | 18 ++--- 9 files changed, 178 insertions(+), 56 deletions(-) diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoManager.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoManager.java index b96c4032a8..a45f7dec64 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoManager.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoManager.java @@ -40,16 +40,6 @@ Occam Labs UG (haftungsbeschränkt) ----------------------------------------------------------------------------*/ package org.deegree.featureinfo; -import static org.slf4j.LoggerFactory.getLogger; - -import java.io.IOException; -import java.net.URL; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -import javax.xml.stream.XMLStreamException; - import org.deegree.featureinfo.serializing.FeatureInfoGmlWriter; import org.deegree.featureinfo.serializing.FeatureInfoSerializer; import org.deegree.featureinfo.serializing.GeoJsonFeatureInfoSerializer; @@ -60,6 +50,15 @@ Occam Labs UG (haftungsbeschränkt) import org.deegree.workspace.Workspace; import org.slf4j.Logger; +import javax.xml.stream.XMLStreamException; +import java.io.IOException; +import java.net.URL; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import static org.slf4j.LoggerFactory.getLogger; + /** * Responsible for managing feature info output formats and their serializers. * @@ -113,9 +112,11 @@ public void addOrReplaceXsltFormat(String format, URL xsltUrl, GMLVersion versio featureInfoSerializers.put(format, xslt); } - public void addOrReplaceGeoJsonFormat(String format) { + public void addOrReplaceGeoJsonFormat(String format, boolean allowOtherCrsThanWGS84, + boolean allowExportOfGeometries) { LOG.debug("Adding GeoJson feature info format"); - GeoJsonFeatureInfoSerializer geoJsonSerializer = new GeoJsonFeatureInfoSerializer(); + GeoJsonFeatureInfoSerializer geoJsonSerializer = new GeoJsonFeatureInfoSerializer(allowOtherCrsThanWGS84, + allowExportOfGeometries); featureInfoSerializers.put(format, geoJsonSerializer); } diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoParams.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoParams.java index fe01d2f422..8f8b80015d 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoParams.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoParams.java @@ -68,8 +68,10 @@ public class FeatureInfoParams { private ICRS crs; + private final ICRS infoCrs; + public FeatureInfoParams(Map nsBindings, FeatureCollection col, String format, - boolean withGeometries, String schemaLocation, FeatureType type, ICRS crs) { + boolean withGeometries, String schemaLocation, FeatureType type, ICRS crs, ICRS infoCrs) { this.nsBindings = nsBindings; this.featureCollection = col; this.format = format; @@ -77,6 +79,7 @@ public FeatureInfoParams(Map nsBindings, FeatureCollection col, this.schemaLocation = schemaLocation; this.featureType = type; this.crs = crs; + this.infoCrs = infoCrs; } /** @@ -128,4 +131,11 @@ public ICRS getCrs() { return crs; } + /** + * @return the CRS of the values to return + */ + public ICRS getInfoCrs() { + return infoCrs; + } + } diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializer.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializer.java index fa7d3acc11..7cc204e5b7 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializer.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializer.java @@ -1,5 +1,6 @@ package org.deegree.featureinfo.serializing; +import org.deegree.cs.coordinatesystems.ICRS; import org.deegree.cs.exceptions.TransformationException; import org.deegree.cs.exceptions.UnknownCRSException; import org.deegree.feature.Feature; @@ -23,9 +24,20 @@ public class GeoJsonFeatureInfoSerializer implements FeatureInfoSerializer { private static final Logger LOG = getLogger(GeoJsonFeatureInfoSerializer.class); + private final boolean allowOtherCrsThanWGS84; + + private final boolean allowExportOfGeometries; + + public GeoJsonFeatureInfoSerializer(boolean allowOtherCrsThanWGS84, boolean allowExportOfGeometries) { + this.allowExportOfGeometries = allowExportOfGeometries; + this.allowOtherCrsThanWGS84 = allowOtherCrsThanWGS84; + } + @Override public void serialize(FeatureInfoParams params, FeatureInfoContext context) { - try (GeoJsonFeatureWriter geoJsonStreamWriter = new GeoJsonWriter(context.getWriter(), null)) { + ICRS crs = detectCrs(params); + boolean skipGeometries = detectSkipGeometries(params); + try (GeoJsonFeatureWriter geoJsonStreamWriter = new GeoJsonWriter(context.getWriter(), crs, skipGeometries)) { geoJsonStreamWriter.startFeatureCollection(); FeatureCollection featureCollection = params.getFeatureCollection(); for (Feature feature : featureCollection) { @@ -38,4 +50,17 @@ public void serialize(FeatureInfoParams params, FeatureInfoContext context) { } } + private boolean detectSkipGeometries(FeatureInfoParams params) { + if (allowExportOfGeometries && params.isWithGeometries()) + return false; + return true; + } + + private ICRS detectCrs(FeatureInfoParams params) { + if (allowOtherCrsThanWGS84 && params.getInfoCrs() != null) { + return params.getInfoCrs(); + } + return null; + } + } diff --git a/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializerTest.java b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializerTest.java index e23d771afd..65c0f4d686 100644 --- a/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializerTest.java +++ b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializerTest.java @@ -1,5 +1,7 @@ package org.deegree.featureinfo.serializing; +import org.deegree.cs.coordinatesystems.ICRS; +import org.deegree.cs.persistence.CRSManager; import org.deegree.feature.FeatureCollection; import org.deegree.featureinfo.FeatureInfoContext; import org.deegree.featureinfo.FeatureInfoParams; @@ -15,6 +17,7 @@ import java.util.HashMap; import java.util.Map; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -27,7 +30,7 @@ public class GeoJsonFeatureInfoSerializerTest { @Test public void testSerialize() throws Exception { StringWriter writer = new StringWriter(); - GeoJsonFeatureInfoSerializer serializer = new GeoJsonFeatureInfoSerializer(); + GeoJsonFeatureInfoSerializer serializer = new GeoJsonFeatureInfoSerializer(false, true); FeatureInfoParams params = createParams(); FeatureInfoContext context = mockContext(writer); serializer.serialize(params, context); @@ -36,14 +39,80 @@ public void testSerialize() throws Exception { assertTrue(geoJson.contains("\"type\":")); assertTrue(geoJson.contains("\"FeatureCollection\"")); assertTrue(geoJson.contains("AdministrativeUnit_10044117")); + assertTrue(geoJson.contains("6.910811280489623")); + } + + @Test + public void testSerialize_withInfoCrsNotAllowed() throws Exception { + StringWriter writer = new StringWriter(); + GeoJsonFeatureInfoSerializer serializer = new GeoJsonFeatureInfoSerializer(false, true); + FeatureInfoParams params = createParams("EPSG:25832"); + FeatureInfoContext context = mockContext(writer); + serializer.serialize(params, context); + + String geoJson = writer.toString(); + assertTrue(geoJson.contains("\"type\":")); + assertTrue(geoJson.contains("\"FeatureCollection\"")); + assertTrue(geoJson.contains("AdministrativeUnit_10044117")); + assertTrue(geoJson.contains("6.910811280489623")); + } + + @Test + public void testSerialize_allowOtherCrs_InfoCrs() throws Exception { + StringWriter writer = new StringWriter(); + GeoJsonFeatureInfoSerializer serializer = new GeoJsonFeatureInfoSerializer(true, true); + FeatureInfoParams params = createParams("EPSG:25832"); + FeatureInfoContext context = mockContext(writer); + serializer.serialize(params, context); + + String geoJson = writer.toString(); + assertTrue(geoJson.contains("\"type\":")); + assertTrue(geoJson.contains("\"FeatureCollection\"")); + assertTrue(geoJson.contains("AdministrativeUnit_10044117")); + assertTrue(geoJson.contains("348736.888")); + } + + @Test + public void testSerialize_allowOtherCrs_SkipGeometries() throws Exception { + StringWriter writer = new StringWriter(); + GeoJsonFeatureInfoSerializer serializer = new GeoJsonFeatureInfoSerializer(false, false); + FeatureInfoParams params = createParams(); + FeatureInfoContext context = mockContext(writer); + serializer.serialize(params, context); + + String geoJson = writer.toString(); + assertTrue(geoJson.contains("\"type\":")); + assertTrue(geoJson.contains("\"FeatureCollection\"")); + assertTrue(geoJson.contains("AdministrativeUnit_10044117")); + assertFalse(geoJson.contains("geometries")); + } + + @Test + public void testSerialize_allowOtherCrs_InfoCrsAndSkipGeometries() throws Exception { + StringWriter writer = new StringWriter(); + GeoJsonFeatureInfoSerializer serializer = new GeoJsonFeatureInfoSerializer(true, false); + FeatureInfoParams params = createParams("EPSG:25832"); + FeatureInfoContext context = mockContext(writer); + serializer.serialize(params, context); + + String geoJson = writer.toString(); + assertTrue(geoJson.contains("\"type\":")); + assertTrue(geoJson.contains("\"FeatureCollection\"")); + assertTrue(geoJson.contains("AdministrativeUnit_10044117")); + assertFalse(geoJson.contains("geometries")); } private FeatureInfoParams createParams() throws Exception { + return createParams(null); + } + + private FeatureInfoParams createParams(String crs) throws Exception { URL resource = TemplateFeatureInfoSerializer.class.getResource("featurecollection.gml"); GMLStreamReader gmlStreamReader = GMLInputFactory.createGMLStreamReader(GMLVersion.GML_32, resource); Map nsBindings = new HashMap<>(); FeatureCollection col = gmlStreamReader.readFeatureCollection(); - return new FeatureInfoParams(nsBindings, col, "text/html", true, null, null, null); + ICRS infoCrs = crs != null ? CRSManager.lookup(crs) : null; + return new FeatureInfoParams(nsBindings, col, "text/html", true, null, null, null, infoCrs); } private FeatureInfoContext mockContext(Writer writer) throws IOException { diff --git a/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/TemplateFeatureInfoSerializerTest.java b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/TemplateFeatureInfoSerializerTest.java index c8fe4c7776..1c622eb748 100644 --- a/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/TemplateFeatureInfoSerializerTest.java +++ b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/TemplateFeatureInfoSerializerTest.java @@ -44,7 +44,7 @@ private FeatureInfoParams createParams() throws Exception { GMLStreamReader gmlStreamReader = GMLInputFactory.createGMLStreamReader(GMLVersion.GML_32, resource); Map nsBindings = new HashMap<>(); FeatureCollection col = gmlStreamReader.readFeatureCollection(); - return new FeatureInfoParams(nsBindings, col, "text/html", true, null, null, null); + return new FeatureInfoParams(nsBindings, col, "text/html", true, null, null, null, null); } private FeatureInfoContext mockContext(OutputStream os) throws IOException { diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java index 8ecdcebd51..904a27d868 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java @@ -35,25 +35,6 @@ package org.deegree.protocol.wms.ops; -import static java.lang.Integer.parseInt; -import static java.util.Arrays.asList; -import static org.deegree.commons.ows.exception.OWSException.INVALID_PARAMETER_VALUE; -import static org.deegree.commons.ows.exception.OWSException.INVALID_POINT; -import static org.deegree.commons.ows.exception.OWSException.MISSING_PARAMETER_VALUE; -import static org.deegree.commons.utils.ArrayUtils.splitAsDoubles; -import static org.deegree.commons.utils.CollectionUtils.map; -import static org.deegree.commons.utils.MapUtils.DEFAULT_PIXEL_SIZE; -import static org.deegree.layer.LayerRef.FROM_NAMES; -import static org.deegree.protocol.wms.WMSConstants.VERSION_111; -import static org.deegree.protocol.wms.WMSConstants.VERSION_130; -import static org.slf4j.LoggerFactory.getLogger; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; - import org.deegree.commons.ows.exception.OWSException; import org.deegree.commons.tom.ows.Version; import org.deegree.cs.CRSUtils; @@ -67,6 +48,24 @@ import org.deegree.style.StyleRef; import org.slf4j.Logger; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; + +import static java.lang.Integer.parseInt; +import static java.util.Arrays.asList; +import static org.deegree.commons.ows.exception.OWSException.INVALID_PARAMETER_VALUE; +import static org.deegree.commons.ows.exception.OWSException.INVALID_POINT; +import static org.deegree.commons.ows.exception.OWSException.MISSING_PARAMETER_VALUE; +import static org.deegree.commons.utils.ArrayUtils.splitAsDoubles; +import static org.deegree.commons.utils.CollectionUtils.map; +import static org.deegree.layer.LayerRef.FROM_NAMES; +import static org.deegree.protocol.wms.WMSConstants.VERSION_111; +import static org.deegree.protocol.wms.WMSConstants.VERSION_130; +import static org.slf4j.LoggerFactory.getLogger; + /** * GetFeatureInfo * @@ -96,6 +95,8 @@ public class GetFeatureInfo extends RequestBase { private String infoFormat; + private ICRS infoCrs; + private int featureCount = 1; private boolean returnGeometries; @@ -330,6 +331,7 @@ private double[] handleCommon(Map map) throws OWSException { } returnGeometries = map.get("GEOMETRIES") != null && map.get("GEOMETRIES").equalsIgnoreCase("true"); + infoCrs = map.get("INFO_CRS") != null ? CRSManager.getCRSRef(map.get("INFO_CRS")) : null; return vals; } @@ -363,6 +365,13 @@ public String getInfoFormat() { return infoFormat; } + /** + * @return the CRS of the values to return + */ + public ICRS getInfoCrs() { + return infoCrs; + } + /** * @return the max feature count */ diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java index a3b3109641..e32c752092 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java @@ -103,6 +103,7 @@ import org.deegree.commons.xml.XMLAdapter; import org.deegree.commons.xml.stax.XMLStreamUtils; import org.deegree.cs.coordinatesystems.ICRS; +import org.deegree.cs.exceptions.UnknownCRSException; import org.deegree.cs.refs.coordinatesystem.CRSRef; import org.deegree.feature.FeatureCollection; import org.deegree.feature.types.FeatureType; @@ -523,7 +524,7 @@ private void getLegendGraphic(Map map, HttpResponseBuffer respon private void getFeatureInfo(Map map, final HttpResponseBuffer response, Version version) throws OWSException, IOException, MissingDimensionValue, InvalidDimensionValue { org.deegree.protocol.wms.ops.GetFeatureInfo fi = new org.deegree.protocol.wms.ops.GetFeatureInfo(map, version); - doGetFeatureInfo(map, response, version, fi); + doGetFeatureInfo(response, version, fi); } private void getFeatureInfoSchema(Map map, HttpResponseBuffer response) throws IOException { @@ -682,8 +683,7 @@ public void doXML(XMLStreamReader xmlStream, HttpServletRequest request, HttpRes case GetFeatureInfo: GetFeatureInfoParser getFeatureInfoParser = new GetFeatureInfoParser(); GetFeatureInfo getFeatureInfo = getFeatureInfoParser.parse(xmlStream); - Map gfiMap = new HashMap(); - doGetFeatureInfo(gfiMap, response, VERSION_130, getFeatureInfo); + doGetFeatureInfo(response, VERSION_130, getFeatureInfo); break; default: String msg = "XML request handling is currently not supported for operation " + requestName; @@ -738,8 +738,7 @@ public void doSOAP(org.apache.axiom.soap.SOAPEnvelope soapDoc, HttpServletReques case GetFeatureInfo: GetFeatureInfoParser getFeatureInfoParser = new GetFeatureInfoParser(); GetFeatureInfo getFeatureInfo = getFeatureInfoParser.parse(xmlStream); - Map gfiMap = new HashMap(); - doGetFeatureInfo(gfiMap, response, VERSION_130, getFeatureInfo); + doGetFeatureInfo(response, VERSION_130, getFeatureInfo); break; default: String msg = "SOAP request handling is currently not supported for operation " + requestName; @@ -923,7 +922,7 @@ private LinkedList doGetMap(GetMap getMap, Map map, Vers return headers; } - private void doGetFeatureInfo(Map map, final HttpResponseBuffer response, Version version, + private void doGetFeatureInfo(final HttpResponseBuffer response, Version version, org.deegree.protocol.wms.ops.GetFeatureInfo fi) throws OWSException, IOException { checkGetFeatureInfo(version, fi); ICRS crs = fi.getCoordinateSystem(); @@ -931,6 +930,7 @@ private void doGetFeatureInfo(Map map, final HttpResponseBuffer List queryLayers = map(fi.getQueryLayers(), CollectionUtils.getToStringMapper()); String format = fi.getInfoFormat(); + ICRS infoCrs = fi.getInfoCrs(); LinkedList headers = new LinkedList(); FeatureCollection col = getFeatureInfoProvider.query(this, service, fi, queryLayers, headers); addHeaders(response, headers); @@ -955,7 +955,8 @@ private void doGetFeatureInfo(Map map, final HttpResponseBuffer String loc = getHttpGetURL() + "request=GetFeatureInfoSchema&layers=" + join(",", queryLayers); try { - FeatureInfoParams params = new FeatureInfoParams(nsBindings, col, format, geometries, loc, type, crs); + FeatureInfoParams params = new FeatureInfoParams(nsBindings, col, format, geometries, loc, type, crs, + infoCrs); featureInfoManager.serializeFeatureInfo(params, new StandardFeatureInfoContext(response)); response.flushBuffer(); } @@ -1012,7 +1013,8 @@ private void addSupportedImageFormats(DeegreeWMS conf) { } } - private void addSupportedFeatureInfoFormats(DeegreeWMS conf) throws InstantiationException, IllegalAccessException { + private void addSupportedFeatureInfoFormats(DeegreeWMS conf) + throws InstantiationException, IllegalAccessException, UnknownCRSException { if (conf.getFeatureInfoFormats() != null) { for (GetFeatureInfoFormat t : conf.getFeatureInfoFormats().getGetFeatureInfoFormat()) { if (t.getFile() != null) { @@ -1026,7 +1028,8 @@ else if (t.getXSLTFile() != null) { metadata.getLocation().resolveToUrl(xsltFile.getValue()), version, workspace); } else if (t.getGeoJson() != null) { - featureInfoManager.addOrReplaceGeoJsonFormat(t.getFormat()); + featureInfoManager.addOrReplaceGeoJsonFormat(t.getFormat(), + t.getGeoJson().isAllowOtherCrsThanWGS84(), t.getGeoJson().isAllowExportOfGeometries()); } else if (t.getSerializer() != null) { Serializer serializer = t.getSerializer(); diff --git a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd index 83891ac506..62f5a7f59d 100644 --- a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd +++ b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd @@ -109,7 +109,12 @@ - + + + + + + @@ -146,7 +151,7 @@ - + diff --git a/deegree-services/deegree-services-wmts/src/main/java/org/deegree/services/wmts/controller/FeatureInfoFetcher.java b/deegree-services/deegree-services-wmts/src/main/java/org/deegree/services/wmts/controller/FeatureInfoFetcher.java index 8ec366699d..ad41d8f67a 100644 --- a/deegree-services/deegree-services-wmts/src/main/java/org/deegree/services/wmts/controller/FeatureInfoFetcher.java +++ b/deegree-services/deegree-services-wmts/src/main/java/org/deegree/services/wmts/controller/FeatureInfoFetcher.java @@ -40,14 +40,6 @@ Occam Labs UG (haftungsbeschränkt) ----------------------------------------------------------------------------*/ package org.deegree.services.wmts.controller; -import static org.deegree.commons.ows.exception.OWSException.INVALID_PARAMETER_VALUE; - -import java.io.IOException; -import java.util.HashMap; -import java.util.List; - -import javax.xml.stream.XMLStreamException; - import org.deegree.commons.ows.exception.OWSException; import org.deegree.cs.coordinatesystems.ICRS; import org.deegree.feature.FeatureCollection; @@ -61,6 +53,13 @@ Occam Labs UG (haftungsbeschränkt) import org.deegree.tile.TileDataLevel; import org.deegree.tile.TileDataSet; +import javax.xml.stream.XMLStreamException; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; + +import static org.deegree.commons.ows.exception.OWSException.INVALID_PARAMETER_VALUE; + /** * Responsible for fetching features from tile layers, prepared to immediately be * serialized. @@ -105,7 +104,8 @@ void fetch(FeatureInfoManager featureInfoManager, HttpResponseBuffer response) ICRS crs = tds.getTileMatrixSet().getSpatialMetadata().getEnvelope().getCoordinateSystem(); HashMap nsBindings = new HashMap(); - FeatureInfoParams params = new FeatureInfoParams(nsBindings, col, gfi.getInfoFormat(), false, null, null, crs); + FeatureInfoParams params = new FeatureInfoParams(nsBindings, col, gfi.getInfoFormat(), false, null, null, crs, + null); featureInfoManager.serializeFeatureInfo(params, new StandardFeatureInfoContext(response)); } From cd5f9ede6bacfb98abe1a2ae8ef2d1da3f0cdf42 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Tue, 19 Dec 2023 14:34:50 +0100 Subject: [PATCH 5/9] #1582 (#9399) - renamed GeoJson to GeoJSON --- .../org/deegree/services/wms/controller/WMSController.java | 4 ++-- .../META-INF/schemas/services/wms/wms_configuration.xsd | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java index e32c752092..180d08bbc9 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java @@ -1027,9 +1027,9 @@ else if (t.getXSLTFile() != null) { featureInfoManager.addOrReplaceXsltFormat(t.getFormat(), metadata.getLocation().resolveToUrl(xsltFile.getValue()), version, workspace); } - else if (t.getGeoJson() != null) { + else if (t.getGeoJSON() != null) { featureInfoManager.addOrReplaceGeoJsonFormat(t.getFormat(), - t.getGeoJson().isAllowOtherCrsThanWGS84(), t.getGeoJson().isAllowExportOfGeometries()); + t.getGeoJSON().isAllowOtherCrsThanWGS84(), t.getGeoJSON().isAllowExportOfGeometries()); } else if (t.getSerializer() != null) { Serializer serializer = t.getSerializer(); diff --git a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd index 62f5a7f59d..deadc0c39b 100644 --- a/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd +++ b/deegree-services/deegree-services-wms/src/main/resources/META-INF/schemas/services/wms/wms_configuration.xsd @@ -109,7 +109,7 @@ - + From b360d112da2cf11af4e7fc0c5c117ece983ee002 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Tue, 19 Dec 2023 14:35:20 +0100 Subject: [PATCH 6/9] #1582 (#9399) - described GeoJSON as GFI output format --- .../src/main/asciidoc/webservices.adoc | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/deegree-services/deegree-webservices-handbook/src/main/asciidoc/webservices.adoc b/deegree-services/deegree-webservices-handbook/src/main/asciidoc/webservices.adoc index e3efdeb724..a4dc074050 100644 --- a/deegree-services/deegree-webservices-handbook/src/main/asciidoc/webservices.adoc +++ b/deegree-services/deegree-webservices-handbook/src/main/asciidoc/webservices.adoc @@ -1268,6 +1268,30 @@ _GML_32_. If you want to learn more about the templating format, read the following sections. +==== GeoJSON feature info format + +Besides XML, Text or HTML, deegree supports GeoJSON as output format: + +[source,xml] +---- + + + + application/geo+json + + +---- + +Using option element _GeoJSON_, it possible to enable GeoJSON as GetFeature output format. +The _GeoJSON_ option has the following sub-options: + +[width="100%",cols="15%,15%,10%,60%",options="header",] +|=== +|Option |Cardinality |Value |Description +| @allowExportOfGeometries| 0..1 | Boolean | Per default geometries are not written. With this option the geometries are written if the vendor-specific parameter GEOMETRIES is set to true in the request. Default: false +| @allowOtherCrsThanWGS84 | 0..1 | Boolean | GeoJSON only allows geometries in WGS84. With this option the geometries are written in the requested CRS. The vendor-specific parameter _INFO_CRS_ can be used in the request to control the CRS of the geometries in the response. Default: false +|=== + ==== FeatureInfo templating format The templating format can be used to create text based output formats From 321a6dc60d89eb2b3b064a3aecde0204c930e6d4 Mon Sep 17 00:00:00 2001 From: dstenger Date: Tue, 19 Dec 2023 16:00:28 +0100 Subject: [PATCH 7/9] Update GeoJSON sections of GetFeature and GetFeatureInfo --- .../src/main/asciidoc/webservices.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/deegree-services/deegree-webservices-handbook/src/main/asciidoc/webservices.adoc b/deegree-services/deegree-webservices-handbook/src/main/asciidoc/webservices.adoc index a4dc074050..00d60b495d 100644 --- a/deegree-services/deegree-webservices-handbook/src/main/asciidoc/webservices.adoc +++ b/deegree-services/deegree-webservices-handbook/src/main/asciidoc/webservices.adoc @@ -665,7 +665,7 @@ would be generated by the WFS: ==== Adding GeoJSON output formats -Using option element _GeoJSONFormat, it possible to enable GeoJSON as GetFeature output format. +Using element _GeoJSONFormat_ enables GeoJSON as GetFeature output format. The _GeoJSON_ option has the following sub-options: [width="100%",cols="15%,15%,10%,60%",options="header",] @@ -1270,7 +1270,7 @@ following sections. ==== GeoJSON feature info format -Besides XML, Text or HTML, deegree supports GeoJSON as output format: +Besides XML, Text and HTML, deegree supports GeoJSON as output format: [source,xml] ---- @@ -1282,14 +1282,14 @@ Besides XML, Text or HTML, deegree supports GeoJSON as output format: ---- -Using option element _GeoJSON_, it possible to enable GeoJSON as GetFeature output format. +Using the element _GeoJSON_ enables GeoJSON as GetFeatureInfo output format. The _GeoJSON_ option has the following sub-options: [width="100%",cols="15%,15%,10%,60%",options="header",] |=== |Option |Cardinality |Value |Description -| @allowExportOfGeometries| 0..1 | Boolean | Per default geometries are not written. With this option the geometries are written if the vendor-specific parameter GEOMETRIES is set to true in the request. Default: false -| @allowOtherCrsThanWGS84 | 0..1 | Boolean | GeoJSON only allows geometries in WGS84. With this option the geometries are written in the requested CRS. The vendor-specific parameter _INFO_CRS_ can be used in the request to control the CRS of the geometries in the response. Default: false +| @allowExportOfGeometries| 0..1 | Boolean | Per default, geometries are not written. With this option, the geometries are written if the vendor-specific parameter _GEOMETRIES_ is set to true in the request. Default: false +| @allowOtherCrsThanWGS84 | 0..1 | Boolean | GeoJSON only allows geometries in WGS84. With this option, the geometries are written in the requested CRS. The vendor-specific parameter _INFO_CRS_ can be used in the request to control the CRS of the geometries in the response. Default: false |=== ==== FeatureInfo templating format From aa761c8ac8ed54a648ddf9faf64d7cb7a4121394 Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Wed, 17 Jan 2024 18:46:42 +0100 Subject: [PATCH 8/9] #1582 (#9399) - added description of parameter GEOMETRIES and INFO_CRS --- .../src/main/asciidoc/webservices.adoc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/deegree-services/deegree-webservices-handbook/src/main/asciidoc/webservices.adoc b/deegree-services/deegree-webservices-handbook/src/main/asciidoc/webservices.adoc index 00d60b495d..6e72f5c610 100644 --- a/deegree-services/deegree-webservices-handbook/src/main/asciidoc/webservices.adoc +++ b/deegree-services/deegree-webservices-handbook/src/main/asciidoc/webservices.adoc @@ -671,7 +671,7 @@ The _GeoJSON_ option has the following sub-options: [width="100%",cols="15%,15%,10%,60%",options="header",] |=== |Option |Cardinality |Value |Description -| @allowOtherCrsThanWGS84 | 0..1 | Boolean | GeoJson only allows geometries in WGS84. With this option the default behaviour of a WFS can be enabled: the CRS of the requested geometries are written in the requested CRS of the DefaultCRS of the WFS. Default: false +| @allowOtherCrsThanWGS84 | 0..1 | Boolean | GeoJSON only allows geometries in WGS84. With this option the default behaviour of a WFS can be enabled: the CRS of the requested geometries are written in the requested CRS of the DefaultCRS of the WFS. Default: false | MimeType | 1..n | String | Mime types associated with this format configuration |=== @@ -1268,6 +1268,7 @@ _GML_32_. If you want to learn more about the templating format, read the following sections. +[[geojson-featureinfo-configuration]] ==== GeoJSON feature info format Besides XML, Text and HTML, deegree supports GeoJSON as output format: @@ -1685,6 +1686,11 @@ total). With the two vendorspecific parameter FILTERPROPERTY and FILTERVALUE you can request rendering just a defined list of features. Each feature to be rendered will be identified by the value of a given property. The name of the property is defined by the parameter filterproperty. The name of the property is not qualified so all properties with the given local name will be considered. A list of valid property values will be defined using parameter filtervalue, multiple values must be comma separated. Each layer - or better its underlying data source - requested by a GeMap will evaluated for having a feature with a property with given name and one of the defined values. Just the features matching this filter condition will be rendered. It's quite natural that only layer with an underlying Feature-DataSource can be filtered. The other parameters addressed in the GetMap (e.g. the style) request are not effected by this parameters. If the filter cannot be applied to the layer, e.g. cause it is a raster layer or the data source does not have a matching property, the filter will be ignored. If one the parameters is missing or the value empty, the filter is not applied. Example: FILTERPROPERTY=type&FILTERVALUE=stone,wood + + +In a GetFeatureInfo request the parameter GEOMETRIES can be used to return the geometries of a feature in GML and GeoJSON output. The default is false. The parameter INFO_CRS can be used in the GetFeatureInfo request to control the CRS of the geometries in the GeoJSON response. Default is WGS84. For GeoJSON output both parameters applies only if it is enabled in the configuration (<>). + + [[anchor-xml-request-encoding]] ==== XML request encoding From 41ff110e67bab052d88b50a72cf573cf8015cf9c Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Wed, 24 Jan 2024 13:05:44 +0100 Subject: [PATCH 9/9] #1582 (#9399) - added missing header --- .../GeoJsonFeatureInfoSerializer.java | 25 +++++++++++++++++++ .../GeoJsonFeatureInfoSerializerTest.java | 25 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializer.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializer.java index 7cc204e5b7..eeadbc261b 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializer.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializer.java @@ -1,3 +1,28 @@ +/*---------------------------------------------------------------------------- + This file is part of deegree + Copyright (C) 2001-2024 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + and others + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + e-mail: info@deegree.org + website: http://www.deegree.org/ +----------------------------------------------------------------------------*/ package org.deegree.featureinfo.serializing; import org.deegree.cs.coordinatesystems.ICRS; diff --git a/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializerTest.java b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializerTest.java index 65c0f4d686..41250b4acd 100644 --- a/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializerTest.java +++ b/deegree-core/deegree-core-featureinfo/src/test/java/org/deegree/featureinfo/serializing/GeoJsonFeatureInfoSerializerTest.java @@ -1,3 +1,28 @@ +/*---------------------------------------------------------------------------- + This file is part of deegree + Copyright (C) 2001-2024 by: + - Department of Geography, University of Bonn - + and + - lat/lon GmbH - + and others + + This library is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2.1 of the License, or (at your option) + any later version. + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, write to the Free Software Foundation, Inc., + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Contact information: + + e-mail: info@deegree.org + website: http://www.deegree.org/ +----------------------------------------------------------------------------*/ package org.deegree.featureinfo.serializing; import org.deegree.cs.coordinatesystems.ICRS;