diff --git a/lib/OpenLayers/Format/Filter/v1_0_0.js b/lib/OpenLayers/Format/Filter/v1_0_0.js index 5e1811338d..02e9aeaad6 100644 --- a/lib/OpenLayers/Format/Filter/v1_0_0.js +++ b/lib/OpenLayers/Format/Filter/v1_0_0.js @@ -124,7 +124,17 @@ OpenLayers.Format.Filter.v1_0_0 = OpenLayers.Class( }, "BBOX": function(filter) { var node = this.createElementNSPlus("ogc:BBOX"); - this.writeNode("PropertyName", filter, node); + // PropertyName is mandatory in 1.0.0, but e.g. GeoServer also + // accepts filters without it. When this is used with + // OpenLayers.Protocol.WFS, OpenLayers.Format.WFST will set a + // missing filter.property to the geometryName that is + // configured with the protocol, which defaults to "the_geom". + // So the only way to omit this mandatory property is to not + // set the property on the filter and to set the geometryName + // on the WFS protocol to null. The latter also happens when + // the protocol is configured without a geometryName and a + // featureNS. + filter.property && this.writeNode("PropertyName", filter, node); var box = this.writeNode("gml:Box", filter.value, node); if(filter.projection) { box.setAttribute("srsName", filter.projection); diff --git a/lib/OpenLayers/Format/Filter/v1_1_0.js b/lib/OpenLayers/Format/Filter/v1_1_0.js index 0bec38d4a9..9c50b4395a 100644 --- a/lib/OpenLayers/Format/Filter/v1_1_0.js +++ b/lib/OpenLayers/Format/Filter/v1_1_0.js @@ -139,7 +139,8 @@ OpenLayers.Format.Filter.v1_1_0 = OpenLayers.Class( }, "BBOX": function(filter) { var node = this.createElementNSPlus("ogc:BBOX"); - this.writeNode("PropertyName", filter, node); + // PropertyName is optional in 1.1.0 + filter.property && this.writeNode("PropertyName", filter, node); var box = this.writeNode("gml:Envelope", filter.value); if(filter.projection) { box.setAttribute("srsName", filter.projection); diff --git a/lib/OpenLayers/Format/GML/Base.js b/lib/OpenLayers/Format/GML/Base.js index b05b3fd2ee..3ec078f8a8 100644 --- a/lib/OpenLayers/Format/GML/Base.js +++ b/lib/OpenLayers/Format/GML/Base.js @@ -62,7 +62,8 @@ OpenLayers.Format.GML.Base = OpenLayers.Class(OpenLayers.Format.XML, { /** * APIProperty: geometry - * {String} Name of geometry element. Defaults to "geometry". + * {String} Name of geometry element. Defaults to "geometry". If null, it + * will be set on when the first geometry is parsed. */ geometryName: "geometry", @@ -440,6 +441,9 @@ OpenLayers.Format.GML.Base = OpenLayers.Class(OpenLayers.Format.XML, { obj.features.push(feature); }, "_geometry": function(node, obj) { + if (!this.geometryName) { + this.geometryName = node.nodeName.split(":").pop(); + } this.readChildNodes(node, obj); }, "_attribute": function(node, obj) { diff --git a/lib/OpenLayers/Format/WFST/v1_0_0.js b/lib/OpenLayers/Format/WFST/v1_0_0.js index d82810a36c..a89d930f59 100644 --- a/lib/OpenLayers/Format/WFST/v1_0_0.js +++ b/lib/OpenLayers/Format/WFST/v1_0_0.js @@ -136,9 +136,10 @@ OpenLayers.Format.WFST.v1_0_0 = OpenLayers.Class( srsName: this.srsName, srsNameInQuery: this.srsNameInQuery }, options); + var prefix = options.featurePrefix; var node = this.createElementNSPlus("wfs:Query", { attributes: { - typeName: (options.featureNS ? options.featurePrefix + ":" : "") + + typeName: (prefix ? prefix + ":" : "") + options.featureType } }); @@ -146,7 +147,7 @@ OpenLayers.Format.WFST.v1_0_0 = OpenLayers.Class( node.setAttribute("srsName", options.srsName); } if(options.featureNS) { - node.setAttribute("xmlns:" + options.featurePrefix, options.featureNS); + node.setAttribute("xmlns:" + prefix, options.featureNS); } if(options.propertyNames) { for(var i=0,len = options.propertyNames.length; i. Otherwise, the default is 'the_geom'. */ initialize: function(options) { OpenLayers.Protocol.prototype.initialize.apply(this, [options]); + if (!options.geometryName && !options.featureNS) { + // poorly configured protocol - try to not fail on BBOX filters + this.geometryName = null; + } if(!options.format) { this.format = OpenLayers.Format.WFST(OpenLayers.Util.extend({ version: this.version, @@ -281,8 +288,18 @@ OpenLayers.Protocol.WFS.v1 = OpenLayers.Class(OpenLayers.Protocol, { if(!doc || doc.length <= 0) { return null; } - return (this.readFormat !== null) ? this.readFormat.read(doc) : + var result = (this.readFormat !== null) ? this.readFormat.read(doc) : this.format.read(doc, options); + if (!this.featureNS) { + var format = this.readFormat || this.format; + this.featureNS = format.featureNS; + // no need to auto-configure again on subsequent reads + format.autoConfig = false; + if (!this.geometryName) { + this.setGeometryName(format.geometryName); + } + } + return result; }, /** diff --git a/tests/Format/Filter/v1_0_0.html b/tests/Format/Filter/v1_0_0.html index 493008be97..876723f23f 100644 --- a/tests/Format/Filter/v1_0_0.html +++ b/tests/Format/Filter/v1_0_0.html @@ -78,6 +78,31 @@ t.xml_eq(node, out, "bbox correctly written"); } + function test_BBOX_noGeometryName(t) { + t.plan(1); + // WFS 1.0.0 does not allow BBOX filters without property, but + // GeoServer accepts them. + var filter = new OpenLayers.Filter.Spatial({ + type: OpenLayers.Filter.Spatial.BBOX, + value: new OpenLayers.Bounds(-180, -90, 180, 90), + projection: "EPSG:4326" + }); + + var out = + '' + + '' + + '' + + '-180,-90 180,90' + + '' + + '' + + ''; + + var parser = new OpenLayers.Format.Filter.v1_0_0(); + var node = parser.write(filter); + + t.xml_eq(node, out, "bbox correctly written"); + } + function test_DWithin(t) { t.plan(6); diff --git a/tests/Format/Filter/v1_1_0.html b/tests/Format/Filter/v1_1_0.html index 8e73e01b30..68d1ec114d 100644 --- a/tests/Format/Filter/v1_1_0.html +++ b/tests/Format/Filter/v1_1_0.html @@ -167,6 +167,31 @@ t.xml_eq(node, out, "bbox correctly written"); } + function test_BBOX_noGeometryName(t) { + t.plan(1); + var filter = new OpenLayers.Filter.Spatial({ + type: OpenLayers.Filter.Spatial.BBOX, + value: new OpenLayers.Bounds(-180, -90, 180, 90), + projection: "EPSG:4326" + }); + + var out = + '' + + '' + + '' + + '-180 -90' + + '180 90' + + '' + + '' + + ''; + + var parser = new OpenLayers.Format.Filter.v1_1_0(); + var node = parser.write(filter); + + t.xml_eq(node, out, "bbox correctly written"); + } + + function test_Intersects(t) { t.plan(4); diff --git a/tests/Format/GML/v3.html b/tests/Format/GML/v3.html index 49b4905106..9e6c5b8482 100644 --- a/tests/Format/GML/v3.html +++ b/tests/Format/GML/v3.html @@ -50,6 +50,19 @@ } + function test_read_setGeometryName(t) { + t.plan(1); + var doc = readXML("v3/topp-states-gml.xml"); + var format = new OpenLayers.Format.GML.v3({ + featureType: "states", + featureNS: "http://www.openplans.org/topp", + geometryName: null + }); + var features = format.read(doc.documentElement); + + t.eq(format.geometryName, "the_geom", "geometryName set when parsing features"); + } + function test_readNode_bounds(t) { var files = ["v3/envelope.xml"]; diff --git a/tests/Format/WFST/v1_0_0.html b/tests/Format/WFST/v1_0_0.html index bd67071ceb..89d810e85e 100644 --- a/tests/Format/WFST/v1_0_0.html +++ b/tests/Format/WFST/v1_0_0.html @@ -67,6 +67,17 @@ } } + + function test_write_poorconfig(t) { + t.plan(1); + var format = new OpenLayers.Format.WFST.v1_0_0({ + featureType: "states", + featurePrefix: "topp" + }); + var exp = "topp:states"; + var got = format.writeNode("wfs:Query").getAttribute("typeName"); + t.eq(got, exp, "Query without featureNS but with featurePrefix queries for the correct featureType"); + } var xmlFormat = new OpenLayers.Format.XML(); function readXML(id) { diff --git a/tests/Format/WFST/v1_1_0.html b/tests/Format/WFST/v1_1_0.html index d6fdd50ed8..6fd024a669 100644 --- a/tests/Format/WFST/v1_1_0.html +++ b/tests/Format/WFST/v1_1_0.html @@ -95,6 +95,17 @@ } } + function test_write_poorconfig(t) { + t.plan(1); + var format = new OpenLayers.Format.WFST.v1_1_0({ + featureType: "states", + featurePrefix: "topp" + }); + var exp = "topp:states"; + var got = format.writeNode("wfs:Query").getAttribute("typeName"); + t.eq(got, exp, "Query without featureNS but with featurePrefix queries for the correct featureType"); + } + var xmlFormat = new OpenLayers.Format.XML(); function readXML(id) { var xml = document.getElementById(id).firstChild.nodeValue; diff --git a/tests/Protocol/WFS.html b/tests/Protocol/WFS.html index ec4afcf02a..b142b1d34d 100644 --- a/tests/Protocol/WFS.html +++ b/tests/Protocol/WFS.html @@ -104,6 +104,20 @@ OpenLayers.Request.POST = _POST; } + + function test_parseResponse_poorconfig(t) { + t.plan(2); + + var protocol = new OpenLayers.Protocol.WFS({ + url: "http://some.url.org", + featurePrefix: "topp", + featureType: "tasmania_roads" + }); + + protocol.parseResponse({responseText: document.getElementById("query_response").firstChild.nodeValue}); + t.eq(protocol.geometryName, "geom", "geometryName configured correctly"); + t.eq(protocol.featureNS, "http://www.openplans.org/topp", "featureNS configured correctly"); + } function test_exception(t) { t.plan(8); @@ -439,7 +453,6 @@ - -5,-5 5,5 @@ -448,5 +461,9 @@ --> +