Commit 91721702 authored by Andreas Watermeyer's avatar Andreas Watermeyer Committed by Andrea Aime
Browse files

[GEOS-7349] value of default geometry always as GeoJSON geometry, never

within properties
parent 95237544
/* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved
/* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
......@@ -137,7 +137,7 @@ public class GeoJSONGetFeatureResponse extends WFSGetFeatureOutputFormat {
// execute should of set all the header information
// including the lockID
//
// execute should also fail if all of the locks could not be aquired
// execute should also fail if all of the locks could not be acquired
List<FeatureCollection> resultsList = featureCollection.getFeature();
CoordinateReferenceSystem crs = null;
for (int i = 0; i < resultsList.size(); i++) {
......@@ -182,16 +182,6 @@ public class GeoJSONGetFeatureResponse extends WFSGetFeatureOutputFormat {
jsonWriter.key("geometry");
Geometry aGeom = (Geometry) feature.getDefaultGeometry();
if (aGeom == null) {
// In case the default geometry is not set, we will
// just use the first geometry we find
for (int j = 0; j < types.size() && aGeom == null; j++) {
Object value = feature.getAttribute(j);
if (value != null && value instanceof Geometry) {
aGeom = (Geometry) value;
}
}
}
// Write the geometry, whether it is a null or not
if (aGeom != null) {
jsonWriter.writeGeom(aGeom);
......@@ -212,30 +202,27 @@ public class GeoJSONGetFeatureResponse extends WFSGetFeatureOutputFormat {
if( id_option != null && id_option.equals(ad.getLocalName()) ){
continue; // skip this value as it is used as the id
}
if (value != null) {
if (value instanceof Geometry) {
// This is an area of the spec where they
// decided to 'let convention evolve',
// that is how to handle multiple
// geometries. My take is to print the
// geometry here if it's not the default.
// If it's the default that you already
// printed above, so you don't need it here.
if (ad.equals(defaultGeomType)) {
// Do nothing, we wrote it above
// jsonWriter.value("geometry_name");
} else {
jsonWriter.key(ad.getLocalName());
jsonWriter.writeGeom((Geometry) value);
}
if (ad instanceof GeometryDescriptor) {
// This is an area of the spec where they
// decided to 'let convention evolve',
// that is how to handle multiple
// geometries. My take is to print the
// geometry here if it's not the default.
// If it's the default that you already
// printed above, so you don't need it here.
if (ad.equals(defaultGeomType)) {
// Do nothing, we wrote it above
// jsonWriter.value("geometry_name");
} else if(value == null){
jsonWriter.key(ad.getLocalName());
jsonWriter.value(null);
} else {
jsonWriter.key(ad.getLocalName());
jsonWriter.value(value);
jsonWriter.writeGeom((Geometry) value);
}
} else {
jsonWriter.key(ad.getLocalName());
jsonWriter.value(null);
jsonWriter.value(value);
}
}
// Bounding box for feature in properties
......@@ -253,7 +240,7 @@ public class GeoJSONGetFeatureResponse extends WFSGetFeatureOutputFormat {
}
jsonWriter.endArray(); // end features
// Coordinate Referense System
// Coordinate Reference System
try {
if ("true".equals(GeoServerExtensions.getProperty("GEOSERVER_GEOJSON_LEGACY_CRS"))){
// This is wrong, but GeoServer used to do it this way.
......@@ -331,7 +318,7 @@ public class GeoJSONGetFeatureResponse extends WFSGetFeatureOutputFormat {
// Doesn't follow spec, but GeoServer used to do this.
private void writeCrsLegacy(final GeoJSONBuilder jsonWriter,
CoordinateReferenceSystem crs) {
// Coordinate Referense System, currently only if the namespace is
// Coordinate Reference System, currently only if the namespace is
// EPSG
if (crs != null) {
Set<ReferenceIdentifier> ids = crs.getIdentifiers();
......
/* (c) 2014 - 2015 Open Source Geospatial Foundation - all rights reserved
/* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
......@@ -9,7 +9,11 @@ package org.geoserver.wfs.json;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.util.Collection;
......@@ -51,6 +55,7 @@ public class GeoJSONTest extends WFSTestSupport {
public static QName LINE3D = new QName(SystemTestData.CITE_URI, "Line3D", SystemTestData.CITE_PREFIX);
public static QName POINT_LATLON = new QName(SystemTestData.CITE_URI, "PointLatLon", SystemTestData.CITE_PREFIX);
public static QName POINT_LONLAT = new QName(SystemTestData.CITE_URI, "PointLonLat", SystemTestData.CITE_PREFIX);
public static QName MULTI_GEOMETRIES_WITH_NULL = new QName(SystemTestData.CITE_URI, "MultiGeometriesWithNull", SystemTestData.CITE_PREFIX);
@Override
@SuppressWarnings("unchecked")
......@@ -79,7 +84,9 @@ public class GeoJSONTest extends WFSTestSupport {
pointLatLon.setSRS("EPSG:4326");
pointLatLon.setProjectionPolicy(ProjectionPolicy.FORCE_DECLARED);
getCatalog().save(pointLonLat);
// A feature with a constant test setup for testing geometry/geometry_name consistency with null geometries
data.addVectorLayer (MULTI_GEOMETRIES_WITH_NULL, Collections.EMPTY_MAP, getClass(), getCatalog());
}
@Test
......@@ -249,7 +256,8 @@ public class GeoJSONTest extends WFSTestSupport {
assertEquals(rootObject.get("type"),"FeatureCollection");
JSONArray featureCol = rootObject.getJSONArray("features");
JSONObject aFeature = featureCol.getJSONObject(1);
JSONObject aGeometry = aFeature.getJSONObject("geometry");
JSONObject aPropeties = aFeature.getJSONObject("properties");
JSONObject aGeometry = aPropeties.getJSONObject("multiCurveProperty");
assertEquals(aGeometry.getString("type"),"MultiLineString");
JSONArray geomArray = aGeometry.getJSONArray("coordinates");
geomArray = geomArray.getJSONArray(0);
......@@ -290,7 +298,8 @@ public class GeoJSONTest extends WFSTestSupport {
assertTrue(aFeature.getString("id").substring(0,19).equalsIgnoreCase("AggregateGeoFeature"));
// Check that a feature has the expected attributes
JSONObject aGeometry = aFeature.getJSONObject("geometry");
JSONObject aProperties = aFeature.getJSONObject("properties");
JSONObject aGeometry = aProperties.getJSONObject("multiCurveProperty");
//System.out.println(aGeometry.getString("type"));
assertEquals(aGeometry.getString("type"),"MultiLineString");
}
......@@ -480,6 +489,80 @@ public class GeoJSONTest extends WFSTestSupport {
assertThat(aCRS, encodesCRS(expectedCrs));
}
/**
* Tests if:
* <ul>
* <li>"geometry_name" is always the attribute name of the default geometry</li>
* <li>"geometry" is always the attribute value of the default geometry</li>
* <li>the default geometry is never contained within the properties, as duplicate</li>
* </ul>
*
* @throws Exception
*/
@Test
public void testGeometryAndGeometryNameConsistency() throws Exception {
JSONObject collection = (JSONObject) getAsJSON(
"wfs?request=GetFeature&version=1.0.0&typename="
+ getLayerId(MULTI_GEOMETRIES_WITH_NULL) + "&outputformat="
+ JSONType.json);
print(collection);
assertEquals(3, collection.getInt("totalFeatures"));
JSONArray features = collection.getJSONArray("features");
assertEquals(3, features.size());
// see MultiGeometriesWithNull.properties
// -- MultiGeometriesWithNull.0 -- all geoms present
JSONObject feature = features.getJSONObject(0);
assertEquals("MultiGeometriesWithNull.0", feature.getString("id"));
assertEquals("All geometries present, first geometry must be default",
"geom_a", feature.getString("geometry_name"));
JSONObject geometry = feature.getJSONObject("geometry");
JSONArray coords = geometry.getJSONArray("coordinates");
assertEquals("geom_a has coodinate 1", 1, coords.getInt(0));
JSONObject properties = feature.getJSONObject("properties");
assertFalse("geom_a must not be present, its the default geom",
properties.containsKey("geom_a"));
JSONObject propertyGeomB = properties.getJSONObject("geom_b");
coords = propertyGeomB.getJSONArray("coordinates");
assertEquals("geom_b has coodinate 2", 2, coords.getInt(0));
JSONObject propertyGeomC = properties.getJSONObject("geom_c");
coords = propertyGeomC.getJSONArray("coordinates");
assertEquals("geom_c has coodinate 3", 3, coords.getInt(0));
// -- MultiGeometriesWithNull.1 --, geom_b and geom_c present
feature = features.getJSONObject(1);
assertEquals("MultiGeometriesWithNull.1", feature.getString("id"));
assertEquals("1st geometry null, still default", "geom_a",
feature.getString("geometry_name"));
geometry = feature.getJSONObject("geometry");
assertTrue(geometry.isNullObject());
properties = feature.getJSONObject("properties");
assertFalse("geom_a must not be present, its the default geom",
properties.containsKey("geom_a"));
propertyGeomB = properties.getJSONObject("geom_b");
coords = propertyGeomB.getJSONArray("coordinates");
assertEquals("geom_b has coodinate 2", 2, coords.getInt(0));
propertyGeomC = properties.getJSONObject("geom_c");
coords = propertyGeomC.getJSONArray("coordinates");
assertEquals("geom_c has coodinate 3", 3, coords.getInt(0));
// -- MultiGeometriesWithNull.2 --, all geoms null
feature = features.getJSONObject(2);
assertEquals("MultiGeometriesWithNull.2", feature.getString("id"));
assertEquals("no geometries present, 1st still default", "geom_a",
feature.getString("geometry_name"));
geometry = feature.getJSONObject("geometry");
assertTrue(geometry.isNullObject());
properties = feature.getJSONObject("properties");
assertFalse("geom_a must not be present, its the default geom",
properties.containsKey("geom_a"));
propertyGeomB = properties.getJSONObject("geom_b");
assertTrue(propertyGeomB.isNullObject());
propertyGeomC = properties.getJSONObject("geom_c");
assertTrue(propertyGeomC.isNullObject());
}
private org.hamcrest.Matcher<JSONObject> encodesCRS(final CoordinateReferenceSystem crs) {
return new org.hamcrest.BaseMatcher<JSONObject>(){
......
_=geom_a:Point:srid=4326,geom_b:Point:srid=4326,geom_c:Point:srid=4326,Title:String
MultiGeometriesWithNull.0=POINT(1 1)|POINT(2 2)|POINT(3 3)|FeatureWithAllGeometries
MultiGeometriesWithNull.1=|POINT(2 2)|POINT(3 3)|FeatureWithoutAGeometries
MultiGeometriesWithNull.2=|||FeatureWithoutGeometries
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment