diff --git a/examples/mapguide-untiled.html b/examples/mapguide-untiled.html
new file mode 100644
index 0000000000..0d80284c1b
--- /dev/null
+++ b/examples/mapguide-untiled.html
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+ MapGuide untiled example
+
+
+
+
+
+
+
+
+
+
+
+
+
MapGuide untiled example
+
Example of a untiled MapGuide map.
+
+
mapguide
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/mapguide-untiled.js b/examples/mapguide-untiled.js
new file mode 100644
index 0000000000..d8b84060c1
--- /dev/null
+++ b/examples/mapguide-untiled.js
@@ -0,0 +1,40 @@
+goog.require('ol.Map');
+goog.require('ol.RendererHint');
+goog.require('ol.View2D');
+goog.require('ol.layer.Image');
+goog.require('ol.source.MapGuide');
+
+var mdf = 'Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition';
+var agentUrl =
+ 'http://data.mapguide.com/mapguide/mapagent/mapagent.fcgi?USERNAME=Anonymous';
+var bounds = [
+ -87.865114442365922,
+ 43.665065564837931,
+ -87.595394059497067,
+ 43.823852564430069
+];
+var map = new ol.Map({
+ layers: [
+ new ol.layer.Image({
+ source: new ol.source.MapGuide({
+ projection: 'EPSG:4326',
+ url: agentUrl,
+ useOverlay: false,
+ metersPerUnit: 111319.4908, //value returned from mapguide
+ params: {
+ MAPDEFINITION: mdf,
+ FORMAT: 'PNG'
+ },
+ ratio: 2,
+ extent: bounds
+ })
+ })
+ ],
+ renderer: ol.RendererHint.CANVAS,
+ target: 'map',
+ view: new ol.View2D({
+ center: [-87.7302542509315, 43.744459064634],
+ projection: 'EPSG:4326',
+ zoom: 12
+ })
+});
diff --git a/old/src/ol/interaction/modifyinteraction.js b/old/src/ol/interaction/modifyinteraction.js
index 692c0cd74d..fdef1b88e7 100644
--- a/old/src/ol/interaction/modifyinteraction.js
+++ b/old/src/ol/interaction/modifyinteraction.js
@@ -252,9 +252,9 @@ ol.interaction.Modify.prototype.removeIndex_ = function(features) {
nodesToRemove.push(node);
}
});
- }
- for (i = nodesToRemove.length - 1; i >= 0; --i) {
- rBush.remove(nodesToRemove[i]);
+ for (i = nodesToRemove.length - 1; i >= 0; --i) {
+ rBush.remove(nodesToRemove[i]);
+ }
}
};
@@ -368,12 +368,6 @@ ol.interaction.Modify.prototype.handleDragStart = function(evt) {
if (!(goog.getUid(node.feature) in distinctFeatures)) {
var feature = node.feature;
distinctFeatures[goog.getUid(feature)] = true;
- var original = new ol.Feature(feature.getAttributes());
- original.setGeometry(feature.getGeometry().clone());
- original.setId(feature.getId());
- original.setOriginal(feature.getOriginal());
- original.setSymbolizers(feature.getSymbolizers());
- feature.setOriginal(original);
}
if (renderIntent == ol.FeatureRenderIntent.TEMPORARY) {
if (ol.coordinate.equals(segment[0], vertex)) {
diff --git a/old/src/ol/parser/ogc/filterparser_v1.js b/old/src/ol/parser/ogc/filterparser_v1.js
index 6a5822ee4f..3d3ff44d55 100644
--- a/old/src/ol/parser/ogc/filterparser_v1.js
+++ b/old/src/ol/parser/ogc/filterparser_v1.js
@@ -648,6 +648,7 @@ ol.parser.ogc.Filter_v1.prototype.setFeatureType = function(featureType) {
ol.parser.ogc.Filter_v1.prototype.setSrsName = function(srsName) {
this.srsName = srsName;
if (goog.isDefAndNotNull(this.gmlParser_)) {
- this.gmlParser_.srsName = this.srsName;
+ this.gmlParser_.applyWriteOptions({},
+ /** @type {ol.parser.GMLWriteOptions} */ ({srsName: srsName}));
}
};
diff --git a/old/src/ol/parser/ogc/gmlparser_v2.js b/old/src/ol/parser/ogc/gmlparser_v2.js
index 837b5d844e..37bdd9d191 100644
--- a/old/src/ol/parser/ogc/gmlparser_v2.js
+++ b/old/src/ol/parser/ogc/gmlparser_v2.js
@@ -54,7 +54,8 @@ ol.parser.ogc.GML_v2 = function(opt_options) {
for (var i = 0; i < numCoordinates; ++i) {
var coord = coordinates[i];
var part = goog.array.concat(coord);
- if (this.axisOrientation.substr(0, 2) !== 'en') {
+ if (goog.isDef(this.axisOrientation) &&
+ this.axisOrientation.substr(0, 2) !== 'en') {
part[0] = coord[1];
part[1] = coord[0];
}
diff --git a/old/src/ol/parser/ogc/versionedparser.exports b/old/src/ol/parser/ogc/versionedparser.exports
new file mode 100644
index 0000000000..8d3189fde9
--- /dev/null
+++ b/old/src/ol/parser/ogc/versionedparser.exports
@@ -0,0 +1 @@
+@exportProperty ol.parser.ogc.Versioned.prototype.getParser
diff --git a/old/src/ol/parser/ogc/wfsparser.exports b/old/src/ol/parser/ogc/wfsparser.exports
new file mode 100644
index 0000000000..14dbb32df3
--- /dev/null
+++ b/old/src/ol/parser/ogc/wfsparser.exports
@@ -0,0 +1,3 @@
+@exportSymbol ol.parser.ogc.WFS
+@exportProperty ol.parser.ogc.WFS_v1.prototype.writeGetFeature
+@exportProperty ol.parser.ogc.WFS_v1.prototype.writeTransaction
diff --git a/old/src/ol/parser/ogc/wfsparser_v1.js b/old/src/ol/parser/ogc/wfsparser_v1.js
index 2fb5f685fa..acc0449c8b 100644
--- a/old/src/ol/parser/ogc/wfsparser_v1.js
+++ b/old/src/ol/parser/ogc/wfsparser_v1.js
@@ -1,31 +1,22 @@
goog.provide('ol.parser.ogc.WFS_v1');
+goog.require('goog.asserts');
goog.require('goog.dom.xml');
+goog.require('ol.expr.Call');
+goog.require('ol.expr.Identifier');
+goog.require('ol.expr.Literal');
+goog.require('ol.geom.Geometry');
goog.require('ol.parser.XML');
-/**
- * @typedef {{featureNS: string,
- featurePrefix: string,
- featureTypes: Array.,
- handle: string,
- outputFormat: string,
- nativeElements: Array.<{
- vendorId: string,
- safeToIgnore: boolean,
- value: string
- }>,
- maxFeatures: number}}
- */
-ol.parser.WFSWriteOptions;
-
-
/**
* @constructor
* @extends {ol.parser.XML}
+ * @param {Object=} opt_options Options which will be set on this object.
*/
-ol.parser.ogc.WFS_v1 = function() {
+ol.parser.ogc.WFS_v1 = function(opt_options) {
this.defaultNamespaceURI = 'http://www.opengis.net/wfs';
+
// TODO set errorProperty
this.readers = {};
this.readers[this.defaultNamespaceURI] = {
@@ -36,8 +27,13 @@ ol.parser.ogc.WFS_v1 = function() {
};
this.writers = {};
this.writers[this.defaultNamespaceURI] = {
+ /**
+ * @param {ol.parser.WFSWriteGetFeatureOptions} options Options.
+ * @return {{node: Node,
+ * options: ol.parser.WFSWriteGetFeatureOptions}} Object.
+ * @this {ol.parser.XML}
+ */
'GetFeature': function(options) {
- options = /** @type {ol.parser.WFSWriteOptions} */(options);
var node = this.createElementNS('wfs:GetFeature');
node.setAttribute('service', 'WFS');
node.setAttribute('version', this.version);
@@ -51,6 +47,9 @@ ol.parser.ogc.WFS_v1 = function() {
if (goog.isDef(options.maxFeatures)) {
node.setAttribute('maxFeatures', options.maxFeatures);
}
+ if (goog.isDef(options.srsName)) {
+ this.setSrsName(options.srsName);
+ }
}
for (var i = 0, ii = options.featureTypes.length; i < ii; i++) {
options.featureType = options.featureTypes[i];
@@ -61,29 +60,41 @@ ol.parser.ogc.WFS_v1 = function() {
'xsi:schemaLocation', this.schemaLocation);
return {node: node, options: options};
},
+ /**
+ * @param {{inserts: Array.,
+ * updates: Array.,
+ * deletes: Array.,
+ * options: ol.parser.WFSWriteTransactionOptions}} obj Object.
+ * @return {Element} Node.
+ * @this {ol.parser.XML}
+ */
'Transaction': function(obj) {
- obj = obj || {};
- var options = /** {ol.parser.WFSWriteOptions} */(obj.options || {});
+ var options = obj.options;
+ this.setFeatureType(options.featureType);
+ this.setFeatureNS(options.featureNS);
+ if (goog.isDef(options.srsName)) {
+ this.setSrsName(options.srsName);
+ }
var node = this.createElementNS('wfs:Transaction');
node.setAttribute('service', 'WFS');
node.setAttribute('version', this.version);
if (goog.isDef(options.handle)) {
node.setAttribute('handle', options.handle);
}
- var i, ii;
- var features = obj.features;
- if (goog.isDefAndNotNull(features)) {
- // TODO implement multi option for geometry types
- var name, feature;
- for (i = 0, ii = features.length; i < ii; ++i) {
- feature = features[i];
- // TODO Update (use feature.getOriginal())
- // TODO Insert and Delete
- if (goog.isDef(name)) {
- this.writeNode(name, {
- feature: feature,
- options: options
- }, null, node);
+ var i, ii, features, feature;
+ var operations = {
+ 'Insert': obj.inserts,
+ 'Update': obj.updates,
+ 'Delete': obj.deletes
+ };
+ for (var name in operations) {
+ features = operations[name];
+ if (!goog.isNull(features)) {
+ // TODO implement multi option for geometry types
+ for (i = 0, ii = features.length; i < ii; ++i) {
+ feature = features[i];
+ this.writeNode(name, {feature: feature, options: options}, null,
+ node);
}
}
}
@@ -94,12 +105,135 @@ ol.parser.ogc.WFS_v1 = function() {
}
return node;
},
+ /**
+ * @param {{vendorId: string, safeToIgnore: boolean, value: string}}
+ * nativeElement Native element.
+ * @return {Node} Node.
+ * @this {ol.parser.XML}
+ */
'Native': function(nativeElement) {
var node = this.createElementNS('wfs:Native');
node.setAttribute('vendorId', nativeElement.vendorId);
node.setAttribute('safeToIgnore', nativeElement.safeToIgnore);
node.appendChild(this.createTextNode(nativeElement.value));
return node;
+ },
+ /**
+ * @param {{feature: ol.Feature,
+ * options: ol.parser.WFSWriteTransactionOptions}} obj Object.
+ * @return {Element} Node.
+ * @this {ol.parser.XML}
+ */
+ 'Insert': function(obj) {
+ var feature = obj.feature;
+ var options = obj.options;
+ var node = this.createElementNS('wfs:Insert');
+ if (goog.isDef(options) && goog.isDef(options.handle)) {
+ this.setAttributeNS(node, this.defaultNamespaceURI, 'handle',
+ options.handle);
+ }
+ if (goog.isDef(options.srsName)) {
+ this.setSrsName(options.srsName);
+ }
+ this.writeNode('_typeName', feature, options.featureNS, node);
+ return node;
+ },
+ /**
+ * @param {{feature: ol.Feature,
+ * options: ol.parser.WFSWriteTransactionOptions}} obj Object.
+ * @return {Element} Node.
+ * @this {ol.parser.XML}
+ */
+ 'Update': function(obj) {
+ var feature = obj.feature;
+ var options = obj.options;
+ var node = this.createElementNS('wfs:Update');
+ this.setAttributeNS(node, this.defaultNamespaceURI, 'typeName',
+ (goog.isDef(options.featureNS) ? options.featurePrefix + ':' : '') +
+ options.featureType);
+ if (goog.isDef(options.handle)) {
+ this.setAttributeNS(node, this.defaultNamespaceURI, 'handle',
+ options.handle);
+ }
+
+ // add in fields
+ var attributes = feature.getAttributes();
+ var attribute;
+ for (var key in attributes) {
+ attribute = attributes[key];
+ // TODO Only add geometries whose values have changed
+ if (goog.isDef(attribute)) {
+ this.writeNode('Property', {name: key, value: attribute}, null, node);
+ }
+ }
+
+ // add feature id filter
+ var fid = feature.getId();
+ goog.asserts.assert(goog.isDef(fid));
+ this.writeNode('Filter', new ol.expr.Call(new ol.expr.Identifier(
+ ol.expr.functions.FID), [new ol.expr.Literal(fid)]),
+ 'http://www.opengis.net/ogc', node);
+
+ return node;
+ },
+ 'Property': function(obj) {
+ var node = this.createElementNS('wfs:Property');
+ this.writeNode('Name', obj.name, null, node);
+ if (!goog.isNull(obj.value)) {
+ this.writeNode('Value', obj.value, null, node);
+ }
+ return node;
+ },
+ /**
+ * @param {string} name Name.
+ * @return {Element} Node.
+ * @this {ol.parser.XML}
+ */
+ 'Name': function(name) {
+ var node = this.createElementNS('wfs:Name');
+ node.appendChild(this.createTextNode(name));
+ return node;
+ },
+ /**
+ * @param {string|number|ol.geom.Geometry} obj Object.
+ * @return {Element} Node.
+ * @this {ol.parser.XML}
+ */
+ 'Value': function(obj) {
+ var node;
+ if (obj instanceof ol.geom.Geometry) {
+ node = this.createElementNS('wfs:Value');
+ node.appendChild(
+ this.getFilterParser().getGmlParser().writeGeometry(obj));
+ } else {
+ node = this.createElementNS('wfs:Value');
+ node.appendChild(this.createTextNode(/** @type {string} */ (obj)));
+ }
+ return node;
+ },
+ /**
+ * @param {{feature: ol.Feature,
+ * options: ol.parser.WFSWriteTransactionOptions}} obj Object.
+ * @return {Element} Node.
+ * @this {ol.parser.XML}
+ */
+ 'Delete': function(obj) {
+ var feature = obj.feature;
+ var options = obj.options;
+ var node = this.createElementNS('wfs:Delete');
+ this.setAttributeNS(node, this.defaultNamespaceURI, 'typeName',
+ (goog.isDef(options.featureNS) ? options.featurePrefix + ':' : '') +
+ options.featureType);
+ if (goog.isDef(options.handle)) {
+ this.setAttributeNS(node, this.defaultNamespaceURI, 'handle',
+ options.handle);
+ }
+ var fid = feature.getId();
+ goog.asserts.assert(goog.isDef(fid));
+ this.writeNode('Filter', new ol.expr.Call(new ol.expr.Identifier(
+ ol.expr.functions.FID), [new ol.expr.Literal(fid)]),
+ 'http://www.opengis.net/ogc', node);
+ return node;
}
};
goog.base(this);
@@ -204,13 +338,27 @@ ol.parser.ogc.WFS_v1.prototype.read = function(data) {
/**
- * @param {Array.} features The features to write out.
- * @param {ol.parser.WFSWriteOptions} options Write options.
+ * @param {ol.parser.WFSWriteGetFeatureOptions} options Options.
+ * @return {string} A serialized WFS GetFeature query.
+ */
+ol.parser.ogc.WFS_v1.prototype.writeGetFeature = function(options) {
+ var root = this.writers[this.defaultNamespaceURI]['GetFeature']
+ .call(this, options);
+ return this.serialize(root);
+};
+
+
+/**
+ * @param {Array.} inserts The features to insert.
+ * @param {Array.} updates The features to update.
+ * @param {Array.} deletes The features to delete.
+ * @param {ol.parser.WFSWriteTransactionOptions} options Write options.
* @return {string} A serialized WFS transaction.
*/
-ol.parser.ogc.WFS_v1.prototype.write = function(features, options) {
- var root = this.writeNode('Transaction', {features: features,
- options: options});
+ol.parser.ogc.WFS_v1.prototype.writeTransaction =
+ function(inserts, updates, deletes, options) {
+ var root = this.writeNode('Transaction', {inserts: inserts,
+ updates: updates, deletes: deletes, options: options});
this.setAttributeNS(
root, 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation', this.schemaLocation);
diff --git a/old/test/spec/ol/parser/ogc/wfs_v1.test.js b/old/test/spec/ol/parser/ogc/wfs_v1.test.js
index 22bf07fc01..69fc103d81 100644
--- a/old/test/spec/ol/parser/ogc/wfs_v1.test.js
+++ b/old/test/spec/ol/parser/ogc/wfs_v1.test.js
@@ -19,17 +19,15 @@ describe('ol.parser.ogc.WFS', function() {
var url = 'spec/ol/parser/ogc/xml/wfs_v1/GetFeature.xml';
afterLoadXml(url, function(xml) {
var p = new ol.parser.ogc.WFS_v1_0_0();
- var output = p.writers[p.defaultNamespaceURI]['GetFeature'].
- apply(p, [{
- featureNS: 'http://www.openplans.org/topp',
- featureTypes: ['states'],
- featurePrefix: 'topp',
- handle: 'handle_g',
- maxFeatures: 1,
- outputFormat: 'json'
- }
- ]);
- expect(goog.dom.xml.loadXml(p.serialize(output))).to.xmleql(xml);
+ var output = p.writeGetFeature({
+ featureNS: 'http://www.openplans.org/topp',
+ featureTypes: ['states'],
+ featurePrefix: 'topp',
+ handle: 'handle_g',
+ maxFeatures: 1,
+ outputFormat: 'json'
+ });
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
done();
});
});
@@ -38,12 +36,44 @@ describe('ol.parser.ogc.WFS', function() {
var url = 'spec/ol/parser/ogc/xml/wfs_v1/Transaction.xml';
afterLoadXml(url, function(xml) {
var p = new ol.parser.ogc.WFS_v1_0_0();
- var output = p.writers[p.defaultNamespaceURI]['Transaction'].
- apply(p, [{
- options: {handle: 'handle_t'}
- }
- ]);
- expect(goog.dom.xml.loadXml(p.serialize(output))).to.xmleql(xml);
+ var output = p.writeTransaction(null, null, null, {handle: 'handle_t'});
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
+ done();
+ });
+ });
+
+ it('handles writing out transactions', function(done) {
+ var url = 'spec/ol/parser/ogc/xml/wfs_v1/TransactionMulti.xml';
+ afterLoadXml(url, function(xml) {
+ var parser = new ol.parser.ogc.WFS_v1_0_0();
+
+ var insertFeature = new ol.Feature({
+ the_geom: new ol.geom.MultiPoint([[1, 2]]),
+ foo: 'bar',
+ nul: null
+ });
+ 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 output = parser.writeTransaction(inserts, updates, deletes, {
+ featureNS: 'http://www.openplans.org/topp',
+ featureType: 'states',
+ featurePrefix: 'topp'
+ });
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
done();
});
});
@@ -52,7 +82,7 @@ describe('ol.parser.ogc.WFS', function() {
var url = 'spec/ol/parser/ogc/xml/wfs_v1/Native.xml';
afterLoadXml(url, function(xml) {
var p = new ol.parser.ogc.WFS_v1_1_0();
- var output = p.write(null, {nativeElements: [{
+ var output = p.writeTransaction(null, null, null, {nativeElements: [{
vendorId: 'ORACLE',
safeToIgnore: true,
value: 'ALTER SESSION ENABLE PARALLEL DML'
@@ -70,14 +100,12 @@ describe('ol.parser.ogc.WFS', function() {
var url = 'spec/ol/parser/ogc/xml/wfs_v1/GetFeatureMultiple.xml';
afterLoadXml(url, function(xml) {
var p = new ol.parser.ogc.WFS_v1_0_0();
- var output = p.writers[p.defaultNamespaceURI]['GetFeature'].
- apply(p, [{
- featureNS: 'http://www.openplans.org/topp',
- featureTypes: ['states', 'cities'],
- featurePrefix: 'topp'
- }
- ]);
- expect(goog.dom.xml.loadXml(p.serialize(output))).to.xmleql(xml);
+ var output = p.writeGetFeature({
+ featureNS: 'http://www.openplans.org/topp',
+ featureTypes: ['states', 'cities'],
+ featurePrefix: 'topp'
+ });
+ expect(goog.dom.xml.loadXml(output)).to.xmleql(xml);
done();
});
});
@@ -87,6 +115,8 @@ describe('ol.parser.ogc.WFS', function() {
});
goog.require('goog.dom.xml');
+goog.require('ol.Feature');
+goog.require('ol.geom.MultiPoint');
goog.require('ol.parser.ogc.WFS');
goog.require('ol.parser.ogc.WFS_v1_0_0');
goog.require('ol.parser.ogc.WFS_v1_1_0');
diff --git a/old/test/spec/ol/parser/ogc/xml/wfs_v1/Transaction.xml b/old/test/spec/ol/parser/ogc/xml/wfs_v1/Transaction.xml
index b147dc07f4..98527bfc2d 100644
--- a/old/test/spec/ol/parser/ogc/xml/wfs_v1/Transaction.xml
+++ b/old/test/spec/ol/parser/ogc/xml/wfs_v1/Transaction.xml
@@ -1 +1 @@
-
+
diff --git a/old/test/spec/ol/parser/ogc/xml/wfs_v1/TransactionMulti.xml b/old/test/spec/ol/parser/ogc/xml/wfs_v1/TransactionMulti.xml
new file mode 100644
index 0000000000..22c0886045
--- /dev/null
+++ b/old/test/spec/ol/parser/ogc/xml/wfs_v1/TransactionMulti.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+ 1,2
+
+
+
+
+ bar
+
+
+
+
+ the_geom
+
+
+
+
+ 1,2
+
+
+
+
+
+
+ foo
+ bar
+
+
+ nul
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc
index 1762bbcb63..33aa022d0b 100644
--- a/src/objectliterals.jsdoc
+++ b/src/objectliterals.jsdoc
@@ -440,6 +440,31 @@
* @property {boolean|undefined} visible Visibility. Default is `true` (visible).
*/
+/**
+ * @typedef {Object} ol.parser.WFSWriteGetFeatureOptions
+ * @property {string} featureNS The namespace URI used for features.
+ * @property {string} featurePrefix The prefix for the feature namespace.
+ * @property {Array.} featureTypes The feature type names.
+ * @property {string|undefined} srsName SRS name. For WFS 1.1.0, this is
+ * required. In WFS 1.0.0, no srsName attribute will be set on geometries
+ * when this is not provided.
+ * @property {string|undefined} handle Handle.
+ * @property {string|undefined} outputFormat Output format.
+ * @property {number} maxFeatures Maximum number of features to fetch.
+ */
+
+/**
+ * @typedef {Object} ol.parser.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.