Adding a WFS protocol. This allows for creating, reading, updating, and deleting features via WFS. Huge thanks to ahocevar for the test writing and review. r=ahocevar (closes #1648)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@8868 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
Tim Schaub
2009-02-18 00:07:43 +00:00
parent 8274b648e8
commit 55f40e224a
17 changed files with 1942 additions and 0 deletions
+8
View File
@@ -193,6 +193,10 @@
"OpenLayers/Protocol/HTTP.js",
"OpenLayers/Protocol/SQL.js",
"OpenLayers/Protocol/SQL/Gears.js",
"OpenLayers/Protocol/WFS.js",
"OpenLayers/Protocol/WFS/v1.js",
"OpenLayers/Protocol/WFS/v1_0_0.js",
"OpenLayers/Protocol/WFS/v1_1_0.js",
"OpenLayers/Layer/PointTrack.js",
"OpenLayers/Layer/GML.js",
"OpenLayers/Style.js",
@@ -224,6 +228,10 @@
"OpenLayers/Format/SLD/v1.js",
"OpenLayers/Format/SLD/v1_0_0.js",
"OpenLayers/Format/SLD/v1.js",
"OpenLayers/Format/WFST.js",
"OpenLayers/Format/WFST/v1.js",
"OpenLayers/Format/WFST/v1_0_0.js",
"OpenLayers/Format/WFST/v1_1_0.js",
"OpenLayers/Format/Text.js",
"OpenLayers/Format/JSON.js",
"OpenLayers/Format/GeoJSON.js",
+29
View File
@@ -0,0 +1,29 @@
/**
* @requires OpenLayers/Format.js
*/
/**
* Function: OpenLayers.Format.WFST
* Used to create a versioned WFS protocol. Default version is 1.0.0.
*
* Returns:
* {<OpenLayers.Format>} A WFST format of the given version.
*/
OpenLayers.Format.WFST = function(options) {
options = OpenLayers.Util.applyDefaults(
options, OpenLayers.Format.WFST.DEFAULTS
);
var cls = OpenLayers.Format.WFST["v"+options.version.replace(/\./g, "_")];
if(!cls) {
throw "Unsupported WFST version: " + options.version;
}
return new cls(options);
}
/**
* Constant: OpenLayers.Format.WFST.DEFAULTS
* {Object} Default properties for the WFST format.
*/
OpenLayers.Format.WFST.DEFAULTS = {
"version": "1.0.0"
};
+373
View File
@@ -0,0 +1,373 @@
/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
* @requires OpenLayers/Format/XML.js
* @requires OpenLayers/Format/WFST.js
*/
/**
* Class: OpenLayers.Format.WFST.v1
* Superclass for WFST parsers.
*
* Inherits from:
* - <OpenLayers.Format.XML>
*/
OpenLayers.Format.WFST.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
/**
* Property: namespaces
* {Object} Mapping of namespace aliases to namespace URIs.
*/
namespaces: {
xlink: "http://www.w3.org/1999/xlink",
xsi: "http://www.w3.org/2001/XMLSchema-instance",
wfs: "http://www.opengis.net/wfs",
gml: "http://www.opengis.net/gml",
ogc: "http://www.opengis.net/ogc"
},
/**
* Property: defaultPrefix
*/
defaultPrefix: "wfs",
/**
* Property: version
* {String} WFS version number.
*/
version: null,
/**
* Property: schemaLocation
* {String} Schema location for a particular minor version.
*/
schemaLocations: null,
/**
* APIProperty: srsName
* {String} URI for spatial reference system.
*/
srsName: null,
/**
* APIProperty: extractAttributes
* {Boolean} Extract attributes from GML. Default is true.
*/
extractAttributes: true,
/**
* APIProperty: xy
* {Boolean} Order of the GML coordinate true:(x,y) or false:(y,x)
* Changing is not recommended, a new Format should be instantiated.
*/
xy: true,
/**
* Property: stateName
* {Object} Maps feature states to node names.
*/
stateName: null,
/**
* Constructor: OpenLayers.Format.WFST.v1
* Instances of this class are not created directly. Use the
* <OpenLayers.Format.WFST.v1_0_0> or <OpenLayers.Format.WFST.v1_1_0>
* constructor instead.
*
* Parameters:
* options - {Object} An optional object whose properties will be set on
* this instance.
*/
initialize: function(options) {
if(options.featureNS) {
this.namespaces = OpenLayers.Util.extend(
{feature: options.featureNS},
OpenLayers.Format.WFST.v1.prototype.namespaces
);
}
// set state name mapping
this.stateName = {};
this.stateName[OpenLayers.State.INSERT] = "wfs:Insert";
this.stateName[OpenLayers.State.UPDATE] = "wfs:Update";
this.stateName[OpenLayers.State.DELETE] = "wfs:Delete";
// extend format with misc properties from filter and gml formats
var filterProto = OpenLayers.Format.Filter.v1.prototype;
var gmlProto = OpenLayers.Format.GML.Base.prototype;
OpenLayers.Util.extend(this, {
readOgcExpression: filterProto.readOgcExpression,
getFilterType: filterProto.getFilterType,
filterMap: filterProto.filterMap,
regExes: gmlProto.regExes
});
OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);
},
/**
* Method: getSrsName
*/
getSrsName: function(feature, options) {
var srsName = options && options.srsName;
if(!srsName) {
if(feature && feature.layer) {
srsName = feature.layer.projection.getCode();
} else {
srsName = this.srsName;
}
}
return srsName;
},
/**
* Method: read
* Parse the response from a transaction. Because WFS is split into
* Transaction requests (create, update, and delete) and GetFeature
* requests (read), this method handles parsing of both types of
* responses.
*/
read: function(data) {
if(typeof data == "string") {
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
}
if(data && data.nodeType == 9) {
data = data.documentElement;
}
var obj = {};
this.readNode(data, obj);
if(obj.features) {
obj = obj.features;
}
return obj;
},
/**
* Property: readers
* Contains public functions, grouped by namespace prefix, that will
* be applied when a namespaced node is found matching the function
* name. The function will be applied in the scope of this parser
* with two arguments: the node being read and a context object passed
* from the parent.
*/
readers: {
"wfs": {
"FeatureCollection": function(node, obj) {
obj.features = [];
this.readChildNodes(node, obj);
}
}
},
/**
* Method: write
* Given an array of features, write a WFS transaction. This assumes
* the features have a state property that determines the operation
* type - insert, update, or delete.
*
* Parameters:
* features - {Array(<OpenLayers.Feature.Vector>)} A list of features.
*
* Returns:
* {String} A serialized WFS transaction.
*/
write: function(features) {
var node = this.writeNode("wfs:Transaction", features);
var value = this.schemaLocationAttr();
if(value) {
this.setAttributeNS(
node, this.namespaces["xsi"], "xsi:schemaLocation", value
)
}
return OpenLayers.Format.XML.prototype.write.apply(this, [node]);
},
/**
* Property: writers
* As a compliment to the readers property, this structure contains public
* writing functions grouped by namespace alias and named like the
* node names they produce.
*/
writers: {
"wfs": {
"GetFeature": function(options) {
var node = this.createElementNSPlus("wfs:GetFeature", {
attributes: {
service: "WFS",
version: this.version,
maxFeatures: options && options.maxFeatures,
"xsi:schemaLocation": this.schemaLocationAttr(options)
}
});
this.writeNode("Query", options, node);
return node;
},
"Query": function(options) {
options = OpenLayers.Util.extend({
featureNS: this.featureNS,
featurePrefix: this.featurePrefix,
featureType: this.featureType,
srsName: this.srsName
}, options);
// TODO: this is still version specific and should be separated out
// v1.0.0 does not allow srsName on wfs:Query
var node = this.createElementNSPlus("wfs:Query", {
attributes: {
typeName: (options.featureNS ? options.featurePrefix + ":" : "") +
options.featureType,
srsName: options.srsName
}
});
if(options.featureNS) {
node.setAttribute("xmlns:" + options.featurePrefix, options.featureNS);
}
if(options.filter) {
this.setFilterProperty(options.filter);
this.writeNode("ogc:Filter", options.filter, node);
}
return node;
},
"Transaction": function(features) {
var node = this.createElementNSPlus("wfs:Transaction", {
attributes: {
service: "WFS",
version: this.version
}
});
if(features) {
var name, feature;
for(var i=0, len=features.length; i<len; ++i) {
feature = features[i];
name = this.stateName[feature.state];
if(name) {
this.writeNode(name, feature, node);
}
}
}
return node;
},
"Insert": function(feature) {
var node = this.createElementNSPlus("wfs:Insert");
this.srsName = this.getSrsName(feature);
this.writeNode("feature:_typeName", feature, node);
return node;
},
"Update": function(feature) {
var node = this.createElementNSPlus("wfs:Update", {
attributes: {
typeName: (this.featureNS ? this.featurePrefix + ":" : "") +
this.featureType
}
});
if(this.featureNS) {
node.setAttribute("xmlns:" + this.featurePrefix, this.featureNS);
}
// add in geometry
this.writeNode(
"Property", {name: this.geometryName, value: feature}, node
);
// add in attributes
for(var key in feature.attributes) {
this.writeNode(
"Property", {name: key, value: feature.attributes[key]}, node
);
}
// add feature id filter
this.writeNode("ogc:Filter", new OpenLayers.Filter.FeatureId({
fids: [feature.fid]
}), node);
return node;
},
"Property": function(obj) {
var node = this.createElementNSPlus("wfs:Property");
this.writeNode("Name", obj.name, node);
this.writeNode("Value", obj.value, node);
return node;
},
"Name": function(name) {
return this.createElementNSPlus("wfs:Name", {value: name});
},
"Value": function(obj) {
var node;
if(obj instanceof OpenLayers.Feature.Vector) {
node = this.createElementNSPlus("wfs:Value");
this.srsName = this.getSrsName(obj);
var geom = this.writeNode("feature:_geometry", obj.geometry).firstChild;
node.appendChild(geom);
} else {
node = this.createElementNSPlus("wfs:Value", {value: obj});
}
return node;
},
"Delete": function(feature) {
var node = this.createElementNSPlus("wfs:Delete", {
attributes: {
typeName: (this.featureNS ? this.featurePrefix + ":" : "") +
this.featureType
}
});
if(this.featureNS) {
node.setAttribute("xmlns:" + this.featurePrefix, this.featureNS);
}
this.writeNode("ogc:Filter", new OpenLayers.Filter.FeatureId({
fids: [feature.fid]
}), node);
return node;
}
}
},
/**
* Method: schemaLocationAttr
* Generate the xsi:schemaLocation attribute value.
*
* Returns:
* {String} The xsi:schemaLocation attribute or undefined if none.
*/
schemaLocationAttr: function(options) {
options = OpenLayers.Util.extend({
featurePrefix: this.featurePrefix,
schema: this.schema
}, options);
var schemaLocations = OpenLayers.Util.extend({}, this.schemaLocations);
if(options.schema) {
schemaLocations[options.featurePrefix] = options.schema;
}
var parts = [];
var uri;
for(var key in schemaLocations) {
uri = this.namespaces[key];
if(uri) {
parts.push(uri + " " + schemaLocations[key]);
}
}
var value = parts.join(" ") || undefined;
return value;
},
/**
* Method: setFilterProperty
* Set the property of each spatial filter.
*
* Parameters:
* filter - {<OpenLayers.Filter>}
*/
setFilterProperty: function(filter) {
if(filter.filters) {
for(var i=0, len=filter.filters.length; i<len; ++i) {
this.setFilterProperty(filter.filters[i]);
}
} else {
if(filter instanceof OpenLayers.Filter.Spatial) {
// got a spatial filter, set its property
filter.property = this.geometryName;
}
}
},
CLASS_NAME: "OpenLayers.Format.WFST.v1"
});
+123
View File
@@ -0,0 +1,123 @@
/**
* @requires OpenLayers/Format/WFST/v1.js
* @requires OpenLayers/Format/GML/v2.js
* @requires OpenLayers/Format/Filter/v1_0_0.js
*/
/**
* Class: OpenLayers.Format.WFST.v1_0_0
* A format for creating WFS v1.0.0 transactions. Create a new instance with the
* <OpenLayers.Format.WFST.v1_0_0> constructor.
*
* Inherits from:
* - <OpenLayers.Format.WFST.v1>
*/
OpenLayers.Format.WFST.v1_0_0 = OpenLayers.Class(OpenLayers.Format.WFST.v1, {
/**
* Property: version
* {String} WFS version number.
*/
version: "1.0.0",
/**
* Property: schemaLocations
* {Object} Properties are namespace aliases, values are schema locations.
*/
schemaLocations: {
"wfs": "http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd"
},
/**
* Constructor: OpenLayers.Format.WFST.v1_0_0
* A class for parsing and generating WFS v1.0.0 transactions.
*
* Parameters:
* options - {Object} Optional object whose properties will be set on the
* instance.
*
* Valid options properties:
* featureType - {String} Local (without prefix) feature typeName (required).
* featureNS - {String} Feature namespace (optional).
* featurePrefix - {String} Feature namespace alias (optional - only used
* if featureNS is provided). Default is 'feature'.
* geometryName - {String} Name of geometry attribute. Default is 'the_geom'.
*/
initialize: function(options) {
OpenLayers.Format.WFST.v1.prototype.initialize.apply(this, [options]);
OpenLayers.Format.GML.v2.prototype.setGeometryTypes.call(this);
},
/**
* Property: readers
* Contains public functions, grouped by namespace prefix, that will
* be applied when a namespaced node is found matching the function
* name. The function will be applied in the scope of this parser
* with two arguments: the node being read and a context object passed
* from the parent.
*/
readers: {
"wfs": OpenLayers.Util.applyDefaults({
"WFS_TransactionResponse": function(node, obj) {
obj.insertIds = [];
obj.success = false;
this.readChildNodes(node, obj);
},
"InsertResult": function(node, container) {
var obj = {fids: []};
this.readChildNodes(node, obj);
container.insertIds.push(obj.fids[0]);
},
"TransactionResult": function(node, obj) {
this.readChildNodes(node, obj);
},
"Status": function(node, obj) {
this.readChildNodes(node, obj);
},
"SUCCESS": function(node, obj) {
obj.success = true;
}
}, OpenLayers.Format.WFST.v1.prototype.readers["wfs"]),
"gml": OpenLayers.Format.GML.v2.prototype.readers["gml"],
"feature": OpenLayers.Format.GML.v2.prototype.readers["feature"],
"ogc": OpenLayers.Format.Filter.v1_0_0.prototype.readers["ogc"]
},
/**
* Property: writers
* As a compliment to the readers property, this structure contains public
* writing functions grouped by namespace alias and named like the
* node names they produce.
*/
writers: {
"wfs": OpenLayers.Util.applyDefaults({
"Query": function(options) {
options = OpenLayers.Util.extend({
featureNS: this.featureNS,
featurePrefix: this.featurePrefix,
featureType: this.featureType,
srsName: this.srsName
}, options);
var node = this.createElementNSPlus("wfs:Query", {
attributes: {
typeName: (options.featureNS ? options.featurePrefix + ":" : "") +
options.featureType
}
});
if(options.featureNS) {
node.setAttribute("xmlns:" + options.featurePrefix, options.featureNS);
}
if(options.filter) {
this.setFilterProperty(options.filter);
this.writeNode("ogc:Filter", options.filter, node);
}
return node;
}
}, OpenLayers.Format.WFST.v1.prototype.writers["wfs"]),
"gml": OpenLayers.Format.GML.v2.prototype.writers["gml"],
"feature": OpenLayers.Format.GML.v2.prototype.writers["feature"],
"ogc": OpenLayers.Format.Filter.v1_0_0.prototype.writers["ogc"]
},
CLASS_NAME: "OpenLayers.Format.WFST.v1_0_0"
});
+122
View File
@@ -0,0 +1,122 @@
/**
* @requires OpenLayers/Format/WFST/v1.js
* @requires OpenLayers/Format/GML/v3.js
* @requires OpenLayers/Format/Filter/v1_1_0.js
*/
/**
* Class: OpenLayers.Format.WFST.v1_1_0
* A format for creating WFS v1.1.0 transactions. Create a new instance with the
* <OpenLayers.Format.WFST.v1_1_0> constructor.
*
* Inherits from:
* - <OpenLayers.Format.WFST.v1>
*/
OpenLayers.Format.WFST.v1_1_0 = OpenLayers.Class(OpenLayers.Format.WFST.v1, {
/**
* Property: version
* {String} WFS version number.
*/
version: "1.1.0",
/**
* Property: schemaLocations
* {Object} Properties are namespace aliases, values are schema locations.
*/
schemaLocations: {
"wfs": "http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"
},
/**
* Constructor: OpenLayers.Format.WFST.v1_1_0
* A class for parsing and generating WFS v1.1.0 transactions.
*
* Parameters:
* options - {Object} Optional object whose properties will be set on the
* instance.
*
* Valid options properties:
* featureType - {String} Local (without prefix) feature typeName (required).
* featureNS - {String} Feature namespace (optional).
* featurePrefix - {String} Feature namespace alias (optional - only used
* if featureNS is provided). Default is 'feature'.
* geometryName - {String} Name of geometry attribute. Default is 'the_geom'.
*/
initialize: function(options) {
OpenLayers.Format.WFST.v1.prototype.initialize.apply(this, [options]);
OpenLayers.Format.GML.v3.prototype.setGeometryTypes.call(this);
},
/**
* Property: readers
* Contains public functions, grouped by namespace prefix, that will
* be applied when a namespaced node is found matching the function
* name. The function will be applied in the scope of this parser
* with two arguments: the node being read and a context object passed
* from the parent.
*/
readers: {
"wfs": OpenLayers.Util.applyDefaults({
"TransactionResponse": function(node, obj) {
obj.insertIds = [];
obj.success = false;
this.readChildNodes(node, obj);
},
"TransactionSummary": function(node, obj) {
// this is a limited test of success
obj.success = true;
},
"InsertResults": function(node, obj) {
this.readChildNodes(node, obj);
},
"Feature": function(node, container) {
var obj = {fids: []};
this.readChildNodes(node, obj);
container.insertIds.push(obj.fids[0]);
}
}, OpenLayers.Format.WFST.v1.prototype.readers["wfs"]),
"gml": OpenLayers.Format.GML.v3.prototype.readers["gml"],
"feature": OpenLayers.Format.GML.v3.prototype.readers["feature"],
"ogc": OpenLayers.Format.Filter.v1_1_0.prototype.readers["ogc"]
},
/**
* Property: writers
* As a compliment to the readers property, this structure contains public
* writing functions grouped by namespace alias and named like the
* node names they produce.
*/
writers: {
"wfs": OpenLayers.Util.applyDefaults({
"Query": function(options) {
options = OpenLayers.Util.extend({
featureNS: this.featureNS,
featurePrefix: this.featurePrefix,
featureType: this.featureType,
srsName: this.srsName
}, options);
var node = this.createElementNSPlus("wfs:Query", {
attributes: {
typeName: (options.featureNS ? options.featurePrefix + ":" : "") +
options.featureType,
srsName: options.srsName
}
});
if(options.featureNS) {
node.setAttribute("xmlns:" + options.featurePrefix, options.featureNS);
}
if(options.filter) {
this.setFilterProperty(options.filter);
this.writeNode("ogc:Filter", options.filter, node);
}
return node;
}
}, OpenLayers.Format.WFST.v1.prototype.writers["wfs"]),
"gml": OpenLayers.Format.GML.v3.prototype.writers["gml"],
"feature": OpenLayers.Format.GML.v3.prototype.writers["feature"],
"ogc": OpenLayers.Format.Filter.v1_1_0.prototype.writers["ogc"]
},
CLASS_NAME: "OpenLayers.Format.WFST.v1_1_0"
});
+28
View File
@@ -0,0 +1,28 @@
/**
* @requires OpenLayers/Protocol.js
*/
/**
* Function: OpenLayers.Protocol.WFS
* Used to create a versioned WFS protocol. Default version is 1.0.0.
*
* Returns:
* {<OpenLayers.Protocol>} A WFS protocol of the given version.
*/
OpenLayers.Protocol.WFS = function(options) {
options = OpenLayers.Util.applyDefaults(
options, OpenLayers.Protocol.WFS.DEFAULTS
);
var cls = OpenLayers.Protocol.WFS["v"+options.version.replace(/\./g, "_")];
if(!cls) {
throw "Unsupported WFS version: " + options.version;
}
return new cls(options);
}
/**
* Constant: OpenLayers.Protocol.WFS.DEFAULTS
*/
OpenLayers.Protocol.WFS.DEFAULTS = {
"version": "1.0.0"
};
+328
View File
@@ -0,0 +1,328 @@
/**
* @requires OpenLayers/Protocol/WFS.js
*/
/**
* Class: OpenLayers.Protocol.WFS.v1
* Abstract class for for v1.0.0 and v1.1.0 protocol.
*
* Inherits from:
* - <OpenLayers.Protocol>
*/
OpenLayers.Protocol.WFS.v1 = new OpenLayers.Class(OpenLayers.Protocol, {
/**
* Property: version
* {String} WFS version number.
*/
version: null,
/**
* Property: srsName
* {String} Name of spatial reference system. Default is "EPSG:4326".
*/
srsName: "EPSG:4326",
/**
* Property: featureType
* {String} Local feature typeName.
*/
featureType: null,
/**
* Property: featureNS
* {String} Feature namespace.
*/
featureNS: null,
/**
* Property: geometryName
* {String} Name of the geometry attribute for features. Default is
* "the_geom".
*/
geometryName: "the_geom",
/**
* Property: schema
* {String} Optional schema location that will be included in the
* schemaLocation attribute value. Note that the feature type schema
* is required for a strict XML validator (on transactions with an
* insert for example), but is *not* required by the WFS specification
* (since the server is supposed to know about feature type schemas).
*/
schema: null,
/**
* Property: featurePrefix
* {String} Namespace alias for feature type. Default is "feature".
*/
featurePrefix: "feature",
/**
* Property: formatOptions
* {Object} Optional options for the format. If a format is not provided,
* this property can be used to extend the default format options.
*/
formatOptions: null,
/**
* Constructor: OpenLayers.Protocol.WFS
* A class for giving layers WFS protocol.
*
* Parameters:
* options - {Object} Optional object whose properties will be set on the
* instance.
*
* Valid options properties:
* url - {String} URL to send requests to (required).
* featureType - {String} Local (without prefix) feature typeName (required).
* featureNS - {String} Feature namespace (required, but can be autodetected
* for reading if featurePrefix is provided and identical to the prefix
* in the server response).
* featurePrefix - {String} Feature namespace alias (optional - only used
* for writing if featureNS is provided). Default is 'feature'.
* geometryName - {String} Name of geometry attribute. Default is 'the_geom'.
*/
initialize: function(options) {
OpenLayers.Protocol.prototype.initialize.apply(this, [options]);
if(!options.format) {
this.format = OpenLayers.Format.WFST(OpenLayers.Util.extend({
version: this.version,
featureType: this.featureType,
featureNS: this.featureNS,
featurePrefix: this.featurePrefix,
geometryName: this.geometryName,
srsName: this.srsName,
schema: this.schema
}, this.formatOptions));
}
if(!this.featureNS) {
// featureNS autodetection
var readNode = this.format.readNode;
this.format.readNode = function(node, obj) {
if(!this.featureNS && node.prefix == this.featurePrefix) {
this.featureNS = node.namespaceURI;
this.setNamespace("feature", this.featureNS);
}
return readNode.apply(this, arguments);
}
}
},
/**
* APIMethod: destroy
* Clean up the protocol.
*/
destroy: function() {
if(this.options && !this.options.format) {
this.format.destroy();
}
this.format = null;
OpenLayers.Protocol.prototype.destroy.apply(this);
},
/**
* Method: createCallback
* Returns a function that applies the given public method with resp and
* options arguments.
*
* Parameters:
* method - {Function} The method to be applied by the callback.
* response - {<OpenLayers.Protocol.Response>} The protocol response object.
* options - {Object} Options sent to the protocol method (read, create,
* update, or delete).
*/
createCallback: function(method, response, options) {
return OpenLayers.Function.bind(function() {
method.apply(this, [response, options]);
}, this);
},
/**
* Method: read
* Construct a request for reading new features. Since WFS splits the
* basic CRUD operations into GetFeature requests (for read) and
* Transactions (for all others), this method does not make use of the
* format's read method (that is only about reading transaction
* responses).
*/
read: function(options) {
options = OpenLayers.Util.extend({}, options);
OpenLayers.Util.applyDefaults(options, this.options || {});
var response = new OpenLayers.Protocol.Response({requestType: "read"});
var data = OpenLayers.Format.XML.prototype.write.apply(
this.format, [this.format.writeNode("wfs:GetFeature", options)]
);
response.priv = OpenLayers.Request.POST({
url: options.url,
callback: this.createCallback(this.handleRead, response, options),
params: options.params,
headers: options.headers,
data: data
});
return response;
},
/**
* Method: handleRead
* Deal with response from the read request.
*
* Parameters:
* response - {<OpenLayers.Protocol.Response>} The response object to pass
* to the user callback.
* options - {Object} The user options passed to the read call.
*/
handleRead: function(response, options) {
if(options.callback) {
var request = response.priv;
if(request.status >= 200 && request.status < 300) {
// success
response.features = this.parseFeatures(request);
response.code = OpenLayers.Protocol.Response.SUCCESS;
} else {
// failure
response.code = OpenLayers.Protocol.Response.FAILURE;
}
options.callback.call(options.scope, response);
};
},
/**
* Method: parseFeatures
* Read HTTP response body and return features
*
* Parameters:
* request - {XMLHttpRequest} The request object
*
* Returns:
* {Array({<OpenLayers.Feature.Vector>})} or
* {<OpenLayers.Feature.Vector>} Array of features or a single feature.
*/
parseFeatures: function(request) {
var doc = request.responseXML;
if(!doc || !doc.documentElement) {
doc = request.responseText;
}
if(!doc || doc.length <= 0) {
return null;
}
return this.format.read(doc);
},
/**
* Method: commit
* Given a list of feature, assemble a batch request for update, create,
* and delete transactions. A commit call on the prototype amounts
* to writing a WFS transaction - so the write method on the format
* is used.
*
* Parameters:
* features - {Array(<OpenLayers.Feature.Vector>}
*
* Returns:
* {<OpenLayers.Protocol.Response>} A response object with a features
* property containing any insertIds and a priv property referencing
* the XMLHttpRequest object.
*/
commit: function(features, options) {
options = OpenLayers.Util.extend({}, options);
OpenLayers.Util.applyDefaults(options, this.options);
var response = new OpenLayers.Protocol.Response({
requestType: "commit",
reqFeatures: features
});
response.priv = OpenLayers.Request.POST({
url: options.url,
data: this.format.write(features, options),
callback: this.createCallback(this.handleCommit, response, options)
});
return response;
},
/**
* Method: handleCommit
* Called when the commit request returns.
*
* Parameters:
* response - {<OpenLayers.Protocol.Response>} The response object to pass
* to the user callback.
* options - {Object} The user options passed to the commit call.
*/
handleCommit: function(response, options) {
if(options.callback) {
var request = response.priv;
// ensure that we have an xml doc
var data = request.responseXML;
if(!data || !data.documentElement) {
data = request.responseText;
}
var obj = this.format.read(data) || {};
response.insertIds = obj.insertIds || [];
response.code = (obj.success) ?
OpenLayers.Protocol.Response.SUCCESS :
OpenLayers.Protocol.Response.FAILURE;
options.callback.call(options.scope, response);
}
},
/**
* Method: filterDelete
* Send a request that deletes all features by their filter.
*
* Parameters:
* filter - {OpenLayers.Filter} filter
*/
filterDelete: function(filter, options) {
options = OpenLayers.Util.extend({}, options);
OpenLayers.Util.applyDefaults(options, this.options);
var response = new OpenLayers.Protocol.Response({
requestType: "commit"
});
var root = this.format.createElementNSPlus("wfs:Transaction", {
attributes: {
service: "WFS",
version: this.version
}
});
var deleteNode = this.format.createElementNSPlus("wfs:Delete", {
attributes: {
typeName: (options.featureNS ? this.featurePrefix + ":" : "") +
options.featureType
}
});
if(options.featureNS) {
deleteNode.setAttribute("xmlns:" + this.featurePrefix, options.featureNS);
}
var filterNode = this.format.writeNode("ogc:Filter", filter);
deleteNode.appendChild(filterNode);
root.appendChild(deleteNode);
var data = OpenLayers.Format.XML.prototype.write.apply(
this.format, [root]
);
return OpenLayers.Request.POST({
url: this.url,
callback : options.callback || function(){},
data: data
});
},
CLASS_NAME: "OpenLayers.Protocol.WFS.v1"
});
+39
View File
@@ -0,0 +1,39 @@
/**
* @requires OpenLayers/Protocol/WFS/v1.js
* @requires OpenLayers/Format/WFST/v1_0_0.js
*/
/**
* Class: OpenLayers.Protocol.WFS.v1_0_0
* A WFS v1.0.0 protocol for vector layers. Create a new instance with the
* <OpenLayers.Protocol.WFS.v1_0_0> constructor.
*
* Inherits from:
* - <OpenLayers.Protocol.WFS.v1>
*/
OpenLayers.Protocol.WFS.v1_0_0 = OpenLayers.Class(OpenLayers.Protocol.WFS.v1, {
/**
* Property: version
* {String} WFS version number.
*/
version: "1.0.0",
/**
* Constructor: OpenLayers.Protocol.WFS.v1_0_0
* A class for giving layers WFS v1.0.0 protocol.
*
* Parameters:
* options - {Object} Optional object whose properties will be set on the
* instance.
*
* Valid options properties:
* featureType - {String} Local (without prefix) feature typeName (required).
* featureNS - {String} Feature namespace (optional).
* featurePrefix - {String} Feature namespace alias (optional - only used
* if featureNS is provided). Default is 'feature'.
* geometryName - {String} Name of geometry attribute. Default is 'the_geom'.
*/
CLASS_NAME: "OpenLayers.Protocol.WFS.v1_0_0"
});
+43
View File
@@ -0,0 +1,43 @@
/**
* @requires OpenLayers/Protocol/WFS/v1.js
* @requires OpenLayers/Format/WFST/v1_1_0.js
*/
/**
* Class: OpenLayers.Protocol.WFS.v1_1_0
* A WFS v1.1.0 protocol for vector layers. Create a new instance with the
* <OpenLayers.Protocol.WFS.v1_1_0> constructor.
*
* Differences from the v1.0.0 protocol:
* - uses Filter Encoding 1.1.0 instead of 1.0.0
* - uses GML 3 instead of 2 if no format is provided
*
* Inherits from:
* - <OpenLayers.Protocol.WFS.v1>
*/
OpenLayers.Protocol.WFS.v1_1_0 = OpenLayers.Class(OpenLayers.Protocol.WFS.v1, {
/**
* Property: version
* {String} WFS version number.
*/
version: "1.1.0",
/**
* Constructor: OpenLayers.Protocol.WFS.v1_1_0
* A class for giving layers WFS v1.1.0 protocol.
*
* Parameters:
* options - {Object} Optional object whose properties will be set on the
* instance.
*
* Valid options properties:
* featureType - {String} Local (without prefix) feature typeName (required).
* featureNS - {String} Feature namespace (optional).
* featurePrefix - {String} Feature namespace alias (optional - only used
* if featureNS is provided). Default is 'feature'.
* geometryName - {String} Name of geometry attribute. Default is 'the_geom'.
*/
CLASS_NAME: "OpenLayers.Protocol.WFS.v1_1_0"
});