/* (c) 2016 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wfs.v1_1;
import static org.junit.Assert.*;
import java.io.IOException;
import java.util.Collections;
import javax.xml.namespace.QName;
import org.apache.commons.io.IOUtils;
import org.custommonkey.xmlunit.XMLUnit;
import org.custommonkey.xmlunit.XpathEngine;
import org.custommonkey.xmlunit.exceptions.XpathException;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.wfs.WFSTestSupport;
import org.geotools.data.DataUtilities;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.geometry.jts.coordinatesequence.CoordinateSequences;
import org.junit.Before;
import org.junit.Test;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import org.w3c.dom.Document;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.WKTReader;
import com.vividsolutions.jts.io.WKTWriter;
public class Transaction3DTest extends WFSTestSupport {
static final QName FULL3D = new QName(SystemTestData.CITE_URI, "full3d",
SystemTestData.CITE_PREFIX);
static final FilterFactory2 FF = CommonFactoryFinder.getFilterFactory2();
private XpathEngine xpath;
private WKTReader wkt = new WKTReader();
@Override
protected void setUpTestData(SystemTestData testData) throws Exception {
// only need the 3d test data, not the rest
}
@Before
public void setupXPathEngine() {
xpath = XMLUnit.newXpathEngine();
}
@Before
public void revert() throws Exception {
getTestData().addVectorLayer(FULL3D, Collections.emptyMap(), getClass(), getCatalog());
}
@Test
public void testInsert3DPoint() throws Exception {
Document insertDom = postRequest("insertPoint3d.xml");
print(insertDom);
String fid = assertSuccesfulInsert(insertDom);
Document featureDom = getFeature(fid);
print(featureDom);
assertEquals("New point", xpath.evaluate("//cite:full3d/gml:name", featureDom));
assertEquals("3", xpath.evaluate("//cite:full3d/cite:geom/gml:Point/@srsDimension", featureDom));
assertEquals("204330 491816 16", xpath.evaluate("//cite:full3d/cite:geom/gml:Point/gml:pos", featureDom));
// check it's actually 3d as a geometry
SimpleFeature feature = getFeatureFromStore(fid);
Geometry g = (Geometry) feature.getDefaultGeometry();
assertEqualND(g, wkt.read("POINT(204330 491816 16)"));
}
@Test
public void testInsert3DLinestring() throws Exception {
Document insertDom = postRequest("insertLinestring3d.xml");
// print(insertDom);
String fid = assertSuccesfulInsert(insertDom);
Document featureDom = getFeature(fid);
assertEquals("New line", xpath.evaluate("//cite:full3d/gml:name", featureDom));
assertEquals("3", xpath.evaluate("//cite:full3d/cite:geom/gml:LineString/@srsDimension", featureDom));
assertEquals("204330 491816 16 204319 491814 16", xpath.evaluate("//cite:full3d/cite:geom/gml:LineString/gml:posList", featureDom));
// check it's actually 3d as a geometry
SimpleFeature feature = getFeatureFromStore(fid);
Geometry g = (Geometry) feature.getDefaultGeometry();
assertEqualND(g, wkt.read("LINESTRING(204330 491816 16, 204319 491814 16)"));
}
@Test
public void testInsert3DPolygon() throws Exception {
Document insertDom = postRequest("insertPolygon3d.xml");
// print(insertDom);
String fid = assertSuccesfulInsert(insertDom);
Document featureDom = getFeature(fid);
// print(featureDom);
assertEquals("New polygon", xpath.evaluate("//cite:full3d/gml:name", featureDom));
assertEquals("3", xpath.evaluate("//cite:full3d/cite:geom/gml:Polygon/@srsDimension", featureDom));
assertEquals("94000 471000 10 94001 471000 11 94001 471001 12 94000 471001 13 94000 471000 10", xpath.evaluate("//cite:full3d/cite:geom/gml:Polygon/gml:exterior/gml:LinearRing/gml:posList", featureDom));
// check it's actually 3d as a geometry
SimpleFeature feature = getFeatureFromStore(fid);
Geometry g = (Geometry) feature.getDefaultGeometry();
assertEqualND(g, wkt.read("POLYGON((94000 471000 10, 94001 471000 11, 94001 471001 12, 94000 471001 13, 94000 471000 10))"));
}
@Test
public void testDelete3DPoint() throws Exception {
Document deleteDom = postRequest("delete3d.xml", "${id}", "full3d.point");
// print(deleteDom);
assertSuccesfulDelete(deleteDom);
assertNull(getFeatureFromStore("full3d.point"));
assertEquals(2, getCountFromStore(Filter.INCLUDE));
}
@Test
public void testDelete3DLineString() throws Exception {
Document deleteDom = postRequest("delete3d.xml", "${id}", "full3d.ls");
// print(deleteDom);
assertSuccesfulDelete(deleteDom);
assertNull(getFeatureFromStore("full3d.ls"));
assertEquals(2, getCountFromStore(Filter.INCLUDE));
}
@Test
public void testDelete3DPolygon() throws Exception {
Document deleteDom = postRequest("delete3d.xml", "${id}", "full3d.poly");
// print(deleteDom);
assertSuccesfulDelete(deleteDom);
assertNull(getFeatureFromStore("full3d.poly"));
assertEquals(2, getCountFromStore(Filter.INCLUDE));
}
@Test
public void testUpdate3DPoint() throws Exception {
Document updateDom = postRequest("updatePoint3d.xml");
// print(deleteDom);
assertSuccesfulUpdate(updateDom);
SimpleFeature feature = getFeatureFromStore("full3d.point");
Geometry g = (Geometry) feature.getDefaultGeometry();
assertEqualND(g, wkt.read("POINT(204330 491816 16)"));
assertEquals(3, getCountFromStore(Filter.INCLUDE));
}
@Test
public void testUpdate3DLinestring() throws Exception {
Document updateDom = postRequest("updateLinestring3d.xml");
// print(deleteDom);
assertSuccesfulUpdate(updateDom);
SimpleFeature feature = getFeatureFromStore("full3d.ls");
Geometry g = (Geometry) feature.getDefaultGeometry();
assertEqualND(g, wkt.read("LINESTRING(204330 491816 16, 204319 491814 16)"));
assertEquals(3, getCountFromStore(Filter.INCLUDE));
}
@Test
public void testUpdate3DPolygon() throws Exception {
Document updateDom = postRequest("updatePolygon3d.xml");
// print(deleteDom);
assertSuccesfulUpdate(updateDom);
SimpleFeature feature = getFeatureFromStore("full3d.poly");
Geometry g = (Geometry) feature.getDefaultGeometry();
assertEqualND(g, wkt.read("POLYGON((94000 471000 10, 94001 471000 11, 94001 471001 12, 94000 471001 13, 94000 471000 10))"));
assertEquals(3, getCountFromStore(Filter.INCLUDE));
}
private String assertSuccesfulInsert(Document dom) throws XpathException {
assertEquals("1", xpath.evaluate("/wfs:TransactionResponse/wfs:TransactionSummary/wfs:totalInserted", dom));
return xpath.evaluate("/wfs:TransactionResponse/wfs:InsertResults/wfs:Feature/ogc:FeatureId/@fid", dom);
}
private void assertSuccesfulDelete(Document dom) throws XpathException {
assertEquals("1", xpath.evaluate("/wfs:TransactionResponse/wfs:TransactionSummary/wfs:totalDeleted", dom));
}
private void assertSuccesfulUpdate(Document dom) throws XpathException {
assertEquals("1", xpath.evaluate("/wfs:TransactionResponse/wfs:TransactionSummary/wfs:totalUpdated", dom));
}
private void assertEqualND(Geometry test, Geometry expected) {
WKTWriter writer = new WKTWriter(3);
assertTrue("Expected " + writer.write(expected) + " but got " + writer.write(test), CoordinateSequences.equalsND(expected, test));
}
private Document postRequest(String requestFile, String... variableMap) throws IOException, Exception {
String xml = IOUtils.toString(getClass().getResourceAsStream(requestFile));
if(variableMap != null) {
for (int i = 0; i < variableMap.length; i+=2) {
String key = variableMap[i];
String value = variableMap[i +1];
xml = xml.replace(key, value);
}
}
Document dom = postAsDOM("wfs", xml);
return dom;
}
private Document getFeature(String featureId) throws IOException, Exception {
Document dom = getAsDOM("wfs?service=WFS&version=1.1.0&request=GetFeature&typeName=" + getLayerId(FULL3D) + "&featureId=" + featureId);
assertEquals("1", xpath.evaluate("count(//cite:full3d)", dom));
return dom;
}
private SimpleFeature getFeatureFromStore(String fid) throws IOException {
FeatureTypeInfo ftInfo = getCatalog().getFeatureTypeByName(getLayerId(FULL3D));
SimpleFeatureSource featureSource = (SimpleFeatureSource) ftInfo.getFeatureSource(null, null);
SimpleFeatureCollection fc = featureSource.getFeatures(FF.id(FF.featureId(fid)));
SimpleFeature first = DataUtilities.first(fc);
return first;
}
private int getCountFromStore(Filter filter) throws IOException {
FeatureTypeInfo ftInfo = getCatalog().getFeatureTypeByName(getLayerId(FULL3D));
SimpleFeatureSource featureSource = (SimpleFeatureSource) ftInfo.getFeatureSource(null, null);
SimpleFeatureCollection fc = featureSource.getFeatures(filter);
return fc.size();
}
}