001: package org.geoserver.wfs.v1_1;
002:
003: import java.util.StringTokenizer;
004:
005: import org.geoserver.data.test.MockData;
006: import org.geoserver.wfs.WFSTestSupport;
007: import org.geotools.referencing.CRS;
008: import org.opengis.referencing.crs.CoordinateReferenceSystem;
009: import org.opengis.referencing.operation.MathTransform;
010: import org.w3c.dom.Document;
011: import org.w3c.dom.Element;
012:
013: public class WFSReprojectionTest extends WFSTestSupport {
014: private static final String TARGET_CRS_CODE = "EPSG:900913";
015: MathTransform tx;
016:
017: protected void setUp() throws Exception {
018: super .setUp();
019:
020: CoordinateReferenceSystem epsgTarget = CRS
021: .decode(TARGET_CRS_CODE);
022: CoordinateReferenceSystem epsg32615 = CRS
023: .decode("urn:x-ogc:def:crs:EPSG:6.11.2:32615");
024:
025: tx = CRS.findMathTransform(epsg32615, epsgTarget);
026: }
027:
028: public void testGetFeatureGet() throws Exception {
029:
030: Document dom1 = getAsDOM("wfs?request=getfeature&service=wfs&version=1.0.0&typename="
031: + MockData.POLYGONS.getLocalPart());
032: Document dom2 = getAsDOM("wfs?request=getfeature&service=wfs&version=1.0.0&typename="
033: + MockData.POLYGONS.getLocalPart()
034: + "&srsName="
035: + TARGET_CRS_CODE);
036:
037: runTest(dom1, dom2);
038: }
039:
040: public void testGetFeaturePost() throws Exception {
041: String xml = "<wfs:GetFeature "
042: + "service=\"WFS\" "
043: + "version=\"1.0.0\" "
044: + "xmlns:cdf=\"http://www.opengis.net/cite/data\" "
045: + "xmlns:ogc=\"http://www.opengis.net/ogc\" "
046: + "xmlns:wfs=\"http://www.opengis.net/wfs\" "
047: + "> "
048: + "<wfs:Query typeName=\""
049: + MockData.POLYGONS.getPrefix()
050: + ":"
051: + MockData.POLYGONS.getLocalPart()
052: + "\"> "
053: + "<wfs:PropertyName>cgf:polygonProperty</wfs:PropertyName> "
054: + "</wfs:Query> " + "</wfs:GetFeature>";
055:
056: Document dom1 = postAsDOM("wfs", xml);
057: // print(dom1);
058:
059: xml = "<wfs:GetFeature "
060: + "service=\"WFS\" "
061: + "version=\"1.0.0\" "
062: + "xmlns:cdf=\"http://www.opengis.net/cite/data\" "
063: + "xmlns:ogc=\"http://www.opengis.net/ogc\" "
064: + "xmlns:wfs=\"http://www.opengis.net/wfs\" "
065: + "> "
066: + "<wfs:Query srsName=\""
067: + TARGET_CRS_CODE
068: + "\" typeName=\""
069: + MockData.POLYGONS.getPrefix()
070: + ":"
071: + MockData.POLYGONS.getLocalPart()
072: + "\"> "
073: + "<wfs:PropertyName>cgf:polygonProperty</wfs:PropertyName> "
074: + "</wfs:Query> " + "</wfs:GetFeature>";
075: Document dom2 = postAsDOM("wfs", xml);
076: // print(dom2);
077:
078: runTest(dom1, dom2);
079: }
080:
081: public void testGetFeatureWithProjectedBoxGet() throws Exception {
082: String q = "wfs?request=getfeature&service=wfs&version=1.1&typeName="
083: + MockData.POLYGONS.getLocalPart();
084: Document dom = getAsDOM(q);
085: // print(dom);
086: Element envelope = getFirstElementByTagName(dom, "gml:Envelope");
087: String lc = getFirstElementByTagName(envelope,
088: "gml:lowerCorner").getFirstChild().getNodeValue();
089: String uc = getFirstElementByTagName(envelope,
090: "gml:upperCorner").getFirstChild().getNodeValue();
091: double[] c = new double[] {
092: Double.parseDouble(lc.split(" ")[0]),
093: Double.parseDouble(lc.split(" ")[1]),
094: Double.parseDouble(uc.split(" ")[0]),
095: Double.parseDouble(uc.split(" ")[1]) };
096: double[] cr = new double[4];
097: tx.transform(c, 0, cr, 0, 2);
098:
099: q += "&bbox=" + cr[0] + "," + cr[1] + "," + cr[2] + "," + cr[3]
100: + "," + TARGET_CRS_CODE;
101: dom = getAsDOM(q);
102:
103: assertEquals(1, dom.getElementsByTagName(
104: MockData.POLYGONS.getPrefix() + ":"
105: + MockData.POLYGONS.getLocalPart()).getLength());
106: }
107:
108: public void testGetFeatureWithProjectedBoxPost() throws Exception {
109: String q = "wfs?request=getfeature&service=wfs&version=1.1&typeName="
110: + MockData.POLYGONS.getLocalPart();
111: Document dom = getAsDOM(q);
112: Element envelope = getFirstElementByTagName(dom, "gml:Envelope");
113: String lc = getFirstElementByTagName(envelope,
114: "gml:lowerCorner").getFirstChild().getNodeValue();
115: String uc = getFirstElementByTagName(envelope,
116: "gml:upperCorner").getFirstChild().getNodeValue();
117: double[] c = new double[] {
118: Double.parseDouble(lc.split(" ")[0]),
119: Double.parseDouble(lc.split(" ")[1]),
120: Double.parseDouble(uc.split(" ")[0]),
121: Double.parseDouble(uc.split(" ")[1]) };
122: double[] cr = new double[4];
123: tx.transform(c, 0, cr, 0, 2);
124:
125: String xml = "<wfs:GetFeature service=\"WFS\" version=\"1.1.0\""
126: + " xmlns:"
127: + MockData.POLYGONS.getPrefix()
128: + "=\""
129: + MockData.POLYGONS.getNamespaceURI()
130: + "\""
131: + " xmlns:ogc=\"http://www.opengis.net/ogc\" "
132: + " xmlns:gml=\"http://www.opengis.net/gml\" "
133: + " xmlns:wfs=\"http://www.opengis.net/wfs\" "
134: + "> "
135: + "<wfs:Query typeName=\""
136: + MockData.POLYGONS.getPrefix()
137: + ":"
138: + MockData.POLYGONS.getLocalPart()
139: + "\">"
140: + "<wfs:PropertyName>cgf:polygonProperty</wfs:PropertyName> "
141: + "<ogc:Filter>"
142: + "<ogc:BBOX>"
143: + "<ogc:PropertyName>polygonProperty</ogc:PropertyName>"
144: + "<gml:Envelope srsName=\""
145: + TARGET_CRS_CODE
146: + "\">"
147: + "<gml:lowerCorner>"
148: + cr[0]
149: + " "
150: + cr[1]
151: + "</gml:lowerCorner>"
152: + "<gml:upperCorner>"
153: + cr[2]
154: + " "
155: + cr[3]
156: + "</gml:upperCorner>"
157: + "</gml:Envelope>"
158: + "</ogc:BBOX>"
159: + "</ogc:Filter>"
160: + "</wfs:Query> " + "</wfs:GetFeature>";
161:
162: dom = postAsDOM("wfs", xml);
163:
164: assertEquals(1, dom.getElementsByTagName(
165: MockData.POLYGONS.getPrefix() + ":"
166: + MockData.POLYGONS.getLocalPart()).getLength());
167: }
168:
169: public void testInsertSrsName() throws Exception {
170: String q = "wfs?request=getfeature&service=wfs&version=1.1&typeName="
171: + MockData.POLYGONS.getLocalPart();
172: Document dom = getAsDOM(q);
173: // print(dom);
174: assertEquals(1, dom.getElementsByTagName(
175: MockData.POLYGONS.getPrefix() + ":"
176: + MockData.POLYGONS.getLocalPart()).getLength());
177:
178: Element polygonProperty = getFirstElementByTagName(dom,
179: "cgf:polygonProperty");
180: Element posList = getFirstElementByTagName(polygonProperty,
181: "gml:posList");
182:
183: double[] c = posList(posList.getFirstChild().getNodeValue());
184: double[] cr = new double[c.length];
185: tx.transform(c, 0, cr, 0, cr.length / 2);
186:
187: String xml = "<wfs:Transaction service=\"WFS\" version=\"1.1.0\" "
188: + " xmlns:wfs=\"http://www.opengis.net/wfs\" "
189: + " xmlns:gml=\"http://www.opengis.net/gml\" "
190: + " xmlns:cgf=\""
191: + MockData.CGF_URI
192: + "\">"
193: + "<wfs:Insert handle=\"insert-1\" srsName=\""
194: + TARGET_CRS_CODE
195: + "\">"
196: + " <cgf:Polygons>"
197: + "<cgf:polygonProperty>"
198: + "<gml:Polygon >"
199: + "<gml:exterior>"
200: + "<gml:LinearRing>"
201: + "<gml:posList>";
202: for (int i = 0; i < cr.length; i++) {
203: xml += cr[i];
204: if (i < cr.length - 1) {
205: xml += " ";
206: }
207: }
208: xml += "</gml:posList>" + "</gml:LinearRing>"
209: + "</gml:exterior>" + "</gml:Polygon>"
210: + "</cgf:polygonProperty>" + " </cgf:Polygons>"
211: + "</wfs:Insert>" + "</wfs:Transaction>";
212: postAsDOM("wfs", xml);
213:
214: dom = getAsDOM(q);
215: // print(dom);
216: assertEquals(2, dom.getElementsByTagName(
217: MockData.POLYGONS.getPrefix() + ":"
218: + MockData.POLYGONS.getLocalPart()).getLength());
219:
220: }
221:
222: public void testInsertGeomSrsName() throws Exception {
223: String q = "wfs?request=getfeature&service=wfs&version=1.1&typeName="
224: + MockData.POLYGONS.getLocalPart();
225: Document dom = getAsDOM(q);
226:
227: Element polygonProperty = getFirstElementByTagName(dom,
228: "cgf:polygonProperty");
229: Element posList = getFirstElementByTagName(polygonProperty,
230: "gml:posList");
231:
232: double[] c = posList(posList.getFirstChild().getNodeValue());
233: double[] cr = new double[c.length];
234: tx.transform(c, 0, cr, 0, cr.length / 2);
235:
236: String xml = "<wfs:Transaction service=\"WFS\" version=\"1.1.0\" "
237: + " xmlns:wfs=\"http://www.opengis.net/wfs\" "
238: + " xmlns:gml=\"http://www.opengis.net/gml\" "
239: + " xmlns:cgf=\""
240: + MockData.CGF_URI
241: + "\">"
242: + "<wfs:Insert handle=\"insert-1\">"
243: + " <cgf:Polygons>"
244: + "<cgf:polygonProperty>"
245: + "<gml:Polygon srsName=\""
246: + TARGET_CRS_CODE
247: + "\">"
248: + "<gml:exterior>"
249: + "<gml:LinearRing>"
250: + "<gml:posList>";
251: for (int i = 0; i < cr.length; i++) {
252: xml += cr[i];
253: if (i < cr.length - 1) {
254: xml += " ";
255: }
256: }
257: xml += "</gml:posList>" + "</gml:LinearRing>"
258: + "</gml:exterior>" + "</gml:Polygon>"
259: + "</cgf:polygonProperty>" + " </cgf:Polygons>"
260: + "</wfs:Insert>" + "</wfs:Transaction>";
261: postAsDOM("wfs", xml);
262:
263: dom = getAsDOM(q);
264:
265: assertEquals(2, dom.getElementsByTagName(
266: MockData.POLYGONS.getPrefix() + ":"
267: + MockData.POLYGONS.getLocalPart()).getLength());
268:
269: }
270:
271: public void testUpdate() throws Exception {
272: String q = "wfs?request=getfeature&service=wfs&version=1.1&typeName="
273: + MockData.POLYGONS.getLocalPart();
274:
275: Document dom = getAsDOM(q);
276: // print(dom);
277:
278: Element polygonProperty = getFirstElementByTagName(dom,
279: "cgf:polygonProperty");
280: Element posList = getFirstElementByTagName(polygonProperty,
281: "gml:posList");
282:
283: double[] c = posList(posList.getFirstChild().getNodeValue());
284: double[] cr = new double[c.length];
285: tx.transform(c, 0, cr, 0, cr.length / 2);
286:
287: // perform an update
288: String xml = "<wfs:Transaction service=\"WFS\" version=\"1.1.0\" "
289: + "xmlns:cgf=\"http://www.opengis.net/cite/geometry\" "
290: + "xmlns:ogc=\"http://www.opengis.net/ogc\" "
291: + "xmlns:wfs=\"http://www.opengis.net/wfs\" "
292: + "xmlns:gml=\"http://www.opengis.net/gml\"> "
293: + "<wfs:Update typeName=\"cgf:Polygons\" > "
294: + "<wfs:Property>"
295: + "<wfs:Name>polygonProperty</wfs:Name>"
296: + "<wfs:Value>"
297: + "<gml:Polygon srsName=\""
298: + TARGET_CRS_CODE
299: + "\">"
300: + "<gml:exterior>"
301: + "<gml:LinearRing>" + "<gml:posList>";
302: for (int i = 0; i < cr.length; i++) {
303: xml += cr[i];
304: if (i < cr.length - 1) {
305: xml += " ";
306: }
307: }
308: xml += "</gml:posList>" + "</gml:LinearRing>"
309: + "</gml:exterior>" + "</gml:Polygon>" + "</wfs:Value>"
310: + "</wfs:Property>" + "<ogc:Filter>"
311: + "<ogc:PropertyIsEqualTo>"
312: + "<ogc:PropertyName>id</ogc:PropertyName>"
313: + "<ogc:Literal>t0002</ogc:Literal>"
314: + "</ogc:PropertyIsEqualTo>" + "</ogc:Filter>"
315: + "</wfs:Update>" + "</wfs:Transaction>";
316:
317: dom = postAsDOM("wfs", xml);
318: assertEquals("wfs:TransactionResponse", dom
319: .getDocumentElement().getNodeName());
320: Element totalUpdated = getFirstElementByTagName(dom,
321: "wfs:totalUpdated");
322: assertEquals("1", totalUpdated.getFirstChild().getNodeValue());
323:
324: dom = getAsDOM(q);
325: polygonProperty = getFirstElementByTagName(dom,
326: "cgf:polygonProperty");
327: posList = getFirstElementByTagName(polygonProperty,
328: "gml:posList");
329: double[] c1 = posList(posList.getFirstChild().getNodeValue());
330:
331: assertEquals(c.length, c1.length);
332: for (int i = 0; i < c.length; i++) {
333: int x = (int) (c[i] + 0.5);
334: int y = (int) (c1[i] + 0.5);
335:
336: assertEquals(x, y);
337: }
338:
339: }
340:
341: public void testUpdateReprojectFilter() throws Exception {
342: testUpdateReprojectFilter("srsName=\"urn:x-ogc:def:crs:EPSG:6.11.2:4326\"");
343: }
344:
345: public void testUpdateReprojectFilterDefaultCRS() throws Exception {
346: testUpdateReprojectFilter("");
347: }
348:
349: private void testUpdateReprojectFilter(String envelopeSRS)
350: throws Exception {
351: // slightly adapted from CITE WFS 1.1, "Test wfs:wfs-1.1.0-LockFeature-tc3.1"
352:
353: // perform an update
354: String xml = "<wfs:Transaction service=\"WFS\" version=\"1.1.0\" "
355: + "xmlns:cgf=\"http://www.opengis.net/cite/geometry\" "
356: + "xmlns:ogc=\"http://www.opengis.net/ogc\" "
357: + "xmlns:wfs=\"http://www.opengis.net/wfs\" "
358: + "xmlns:gml=\"http://www.opengis.net/gml\"> "
359: + "<wfs:Update handle=\"upd-1\" typeName=\"sf:GenericEntity\">"
360: + "<wfs:Property>"
361: + " <wfs:Name>sf:boolProperty</wfs:Name>"
362: + " <wfs:Value>true</wfs:Value>"
363: + "</wfs:Property>"
364: + " <ogc:Filter>"
365: + " <ogc:BBOX>"
366: + " <ogc:PropertyName>sf:attribut.geom</ogc:PropertyName>"
367: + " <gml:Envelope "
368: + envelopeSRS
369: + ">"
370: + " <gml:lowerCorner>34.5 -10.0</gml:lowerCorner>"
371: + " <gml:upperCorner>72.0 32.0</gml:upperCorner>"
372: + " </gml:Envelope>"
373: + " </ogc:BBOX>"
374: + " </ogc:Filter>"
375: + "</wfs:Update> </wfs:Transaction>";
376:
377: Document dom = postAsDOM("wfs", xml);
378: assertEquals("wfs:TransactionResponse", dom
379: .getDocumentElement().getNodeName());
380: Element totalUpdated = getFirstElementByTagName(dom,
381: "wfs:totalUpdated");
382: assertEquals("3", totalUpdated.getFirstChild().getNodeValue());
383: }
384:
385: public void testDeleteReprojectFilter() throws Exception {
386: testDeleteReprojectFilter("srsName=\"urn:x-ogc:def:crs:EPSG:6.11.2:4326\"");
387: }
388:
389: public void testDeleteReprojectFilterDefaultCRS() throws Exception {
390: testDeleteReprojectFilter("");
391: }
392:
393: private void testDeleteReprojectFilter(String envelopeSRS)
394: throws Exception {
395: // slightly adapted from CITE WFS 1.1, "Test wfs:wfs-1.1.0-LockFeature-tc3.1"
396:
397: // perform an update
398: String xml = "<wfs:Transaction service=\"WFS\" version=\"1.1.0\" "
399: + "xmlns:cgf=\"http://www.opengis.net/cite/geometry\" "
400: + "xmlns:ogc=\"http://www.opengis.net/ogc\" "
401: + "xmlns:wfs=\"http://www.opengis.net/wfs\" "
402: + "xmlns:gml=\"http://www.opengis.net/gml\"> "
403: + "<wfs:Delete typeName=\"sf:GenericEntity\">"
404: + " <ogc:Filter>"
405: + " <ogc:BBOX>"
406: + " <ogc:PropertyName>sf:attribut.geom</ogc:PropertyName>"
407: + " <gml:Envelope "
408: + envelopeSRS
409: + ">"
410: + " <gml:lowerCorner>34.5 -10.0</gml:lowerCorner>"
411: + " <gml:upperCorner>72.0 32.0</gml:upperCorner>"
412: + " </gml:Envelope>"
413: + " </ogc:BBOX>"
414: + " </ogc:Filter>"
415: + "</wfs:Delete> </wfs:Transaction>";
416:
417: Document dom = postAsDOM("wfs", xml);
418: assertEquals("wfs:TransactionResponse", dom
419: .getDocumentElement().getNodeName());
420: Element totalUpdated = getFirstElementByTagName(dom,
421: "wfs:totalDeleted");
422: assertEquals("3", totalUpdated.getFirstChild().getNodeValue());
423: }
424:
425: public void testLockReprojectFilter() throws Exception {
426: testLockReprojectFilter("srsName=\"urn:x-ogc:def:crs:EPSG:6.11.2:4326\"");
427: }
428:
429: public void testLockReprojectFilterDefaultCRS() throws Exception {
430: testLockReprojectFilter("");
431: }
432:
433: private void testLockReprojectFilter(String envelopeSRS)
434: throws Exception {
435: // slightly adapted from CITE WFS 1.1, "Test wfs:wfs-1.1.0-LockFeature-tc3.1"
436:
437: // perform a lock
438: String xml = "<wfs:LockFeature xmlns:wfs=\"http://www.opengis.net/wfs\" "
439: + "xmlns:sf=\"http://cite.opengeospatial.org/gmlsf\" "
440: + "xmlns:myparsers=\"http://teamengine.sourceforge.net/parsers\" "
441: + "xmlns:ogc=\"http://www.opengis.net/ogc\" "
442: + "xmlns:gml=\"http://www.opengis.net/gml\" "
443: + "xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
444: + "expiry=\"5\" "
445: + "handle=\"LockFeature-tc3\" "
446: + "lockAction=\"ALL\" "
447: + "service=\"WFS\" "
448: + "version=\"1.1.0\"> "
449: + "<wfs:Lock handle=\"lock-1\" typeName=\"sf:GenericEntity\"> "
450: + "<ogc:Filter>"
451: + "<ogc:BBOX>"
452: + " <ogc:PropertyName>sf:attribut.geom</ogc:PropertyName>"
453: + " <gml:Envelope "
454: + envelopeSRS
455: + ">"
456: + " <gml:lowerCorner>34.5 -10.0</gml:lowerCorner>"
457: + " <gml:upperCorner>72.0 32.0</gml:upperCorner>"
458: + " </gml:Envelope>"
459: + "</ogc:BBOX>"
460: + "</ogc:Filter>"
461: + "</wfs:Lock>" + "</wfs:LockFeature>";
462: // System.out.println(xml);
463:
464: Document dom = postAsDOM("wfs", xml);
465: assertEquals("wfs:LockFeatureResponse", dom
466: .getDocumentElement().getNodeName());
467: assertEquals(3, dom.getElementsByTagName("ogc:FeatureId")
468: .getLength());
469: }
470:
471: public void runTest(Document dom1, Document dom2) throws Exception {
472: Element box = getFirstElementByTagName(dom1
473: .getDocumentElement(), "gml:Box");
474: Element coordinates = getFirstElementByTagName(box,
475: "gml:coordinates");
476: double[] d1 = coordinates(coordinates.getFirstChild()
477: .getNodeValue());
478:
479: box = getFirstElementByTagName(dom2.getDocumentElement(),
480: "gml:Box");
481: coordinates = getFirstElementByTagName(box, "gml:coordinates");
482: double[] d2 = coordinates(coordinates.getFirstChild()
483: .getNodeValue());
484:
485: double[] d3 = new double[d1.length];
486: tx.transform(d1, 0, d3, 0, d1.length / 2);
487:
488: for (int i = 0; i < d2.length; i++) {
489: assertEquals(d2[i], d3[i], 0.001);
490: }
491: }
492:
493: double[] coordinates(String string) {
494: StringTokenizer st = new StringTokenizer(string, " ");
495: double[] coordinates = new double[st.countTokens() * 2];
496: int i = 0;
497: while (st.hasMoreTokens()) {
498: String tuple = st.nextToken();
499: coordinates[i++] = Double.parseDouble(tuple.split(",")[0]);
500: coordinates[i++] = Double.parseDouble(tuple.split(",")[1]);
501: }
502:
503: return coordinates;
504: }
505:
506: double[] posList(String string) {
507: StringTokenizer st = new StringTokenizer(string, " ");
508: double[] coordinates = new double[st.countTokens()];
509: int i = 0;
510: while (st.hasMoreTokens()) {
511: coordinates[i++] = Double.parseDouble(st.nextToken());
512: }
513:
514: return coordinates;
515: }
516:
517: }
|