Skip to content

Commit

Permalink
Merge pull request #1623 from lat-lon/feature/geoJsonFeatureInfoForma…
Browse files Browse the repository at this point in the history
…t-9399-1582

Add GeoJSON as GetFeatureInfoFormat (deegree 3.6)
  • Loading branch information
stephanr authored Jan 24, 2024
2 parents a257f6f + 39e39c1 commit 932a602
Show file tree
Hide file tree
Showing 15 changed files with 477 additions and 96 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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;

Expand All @@ -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 <code>null</code>
* @param crs the target crs of the geometries, may be <code>null</code>, then
* "EPSG:4326" will be used
* @param skipGeometries <code>true</code> if geometries should not be exported,
* <code>false</code> 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;
}

Expand Down Expand Up @@ -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<Property> geometryProperties = feature.getGeometryProperties();
if (geometryProperties.isEmpty()) {
name("geometry").nullValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -52,6 +53,8 @@ public interface FeatureInfoContext {

XMLStreamWriter getXmlWriter() throws IOException, XMLStreamException;

Writer getWriter() throws IOException;

void sendRedirect(String location) throws IOException;

}
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,25 @@ 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;
import org.deegree.featureinfo.serializing.PlainTextFeatureInfoSerializer;
import org.deegree.featureinfo.serializing.TemplateFeatureInfoSerializer;
import org.deegree.featureinfo.serializing.XsltFeatureInfoSerializer;
import org.deegree.gml.GMLVersion;
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.
*
Expand Down Expand Up @@ -112,6 +112,14 @@ public void addOrReplaceXsltFormat(String format, URL xsltUrl, GMLVersion versio
featureInfoSerializers.put(format, xslt);
}

public void addOrReplaceGeoJsonFormat(String format, boolean allowOtherCrsThanWGS84,
boolean allowExportOfGeometries) {
LOG.debug("Adding GeoJson feature info format");
GeoJsonFeatureInfoSerializer geoJsonSerializer = new GeoJsonFeatureInfoSerializer(allowOtherCrsThanWGS84,
allowExportOfGeometries);
featureInfoSerializers.put(format, geoJsonSerializer);
}

public Set<String> getSupportedFormats() {
return featureInfoSerializers.keySet();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,18 @@ public class FeatureInfoParams {

private ICRS crs;

private final ICRS infoCrs;

public FeatureInfoParams(Map<String, String> 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;
this.withGeometries = withGeometries;
this.schemaLocation = schemaLocation;
this.featureType = type;
this.crs = crs;
this.infoCrs = infoCrs;
}

/**
Expand Down Expand Up @@ -128,4 +131,11 @@ public ICRS getCrs() {
return crs;
}

/**
* @return the CRS of the values to return
*/
public ICRS getInfoCrs() {
return infoCrs;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*----------------------------------------------------------------------------
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: [email protected]
website: http://www.deegree.org/
----------------------------------------------------------------------------*/
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;
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 <a href="mailto:[email protected]">Lyn Goltz </a>
*/
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) {
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) {
geoJsonStreamWriter.write(feature);
}
geoJsonStreamWriter.endFeatureCollection();
}
catch (IOException | TransformationException | UnknownCRSException e) {
LOG.error("GeoJson GFI response could not be written", e);
}
}

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;
}

}
Loading

0 comments on commit 932a602

Please sign in to comment.