/* (c) 2014 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. */ package org.geoserver.wfs; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; import javax.xml.namespace.QName; import org.geoserver.catalog.ProjectionPolicy; import org.geoserver.data.test.SystemTestData; import org.geoserver.data.test.SystemTestData.LayerProperty; import org.geotools.referencing.CRS; import org.junit.Before; import org.junit.Test; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.w3c.dom.Document; import org.w3c.dom.Element; public class ReprojectionWriteTest extends WFSTestSupport { private static final String TARGET_CRS_CODE = "EPSG:900913"; public static QName NULL_GEOMETRIES = new QName(SystemTestData.CITE_URI, "NullGeometries", SystemTestData.CITE_PREFIX); public static QName GOOGLE = new QName(SystemTestData.CITE_URI, "GoogleFeatures", SystemTestData.CITE_PREFIX); MathTransform tx; @Before public void setUpTX() throws Exception { CoordinateReferenceSystem epsg4326 = CRS.decode(TARGET_CRS_CODE); CoordinateReferenceSystem epsg32615 = CRS.decode("EPSG:32615"); tx = CRS.findMathTransform(epsg32615, epsg4326); this.revertLayer(SystemTestData.POLYGONS); } @Override protected void setUpInternal(SystemTestData dataDirectory) throws Exception { dataDirectory.addVectorLayer(NULL_GEOMETRIES, Collections.EMPTY_MAP, getClass(), getCatalog()); Map<LayerProperty, Object> extra = new HashMap<LayerProperty, Object>(); extra.put(LayerProperty.PROJECTION_POLICY, ProjectionPolicy.REPROJECT_TO_DECLARED); extra.put(LayerProperty.SRS, 900913); dataDirectory.addVectorLayer(GOOGLE, extra, getClass(), getCatalog()); } @Test public void testInsertSrsName() throws Exception { String q = "wfs?request=getfeature&service=wfs&version=1.0.0&typeName=" + SystemTestData.POLYGONS.getLocalPart(); Document dom = getAsDOM( q ); Element polygonProperty = getFirstElementByTagName(dom, "cgf:polygonProperty"); Element posList = getFirstElementByTagName( polygonProperty, "gml:coordinates"); double[] c = coordinates(posList.getFirstChild().getNodeValue()); double[] cr = new double[c.length]; tx.transform(c, 0, cr, 0, cr.length/2); String xml = "<wfs:Transaction service=\"WFS\" version=\"1.0.0\" " + " xmlns:wfs=\"http://www.opengis.net/wfs\" " + " xmlns:gml=\"http://www.opengis.net/gml\" " + " xmlns:cgf=\"" + SystemTestData.CGF_URI + "\">" + "<wfs:Insert handle=\"insert-1\" srsName=\"" + TARGET_CRS_CODE + "\">" + " <cgf:Polygons>" + "<cgf:polygonProperty>" + "<gml:Polygon >" + "<gml:outerBoundaryIs>" + "<gml:LinearRing>" + "<gml:coordinates>"; for ( int i = 0; i < cr.length; ) { xml += cr[i++] + "," + cr[i++]; if ( i < cr.length - 1 ) { xml += " "; } } xml += "</gml:coordinates>" + "</gml:LinearRing>" + "</gml:outerBoundaryIs>" + "</gml:Polygon>" + "</cgf:polygonProperty>" + " </cgf:Polygons>" + "</wfs:Insert>" + "</wfs:Transaction>"; postAsDOM( "wfs", xml ); dom = getAsDOM( q ); assertEquals( 2, dom.getElementsByTagName( SystemTestData.POLYGONS.getPrefix() + ":" + SystemTestData.POLYGONS.getLocalPart()).getLength() ); } @Test public void testInsertGeomSrsName() throws Exception { String q = "wfs?request=getfeature&service=wfs&version=1.0&typeName=" + SystemTestData.POLYGONS.getLocalPart(); Document dom = getAsDOM( q ); Element polygonProperty = getFirstElementByTagName(dom, "cgf:polygonProperty"); Element posList = getFirstElementByTagName( polygonProperty, "gml:coordinates"); double[] c = coordinates(posList.getFirstChild().getNodeValue()); double[] cr = new double[c.length]; tx.transform(c, 0, cr, 0, cr.length/2); String xml = "<wfs:Transaction service=\"WFS\" version=\"1.0.0\" " + " xmlns:wfs=\"http://www.opengis.net/wfs\" " + " xmlns:gml=\"http://www.opengis.net/gml\" " + " xmlns:cgf=\"" + SystemTestData.CGF_URI + "\">" + "<wfs:Insert handle=\"insert-1\">" + " <cgf:Polygons>" + "<cgf:polygonProperty>" + "<gml:Polygon srsName=\"" + TARGET_CRS_CODE + "\">" + "<gml:outerBoundaryIs>" + "<gml:LinearRing>" + "<gml:coordinates>"; for ( int i = 0; i < cr.length; ) { xml += cr[i++] + "," + cr[i++]; if ( i < cr.length - 1 ) { xml += " "; } } xml += "</gml:coordinates>" + "</gml:LinearRing>" + "</gml:outerBoundaryIs>" + "</gml:Polygon>" + "</cgf:polygonProperty>" + " </cgf:Polygons>" + "</wfs:Insert>" + "</wfs:Transaction>"; postAsDOM( "wfs", xml ); dom = getAsDOM( q ); assertEquals( 2, dom.getElementsByTagName( SystemTestData.POLYGONS.getPrefix() + ":" + SystemTestData.POLYGONS.getLocalPart()).getLength() ); } @Test public void testUpdate() throws Exception { String q = "wfs?request=getfeature&service=wfs&version=1.0&typeName=" + SystemTestData.POLYGONS.getLocalPart(); Document dom = getAsDOM( q ); Element polygonProperty = getFirstElementByTagName(dom, "cgf:polygonProperty"); Element posList = getFirstElementByTagName( polygonProperty, "gml:coordinates"); double[] c = coordinates(posList.getFirstChild().getNodeValue()); double[] cr = new double[c.length]; tx.transform(c, 0, cr, 0, cr.length/2); // perform an update String xml = "<wfs:Transaction service=\"WFS\" version=\"1.0.0\" " + "xmlns:cgf=\"http://www.opengis.net/cite/geometry\" " + "xmlns:ogc=\"http://www.opengis.net/ogc\" " + "xmlns:wfs=\"http://www.opengis.net/wfs\" " + "xmlns:gml=\"http://www.opengis.net/gml\"> " + "<wfs:Update typeName=\"cgf:Polygons\" > " + "<wfs:Property>" + "<wfs:Name>polygonProperty</wfs:Name>" + "<wfs:Value>" + "<gml:Polygon srsName=\"" + TARGET_CRS_CODE + "\">" + "<gml:outerBoundaryIs>" + "<gml:LinearRing>" + "<gml:coordinates>"; for ( int i = 0; i < cr.length; ) { xml += cr[i++] + "," + cr[i++]; if ( i < cr.length - 1 ) { xml += " "; } } xml += "</gml:coordinates>" + "</gml:LinearRing>" + "</gml:outerBoundaryIs>" + "</gml:Polygon>" + "</wfs:Value>" + "</wfs:Property>" + "<ogc:Filter>" + "<ogc:PropertyIsEqualTo>" + "<ogc:PropertyName>id</ogc:PropertyName>" + "<ogc:Literal>t0002</ogc:Literal>" + "</ogc:PropertyIsEqualTo>" + "</ogc:Filter>" + "</wfs:Update>" + "</wfs:Transaction>"; dom = postAsDOM( "wfs", xml ); assertEquals( "wfs:WFS_TransactionResponse", dom.getDocumentElement().getNodeName() ); Element success = getFirstElementByTagName(dom, "wfs:SUCCESS" ); assertNotNull(success); dom = getAsDOM(q); polygonProperty = getFirstElementByTagName(dom, "cgf:polygonProperty"); posList = getFirstElementByTagName( polygonProperty, "gml:coordinates"); double[] c1 = coordinates(posList.getFirstChild().getNodeValue()); assertEquals( c.length, c1.length ); for ( int i = 0; i < c.length; i++ ) { int x = (int)(c[i] + 0.5); int y = (int)(c1[i] + 0.5); assertEquals(x,y); } } private double[] coordinates(String string) { StringTokenizer st = new StringTokenizer(string, " "); double[] coordinates = new double[st.countTokens()*2]; int i = 0; while(st.hasMoreTokens()) { String tuple = st.nextToken(); coordinates[i++] = Double.parseDouble(tuple.split(",")[0]); coordinates[i++] = Double.parseDouble(tuple.split(",")[1]); } return coordinates; } }