Add write support for Transaction
This commit is contained in:
@@ -346,6 +346,18 @@
|
|||||||
* @property {ol.Extent|undefined} bbox Extent to use for the BBOX filter.
|
* @property {ol.Extent|undefined} bbox Extent to use for the BBOX filter.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {Object} olx.format.WFSWriteTransactionOptions
|
||||||
|
* @property {string} featureNS The namespace URI used for features.
|
||||||
|
* @property {string} featurePrefix The prefix for the feature namespace.
|
||||||
|
* @property {string} featureType The feature type name.
|
||||||
|
* @property {string|undefined} srsName SRS name. No srsName attribute will be
|
||||||
|
* set on geometries when this is not provided.
|
||||||
|
* @property {string|undefined} handle Handle.
|
||||||
|
* @property {Array.<Object>} nativeElements Native elements. Currently not
|
||||||
|
* supported.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Object} olx.interaction.DoubleClickZoomOptions
|
* @typedef {Object} olx.interaction.DoubleClickZoomOptions
|
||||||
* @property {number|undefined} duration Animation duration in milliseconds. Default is `250`.
|
* @property {number|undefined} duration Animation duration in milliseconds. Default is `250`.
|
||||||
|
|||||||
+17
-15
@@ -1419,9 +1419,8 @@ ol.format.GML.writeGeometry = function(node, geometry, objectStack) {
|
|||||||
* @param {Node} node Node.
|
* @param {Node} node Node.
|
||||||
* @param {ol.Feature} feature Feature.
|
* @param {ol.Feature} feature Feature.
|
||||||
* @param {Array.<*>} objectStack Node stack.
|
* @param {Array.<*>} objectStack Node stack.
|
||||||
* @private
|
|
||||||
*/
|
*/
|
||||||
ol.format.GML.writeFeature_ = function(node, feature, objectStack) {
|
ol.format.GML.writeFeature = function(node, feature, objectStack) {
|
||||||
var fid = feature.getId();
|
var fid = feature.getId();
|
||||||
if (goog.isDef(fid)) {
|
if (goog.isDef(fid)) {
|
||||||
node.setAttribute('fid', fid);
|
node.setAttribute('fid', fid);
|
||||||
@@ -1437,17 +1436,20 @@ ol.format.GML.writeFeature_ = function(node, feature, objectStack) {
|
|||||||
var properties = feature.getProperties();
|
var properties = feature.getProperties();
|
||||||
var keys = [], values = [];
|
var keys = [], values = [];
|
||||||
for (var key in properties) {
|
for (var key in properties) {
|
||||||
keys.push(key);
|
var value = properties[key];
|
||||||
values.push(properties[key]);
|
if (!goog.isNull(value)) {
|
||||||
if (key == geometryName) {
|
keys.push(key);
|
||||||
if (!(key in context.serializers[featureNS])) {
|
values.push(value);
|
||||||
context.serializers[featureNS][key] = ol.xml.makeChildAppender(
|
if (key == geometryName) {
|
||||||
ol.format.GML.writeGeometry);
|
if (!(key in context.serializers[featureNS])) {
|
||||||
}
|
context.serializers[featureNS][key] = ol.xml.makeChildAppender(
|
||||||
} else {
|
ol.format.GML.writeGeometry);
|
||||||
if (!(key in context.serializers[featureNS])) {
|
}
|
||||||
context.serializers[featureNS][key] = ol.xml.makeChildAppender(
|
} else {
|
||||||
ol.format.XSD.writeStringTextNode);
|
if (!(key in context.serializers[featureNS])) {
|
||||||
|
context.serializers[featureNS][key] = ol.xml.makeChildAppender(
|
||||||
|
ol.format.XSD.writeStringTextNode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1455,7 +1457,7 @@ ol.format.GML.writeFeature_ = function(node, feature, objectStack) {
|
|||||||
item.node = node;
|
item.node = node;
|
||||||
ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */
|
ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */
|
||||||
(item), context.serializers,
|
(item), context.serializers,
|
||||||
ol.xml.OBJECT_PROPERTY_NODE_FACTORY,
|
ol.xml.makeSimpleNodeFactory(undefined, featureNS),
|
||||||
values,
|
values,
|
||||||
objectStack, keys);
|
objectStack, keys);
|
||||||
};
|
};
|
||||||
@@ -1475,7 +1477,7 @@ ol.format.GML.writeFeatureMembers_ = function(node, features, objectStack) {
|
|||||||
var serializers = {};
|
var serializers = {};
|
||||||
serializers[featureNS] = {};
|
serializers[featureNS] = {};
|
||||||
serializers[featureNS][featureType] = ol.xml.makeChildAppender(
|
serializers[featureNS][featureType] = ol.xml.makeChildAppender(
|
||||||
ol.format.GML.writeFeature_);
|
ol.format.GML.writeFeature);
|
||||||
var item = goog.object.clone(context);
|
var item = goog.object.clone(context);
|
||||||
item.node = node;
|
item.node = node;
|
||||||
ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */
|
ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ goog.require('goog.object');
|
|||||||
goog.require('ol.format.GML');
|
goog.require('ol.format.GML');
|
||||||
goog.require('ol.format.XMLFeature');
|
goog.require('ol.format.XMLFeature');
|
||||||
goog.require('ol.format.XSD');
|
goog.require('ol.format.XSD');
|
||||||
|
goog.require('ol.geom.Geometry');
|
||||||
goog.require('ol.xml');
|
goog.require('ol.xml');
|
||||||
|
|
||||||
|
|
||||||
@@ -287,6 +288,124 @@ ol.format.WFS.QUERY_SERIALIZERS_ = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {ol.Feature} feature Feature.
|
||||||
|
* @param {Array.<*>} objectStack Node stack.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.WFS.writeFeature_ = function(node, feature, objectStack) {
|
||||||
|
var context = objectStack[objectStack.length - 1];
|
||||||
|
goog.asserts.assert(goog.isObject(context));
|
||||||
|
var featureType = goog.object.get(context, 'featureType');
|
||||||
|
var featureNS = goog.object.get(context, 'featureNS');
|
||||||
|
var child = ol.xml.createElementNS(featureNS, featureType);
|
||||||
|
node.appendChild(child);
|
||||||
|
ol.format.GML.writeFeature(child, feature, objectStack);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {number|string} fid Feature identifier.
|
||||||
|
* @param {Array.<*>} objectStack Node stack.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.WFS.writeOgcFidFilter_ = function(node, fid, objectStack) {
|
||||||
|
var filter = ol.xml.createElementNS('http://www.opengis.net/ogc', 'Filter');
|
||||||
|
var child = ol.xml.createElementNS('http://www.opengis.net/ogc', 'FeatureId');
|
||||||
|
filter.appendChild(child);
|
||||||
|
child.setAttribute('fid', fid);
|
||||||
|
node.appendChild(filter);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {ol.Feature} feature Feature.
|
||||||
|
* @param {Array.<*>} objectStack Node stack.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.WFS.writeDelete_ = function(node, feature, objectStack) {
|
||||||
|
var context = objectStack[objectStack.length - 1];
|
||||||
|
goog.asserts.assert(goog.isObject(context));
|
||||||
|
var featureType = goog.object.get(context, 'featureType');
|
||||||
|
var featurePrefix = goog.object.get(context, 'featurePrefix');
|
||||||
|
node.setAttribute('typeName', featurePrefix + ':' + featureType);
|
||||||
|
var fid = feature.getId();
|
||||||
|
if (goog.isDef(fid)) {
|
||||||
|
ol.format.WFS.writeOgcFidFilter_(node, fid, objectStack);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {ol.Feature} feature Feature.
|
||||||
|
* @param {Array.<*>} objectStack Node stack.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.WFS.writeUpdate_ = function(node, feature, objectStack) {
|
||||||
|
var context = objectStack[objectStack.length - 1];
|
||||||
|
goog.asserts.assert(goog.isObject(context));
|
||||||
|
var featureType = goog.object.get(context, 'featureType');
|
||||||
|
var featurePrefix = goog.object.get(context, 'featurePrefix');
|
||||||
|
node.setAttribute('typeName', featurePrefix + ':' + featureType);
|
||||||
|
var fid = feature.getId();
|
||||||
|
if (goog.isDef(fid)) {
|
||||||
|
var keys = feature.getKeys();
|
||||||
|
var values = [];
|
||||||
|
for (var i = 0, ii = keys.length; i < ii; i++) {
|
||||||
|
var value = feature.get(keys[i]);
|
||||||
|
if (goog.isDef(value)) {
|
||||||
|
values.push({name: keys[i], value: value});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ol.xml.pushSerializeAndPop({node: node},
|
||||||
|
ol.format.WFS.TRANSACTION_SERIALIZERS_,
|
||||||
|
ol.xml.makeSimpleNodeFactory('Property'), values,
|
||||||
|
objectStack);
|
||||||
|
ol.format.WFS.writeOgcFidFilter_(node, fid, objectStack);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Node} node Node.
|
||||||
|
* @param {Object} pair Property name and value.
|
||||||
|
* @param {Array.<*>} objectStack Node stack.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.WFS.writeProperty_ = function(node, pair, objectStack) {
|
||||||
|
var name = ol.xml.createElementNS('http://www.opengis.net/wfs', 'Name');
|
||||||
|
node.appendChild(name);
|
||||||
|
ol.format.XSD.writeStringTextNode(name, pair.name);
|
||||||
|
if (goog.isDefAndNotNull(pair.value)) {
|
||||||
|
var value = ol.xml.createElementNS('http://www.opengis.net/wfs', 'Value');
|
||||||
|
node.appendChild(value);
|
||||||
|
if (pair.value instanceof ol.geom.Geometry) {
|
||||||
|
ol.format.GML.writeGeometry(value, pair.value, objectStack);
|
||||||
|
} else {
|
||||||
|
ol.format.XSD.writeStringTextNode(value, pair.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Object.<string, Object.<string, ol.xml.Serializer>>}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
ol.format.WFS.TRANSACTION_SERIALIZERS_ = {
|
||||||
|
'http://www.opengis.net/wfs': {
|
||||||
|
'Insert': ol.xml.makeChildAppender(ol.format.WFS.writeFeature_),
|
||||||
|
'Update': ol.xml.makeChildAppender(ol.format.WFS.writeUpdate_),
|
||||||
|
'Delete': ol.xml.makeChildAppender(ol.format.WFS.writeDelete_),
|
||||||
|
'Property': ol.xml.makeChildAppender(ol.format.WFS.writeProperty_)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Node} node Node.
|
* @param {Node} node Node.
|
||||||
* @param {string} featureType Feature type.
|
* @param {string} featureType Feature type.
|
||||||
@@ -428,3 +547,48 @@ ol.format.WFS.prototype.writeGetFeature = function(options) {
|
|||||||
ol.format.WFS.writeGetFeature_(node, options.featureTypes, [context]);
|
ol.format.WFS.writeGetFeature_(node, options.featureTypes, [context]);
|
||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array.<ol.Feature>} inserts The features to insert.
|
||||||
|
* @param {Array.<ol.Feature>} updates The features to update.
|
||||||
|
* @param {Array.<ol.Feature>} deletes The features to delete.
|
||||||
|
* @param {olx.format.WFSWriteTransactionOptions} options Write options.
|
||||||
|
* @return {ArrayBuffer|Node|Object|string} Result.
|
||||||
|
*/
|
||||||
|
ol.format.WFS.prototype.writeTransaction = function(inserts, updates, deletes,
|
||||||
|
options) {
|
||||||
|
var node = ol.xml.createElementNS('http://www.opengis.net/wfs',
|
||||||
|
'Transaction');
|
||||||
|
node.setAttribute('service', 'WFS');
|
||||||
|
node.setAttribute('version', '1.1.0');
|
||||||
|
if (goog.isDef(options)) {
|
||||||
|
if (goog.isDef(options.handle)) {
|
||||||
|
node.setAttribute('handle', options.handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ol.xml.setAttributeNS(node, 'http://www.w3.org/2001/XMLSchema-instance',
|
||||||
|
'xsi:schemaLocation', this.schemaLocation_);
|
||||||
|
if (goog.isDefAndNotNull(inserts)) {
|
||||||
|
ol.xml.pushSerializeAndPop({node: node, featureNS: options.featureNS,
|
||||||
|
featureType: options.featureType},
|
||||||
|
ol.format.WFS.TRANSACTION_SERIALIZERS_,
|
||||||
|
ol.xml.makeSimpleNodeFactory('Insert'), inserts,
|
||||||
|
[]);
|
||||||
|
}
|
||||||
|
if (goog.isDefAndNotNull(updates)) {
|
||||||
|
ol.xml.pushSerializeAndPop({node: node, featureNS: options.featureNS,
|
||||||
|
featureType: options.featureType, featurePrefix: options.featurePrefix},
|
||||||
|
ol.format.WFS.TRANSACTION_SERIALIZERS_,
|
||||||
|
ol.xml.makeSimpleNodeFactory('Update'), updates,
|
||||||
|
[]);
|
||||||
|
}
|
||||||
|
if (goog.isDefAndNotNull(deletes)) {
|
||||||
|
ol.xml.pushSerializeAndPop({node: node, featureNS: options.featureNS,
|
||||||
|
featureType: options.featureType, featurePrefix: options.featurePrefix},
|
||||||
|
ol.format.WFS.TRANSACTION_SERIALIZERS_,
|
||||||
|
ol.xml.makeSimpleNodeFactory('Delete'), deletes,
|
||||||
|
[]);
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
};
|
||||||
|
|||||||
+4
-4
@@ -1,11 +1,11 @@
|
|||||||
<wfs:Transaction xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" service="WFS" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd">
|
<wfs:Transaction xmlns:wfs="http://www.opengis.net/wfs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" service="WFS" version="1.1.0" xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
|
||||||
<wfs:Insert>
|
<wfs:Insert>
|
||||||
<feature:states xmlns:feature="http://www.openplans.org/topp">
|
<feature:states xmlns:feature="http://www.openplans.org/topp">
|
||||||
<feature:the_geom>
|
<feature:the_geom>
|
||||||
<gml:MultiPoint xmlns:gml="http://www.opengis.net/gml">
|
<gml:MultiPoint xmlns:gml="http://www.opengis.net/gml">
|
||||||
<gml:pointMember>
|
<gml:pointMember>
|
||||||
<gml:Point>
|
<gml:Point>
|
||||||
<gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates>
|
<gml:pos>1 2</gml:pos>
|
||||||
</gml:Point>
|
</gml:Point>
|
||||||
</gml:pointMember>
|
</gml:pointMember>
|
||||||
</gml:MultiPoint>
|
</gml:MultiPoint>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
<gml:MultiPoint xmlns:gml="http://www.opengis.net/gml">
|
<gml:MultiPoint xmlns:gml="http://www.opengis.net/gml">
|
||||||
<gml:pointMember>
|
<gml:pointMember>
|
||||||
<gml:Point>
|
<gml:Point>
|
||||||
<gml:coordinates decimal="." cs="," ts=" ">1,2</gml:coordinates>
|
<gml:pos>1 2</gml:pos>
|
||||||
</gml:Point>
|
</gml:Point>
|
||||||
</gml:pointMember>
|
</gml:pointMember>
|
||||||
</gml:MultiPoint>
|
</gml:MultiPoint>
|
||||||
@@ -42,4 +42,4 @@
|
|||||||
<ogc:FeatureId fid="fid.37"/>
|
<ogc:FeatureId fid="fid.37"/>
|
||||||
</ogc:Filter>
|
</ogc:Filter>
|
||||||
</wfs:Delete>
|
</wfs:Delete>
|
||||||
</wfs:Transaction>
|
</wfs:Transaction>
|
||||||
@@ -176,9 +176,69 @@ describe('ol.format.WFS', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when writing out a Transaction request', function() {
|
||||||
|
|
||||||
|
it('creates a handle', function() {
|
||||||
|
var text =
|
||||||
|
'<wfs:Transaction xmlns:wfs="http://www.opengis.net/wfs" ' +
|
||||||
|
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
|
||||||
|
'service="WFS" version="1.1.0" handle="handle_t" ' +
|
||||||
|
'xsi:schemaLocation="http://www.opengis.net/wfs ' +
|
||||||
|
'http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"/>';
|
||||||
|
var serialized = new ol.format.WFS().writeTransaction(null, null, null,
|
||||||
|
{handle: 'handle_t'});
|
||||||
|
expect(serialized).to.xmleql(ol.xml.load(text));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when writing out a Transaction request', function() {
|
||||||
|
var text;
|
||||||
|
before(function(done) {
|
||||||
|
afterLoadText('spec/ol/format/wfs/TransactionMulti.xml', function(xml) {
|
||||||
|
text = xml;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('creates the correct transaction body', function() {
|
||||||
|
var format = new ol.format.WFS();
|
||||||
|
var insertFeature = new ol.Feature({
|
||||||
|
the_geom: new ol.geom.MultiPoint([[1, 2]]),
|
||||||
|
foo: 'bar',
|
||||||
|
nul: null
|
||||||
|
});
|
||||||
|
insertFeature.setGeometryName('the_geom');
|
||||||
|
var inserts = [insertFeature];
|
||||||
|
var updateFeature = new ol.Feature({
|
||||||
|
the_geom: new ol.geom.MultiPoint([[1, 2]]),
|
||||||
|
foo: 'bar',
|
||||||
|
// null value gets Property element with no Value
|
||||||
|
nul: null,
|
||||||
|
// undefined value means don't create a Property element
|
||||||
|
unwritten: undefined
|
||||||
|
});
|
||||||
|
updateFeature.setId('fid.42');
|
||||||
|
var updates = [updateFeature];
|
||||||
|
|
||||||
|
var deleteFeature = new ol.Feature();
|
||||||
|
deleteFeature.setId('fid.37');
|
||||||
|
var deletes = [deleteFeature];
|
||||||
|
var serialized = format.writeTransaction(inserts, updates, deletes, {
|
||||||
|
featureNS: 'http://www.openplans.org/topp',
|
||||||
|
featureType: 'states',
|
||||||
|
featurePrefix: 'topp'
|
||||||
|
});
|
||||||
|
expect(serialized).to.xmleql(ol.xml.load(text));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
goog.require('ol.xml');
|
goog.require('ol.xml');
|
||||||
|
goog.require('ol.Feature');
|
||||||
|
goog.require('ol.geom.MultiPoint');
|
||||||
goog.require('ol.geom.MultiPolygon');
|
goog.require('ol.geom.MultiPolygon');
|
||||||
goog.require('ol.format.WFS');
|
goog.require('ol.format.WFS');
|
||||||
|
|||||||
Reference in New Issue
Block a user