[76] | 1 | /* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for |
---|
| 2 | * full list of contributors). Published under the Clear BSD license. |
---|
| 3 | * See http://svn.openlayers.org/trunk/openlayers/license.txt for the |
---|
| 4 | * full text of the license. */ |
---|
| 5 | |
---|
| 6 | /** |
---|
| 7 | * @requires OpenLayers/Protocol/WFS.js |
---|
| 8 | */ |
---|
| 9 | |
---|
| 10 | /** |
---|
| 11 | * Class: OpenLayers.Protocol.WFS.v1 |
---|
| 12 | * Abstract class for for v1.0.0 and v1.1.0 protocol. |
---|
| 13 | * |
---|
| 14 | * Inherits from: |
---|
| 15 | * - <OpenLayers.Protocol> |
---|
| 16 | */ |
---|
| 17 | OpenLayers.Protocol.WFS.v1 = OpenLayers.Class(OpenLayers.Protocol, { |
---|
| 18 | |
---|
| 19 | /** |
---|
| 20 | * Property: version |
---|
| 21 | * {String} WFS version number. |
---|
| 22 | */ |
---|
| 23 | version: null, |
---|
| 24 | |
---|
| 25 | /** |
---|
| 26 | * Property: srsName |
---|
| 27 | * {String} Name of spatial reference system. Default is "EPSG:4326". |
---|
| 28 | */ |
---|
| 29 | srsName: "EPSG:4326", |
---|
| 30 | |
---|
| 31 | /** |
---|
| 32 | * Property: featureType |
---|
| 33 | * {String} Local feature typeName. |
---|
| 34 | */ |
---|
| 35 | featureType: null, |
---|
| 36 | |
---|
| 37 | /** |
---|
| 38 | * Property: featureNS |
---|
| 39 | * {String} Feature namespace. |
---|
| 40 | */ |
---|
| 41 | featureNS: null, |
---|
| 42 | |
---|
| 43 | /** |
---|
| 44 | * Property: geometryName |
---|
| 45 | * {String} Name of the geometry attribute for features. Default is |
---|
| 46 | * "the_geom". |
---|
| 47 | */ |
---|
| 48 | geometryName: "the_geom", |
---|
| 49 | |
---|
| 50 | /** |
---|
| 51 | * Property: schema |
---|
| 52 | * {String} Optional schema location that will be included in the |
---|
| 53 | * schemaLocation attribute value. Note that the feature type schema |
---|
| 54 | * is required for a strict XML validator (on transactions with an |
---|
| 55 | * insert for example), but is *not* required by the WFS specification |
---|
| 56 | * (since the server is supposed to know about feature type schemas). |
---|
| 57 | */ |
---|
| 58 | schema: null, |
---|
| 59 | |
---|
| 60 | /** |
---|
| 61 | * Property: featurePrefix |
---|
| 62 | * {String} Namespace alias for feature type. Default is "feature". |
---|
| 63 | */ |
---|
| 64 | featurePrefix: "feature", |
---|
| 65 | |
---|
| 66 | /** |
---|
| 67 | * Property: formatOptions |
---|
| 68 | * {Object} Optional options for the format. If a format is not provided, |
---|
| 69 | * this property can be used to extend the default format options. |
---|
| 70 | */ |
---|
| 71 | formatOptions: null, |
---|
| 72 | |
---|
| 73 | /** |
---|
| 74 | * Property: readFormat |
---|
| 75 | * {<OpenLayers.Format>} For WFS requests it is possible to get a |
---|
| 76 | * different output format than GML. In that case, we cannot parse |
---|
| 77 | * the response with the default format (WFST) and we need a different |
---|
| 78 | * format for reading. |
---|
| 79 | */ |
---|
| 80 | readFormat: null, |
---|
| 81 | |
---|
| 82 | /** |
---|
| 83 | * Constructor: OpenLayers.Protocol.WFS |
---|
| 84 | * A class for giving layers WFS protocol. |
---|
| 85 | * |
---|
| 86 | * Parameters: |
---|
| 87 | * options - {Object} Optional object whose properties will be set on the |
---|
| 88 | * instance. |
---|
| 89 | * |
---|
| 90 | * Valid options properties: |
---|
| 91 | * url - {String} URL to send requests to (required). |
---|
| 92 | * featureType - {String} Local (without prefix) feature typeName (required). |
---|
| 93 | * featureNS - {String} Feature namespace (required, but can be autodetected |
---|
| 94 | * for reading if featurePrefix is provided and identical to the prefix |
---|
| 95 | * in the server response). |
---|
| 96 | * featurePrefix - {String} Feature namespace alias (optional - only used |
---|
| 97 | * for writing if featureNS is provided). Default is 'feature'. |
---|
| 98 | * geometryName - {String} Name of geometry attribute. Default is 'the_geom'. |
---|
| 99 | */ |
---|
| 100 | initialize: function(options) { |
---|
| 101 | OpenLayers.Protocol.prototype.initialize.apply(this, [options]); |
---|
| 102 | if(!options.format) { |
---|
| 103 | this.format = OpenLayers.Format.WFST(OpenLayers.Util.extend({ |
---|
| 104 | version: this.version, |
---|
| 105 | featureType: this.featureType, |
---|
| 106 | featureNS: this.featureNS, |
---|
| 107 | featurePrefix: this.featurePrefix, |
---|
| 108 | geometryName: this.geometryName, |
---|
| 109 | srsName: this.srsName, |
---|
| 110 | schema: this.schema |
---|
| 111 | }, this.formatOptions)); |
---|
| 112 | } |
---|
| 113 | if(!this.featureNS && this.featurePrefix) { |
---|
| 114 | // featureNS autodetection |
---|
| 115 | var readNode = this.format.readNode; |
---|
| 116 | this.format.readNode = function(node, obj) { |
---|
| 117 | if(!this.featureNS && node.prefix == this.featurePrefix) { |
---|
| 118 | this.featureNS = node.namespaceURI; |
---|
| 119 | this.setNamespace("feature", this.featureNS); |
---|
| 120 | } |
---|
| 121 | return readNode.apply(this, arguments); |
---|
| 122 | }; |
---|
| 123 | } |
---|
| 124 | }, |
---|
| 125 | |
---|
| 126 | /** |
---|
| 127 | * APIMethod: destroy |
---|
| 128 | * Clean up the protocol. |
---|
| 129 | */ |
---|
| 130 | destroy: function() { |
---|
| 131 | if(this.options && !this.options.format) { |
---|
| 132 | this.format.destroy(); |
---|
| 133 | } |
---|
| 134 | this.format = null; |
---|
| 135 | OpenLayers.Protocol.prototype.destroy.apply(this); |
---|
| 136 | }, |
---|
| 137 | |
---|
| 138 | /** |
---|
| 139 | * Method: read |
---|
| 140 | * Construct a request for reading new features. Since WFS splits the |
---|
| 141 | * basic CRUD operations into GetFeature requests (for read) and |
---|
| 142 | * Transactions (for all others), this method does not make use of the |
---|
| 143 | * format's read method (that is only about reading transaction |
---|
| 144 | * responses). |
---|
| 145 | */ |
---|
| 146 | read: function(options) { |
---|
| 147 | OpenLayers.Protocol.prototype.read.apply(this, arguments); |
---|
| 148 | options = OpenLayers.Util.extend({}, options); |
---|
| 149 | OpenLayers.Util.applyDefaults(options, this.options || {}); |
---|
| 150 | var response = new OpenLayers.Protocol.Response({requestType: "read"}); |
---|
| 151 | |
---|
| 152 | var data = OpenLayers.Format.XML.prototype.write.apply( |
---|
| 153 | this.format, [this.format.writeNode("wfs:GetFeature", options)] |
---|
| 154 | ); |
---|
| 155 | |
---|
| 156 | response.priv = OpenLayers.Request.POST({ |
---|
| 157 | url: options.url, |
---|
| 158 | callback: this.createCallback(this.handleRead, response, options), |
---|
| 159 | params: options.params, |
---|
| 160 | headers: options.headers, |
---|
| 161 | data: data |
---|
| 162 | }); |
---|
| 163 | |
---|
| 164 | return response; |
---|
| 165 | }, |
---|
| 166 | |
---|
| 167 | /** |
---|
| 168 | * Method: handleRead |
---|
| 169 | * Deal with response from the read request. |
---|
| 170 | * |
---|
| 171 | * Parameters: |
---|
| 172 | * response - {<OpenLayers.Protocol.Response>} The response object to pass |
---|
| 173 | * to the user callback. |
---|
| 174 | * options - {Object} The user options passed to the read call. |
---|
| 175 | */ |
---|
| 176 | handleRead: function(response, options) { |
---|
| 177 | if(options.callback) { |
---|
| 178 | var request = response.priv; |
---|
| 179 | if(request.status >= 200 && request.status < 300) { |
---|
| 180 | // success |
---|
| 181 | response.features = this.parseFeatures(request); |
---|
| 182 | response.code = OpenLayers.Protocol.Response.SUCCESS; |
---|
| 183 | } else { |
---|
| 184 | // failure |
---|
| 185 | response.code = OpenLayers.Protocol.Response.FAILURE; |
---|
| 186 | } |
---|
| 187 | options.callback.call(options.scope, response); |
---|
| 188 | } |
---|
| 189 | }, |
---|
| 190 | |
---|
| 191 | /** |
---|
| 192 | * Method: parseFeatures |
---|
| 193 | * Read HTTP response body and return features |
---|
| 194 | * |
---|
| 195 | * Parameters: |
---|
| 196 | * request - {XMLHttpRequest} The request object |
---|
| 197 | * |
---|
| 198 | * Returns: |
---|
| 199 | * {Array({<OpenLayers.Feature.Vector>})} or |
---|
| 200 | * {<OpenLayers.Feature.Vector>} Array of features or a single feature. |
---|
| 201 | */ |
---|
| 202 | parseFeatures: function(request) { |
---|
| 203 | var doc = request.responseXML; |
---|
| 204 | if(!doc || !doc.documentElement) { |
---|
| 205 | doc = request.responseText; |
---|
| 206 | } |
---|
| 207 | if(!doc || doc.length <= 0) { |
---|
| 208 | return null; |
---|
| 209 | } |
---|
| 210 | return (this.readFormat !== null) ? this.readFormat.read(doc) : |
---|
| 211 | this.format.read(doc); |
---|
| 212 | }, |
---|
| 213 | |
---|
| 214 | /** |
---|
| 215 | * Method: commit |
---|
| 216 | * Given a list of feature, assemble a batch request for update, create, |
---|
| 217 | * and delete transactions. A commit call on the prototype amounts |
---|
| 218 | * to writing a WFS transaction - so the write method on the format |
---|
| 219 | * is used. |
---|
| 220 | * |
---|
| 221 | * Parameters: |
---|
| 222 | * features - {Array(<OpenLayers.Feature.Vector>} |
---|
| 223 | * |
---|
| 224 | * Returns: |
---|
| 225 | * {<OpenLayers.Protocol.Response>} A response object with a features |
---|
| 226 | * property containing any insertIds and a priv property referencing |
---|
| 227 | * the XMLHttpRequest object. |
---|
| 228 | */ |
---|
| 229 | commit: function(features, options) { |
---|
| 230 | |
---|
| 231 | options = OpenLayers.Util.extend({}, options); |
---|
| 232 | OpenLayers.Util.applyDefaults(options, this.options); |
---|
| 233 | |
---|
| 234 | var response = new OpenLayers.Protocol.Response({ |
---|
| 235 | requestType: "commit", |
---|
| 236 | reqFeatures: features |
---|
| 237 | }); |
---|
| 238 | response.priv = OpenLayers.Request.POST({ |
---|
| 239 | url: options.url, |
---|
| 240 | data: this.format.write(features, options), |
---|
| 241 | callback: this.createCallback(this.handleCommit, response, options) |
---|
| 242 | }); |
---|
| 243 | |
---|
| 244 | return response; |
---|
| 245 | }, |
---|
| 246 | |
---|
| 247 | /** |
---|
| 248 | * Method: handleCommit |
---|
| 249 | * Called when the commit request returns. |
---|
| 250 | * |
---|
| 251 | * Parameters: |
---|
| 252 | * response - {<OpenLayers.Protocol.Response>} The response object to pass |
---|
| 253 | * to the user callback. |
---|
| 254 | * options - {Object} The user options passed to the commit call. |
---|
| 255 | */ |
---|
| 256 | handleCommit: function(response, options) { |
---|
| 257 | if(options.callback) { |
---|
| 258 | var request = response.priv; |
---|
| 259 | |
---|
| 260 | // ensure that we have an xml doc |
---|
| 261 | var data = request.responseXML; |
---|
| 262 | if(!data || !data.documentElement) { |
---|
| 263 | data = request.responseText; |
---|
| 264 | } |
---|
| 265 | |
---|
| 266 | var obj = this.format.read(data) || {}; |
---|
| 267 | |
---|
| 268 | response.insertIds = obj.insertIds || []; |
---|
| 269 | response.code = (obj.success) ? |
---|
| 270 | OpenLayers.Protocol.Response.SUCCESS : |
---|
| 271 | OpenLayers.Protocol.Response.FAILURE; |
---|
| 272 | options.callback.call(options.scope, response); |
---|
| 273 | } |
---|
| 274 | }, |
---|
| 275 | |
---|
| 276 | /** |
---|
| 277 | * Method: filterDelete |
---|
| 278 | * Send a request that deletes all features by their filter. |
---|
| 279 | * |
---|
| 280 | * Parameters: |
---|
| 281 | * filter - {OpenLayers.Filter} filter |
---|
| 282 | */ |
---|
| 283 | filterDelete: function(filter, options) { |
---|
| 284 | options = OpenLayers.Util.extend({}, options); |
---|
| 285 | OpenLayers.Util.applyDefaults(options, this.options); |
---|
| 286 | |
---|
| 287 | var response = new OpenLayers.Protocol.Response({ |
---|
| 288 | requestType: "commit" |
---|
| 289 | }); |
---|
| 290 | |
---|
| 291 | var root = this.format.createElementNSPlus("wfs:Transaction", { |
---|
| 292 | attributes: { |
---|
| 293 | service: "WFS", |
---|
| 294 | version: this.version |
---|
| 295 | } |
---|
| 296 | }); |
---|
| 297 | |
---|
| 298 | var deleteNode = this.format.createElementNSPlus("wfs:Delete", { |
---|
| 299 | attributes: { |
---|
| 300 | typeName: (options.featureNS ? this.featurePrefix + ":" : "") + |
---|
| 301 | options.featureType |
---|
| 302 | } |
---|
| 303 | }); |
---|
| 304 | |
---|
| 305 | if(options.featureNS) { |
---|
| 306 | deleteNode.setAttribute("xmlns:" + this.featurePrefix, options.featureNS); |
---|
| 307 | } |
---|
| 308 | var filterNode = this.format.writeNode("ogc:Filter", filter); |
---|
| 309 | |
---|
| 310 | deleteNode.appendChild(filterNode); |
---|
| 311 | |
---|
| 312 | root.appendChild(deleteNode); |
---|
| 313 | |
---|
| 314 | var data = OpenLayers.Format.XML.prototype.write.apply( |
---|
| 315 | this.format, [root] |
---|
| 316 | ); |
---|
| 317 | |
---|
| 318 | return OpenLayers.Request.POST({ |
---|
| 319 | url: this.url, |
---|
| 320 | callback : options.callback || function(){}, |
---|
| 321 | data: data |
---|
| 322 | }); |
---|
| 323 | |
---|
| 324 | }, |
---|
| 325 | |
---|
| 326 | /** |
---|
| 327 | * Method: abort |
---|
| 328 | * Abort an ongoing request, the response object passed to |
---|
| 329 | * this method must come from this protocol (as a result |
---|
| 330 | * of a read, or commit operation). |
---|
| 331 | * |
---|
| 332 | * Parameters: |
---|
| 333 | * response - {<OpenLayers.Protocol.Response>} |
---|
| 334 | */ |
---|
| 335 | abort: function(response) { |
---|
| 336 | if (response) { |
---|
| 337 | response.priv.abort(); |
---|
| 338 | } |
---|
| 339 | }, |
---|
| 340 | |
---|
| 341 | CLASS_NAME: "OpenLayers.Protocol.WFS.v1" |
---|
| 342 | }); |
---|