From 717db8b78837b5df3e3643dffa300627c7ea9d65 Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Wed, 26 Feb 2014 15:12:30 +0100 Subject: [PATCH] Add write support for gml:Point --- src/objectliterals.jsdoc | 1 + src/ol/format/gmlformat.js | 105 ++++++++++++++++++++++++++ test/spec/ol/format/gmlformat.test.js | 8 +- 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 55fbe40143..5663a6b486 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -308,6 +308,7 @@ * @typedef {Object} olx.format.GMLOptions * @property {string} featureNS Feature namespace. * @property {string} featureType Feature type to parse. + * @property {string} srsName srsName to use when writing geometries. */ /** diff --git a/src/ol/format/gmlformat.js b/src/ol/format/gmlformat.js index 3a91cf8b77..725a738e5a 100644 --- a/src/ol/format/gmlformat.js +++ b/src/ol/format/gmlformat.js @@ -9,6 +9,8 @@ goog.require('goog.string'); goog.require('ol.Feature'); goog.require('ol.extent'); goog.require('ol.format.XMLFeature'); +goog.require('ol.format.XSD'); +goog.require('ol.geom.Geometry'); goog.require('ol.geom.LineString'); goog.require('ol.geom.MultiLineString'); goog.require('ol.geom.MultiPoint'); @@ -43,6 +45,12 @@ ol.format.GML = function(opt_options) { */ this.featureNS_ = options.featureNS; + /** + * @private + * @type {string} + */ + this.srsName_ = options.srsName; + goog.base(this); }; goog.inherits(ol.format.GML, ol.format.XMLFeature); @@ -973,3 +981,100 @@ ol.format.GML.prototype.readFeaturesFromNode = function(node) { }]; return ol.format.GML.readFeatures_(node, objectStack); }; + + +/** + * @param {Node} node Node. + * @param {ol.geom.Point} value Point geometry. + * @param {Array.<*>} objectStack Node stack. + * @private + */ +ol.format.GML.writePos_ = function(node, value, objectStack) { + var layout = value.getLayout(); + node.setAttribute('srsDimension', + (layout == ol.geom.GeometryLayout.XYZ) ? '3' : '2'); + ol.format.XSD.writeStringTextNode(node, value.getCoordinates().join(' ')); +}; + + +/** + * @const + * @param {*} value Value. + * @param {Array.<*>} objectStack Object stack. + * @param {string=} opt_nodeName Node name. + * @return {Node|undefined} Node. + * @private + */ +ol.format.GML.POS_NODE_FACTORY_ = ol.xml.makeSimpleNodeFactory('pos'); + + +/** + * @type {Object.>} + * @private + */ +ol.format.GML.POS_SERIALIZERS_ = { + 'http://www.opengis.net/gml': { + 'pos': ol.xml.makeChildAppender(ol.format.GML.writePos_), + 'pos_': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode) + } +}; + + +/** + * @param {Node} node Node. + * @param {ol.geom.Point} geometry Point geometry. + * @param {Array.<*>} objectStack Node stack. + * @private + */ +ol.format.GML.writePoint_ = function(node, geometry, objectStack) { + var context = objectStack[objectStack.length - 1]; + goog.asserts.assert(goog.isObject(context)); + var srsName = goog.object.get(context, 'srsName'); + if (goog.isDefAndNotNull(srsName)) { + node.setAttribute('srsName', srsName); + } + ol.xml.pushSerializeAndPop({node: node}, ol.format.GML.POS_SERIALIZERS_, + ol.format.GML.POS_NODE_FACTORY_, [geometry], []); +}; + + +/** + * @type {Object.>} + * @private + */ +ol.format.GML.GEOMETRY_SERIALIZERS_ = { + 'http://www.opengis.net/gml': { + 'Point': ol.xml.makeChildAppender(ol.format.GML.writePoint_) + } +}; + + +/** + * @const + * @param {*} value Value. + * @param {Array.<*>} objectStack Object stack. + * @param {string=} opt_nodeName Node name. + * @return {Node|undefined} Node. + * @private + */ +ol.format.GML.GEOMETRY_NODE_FACTORY_ = function(value, objectStack, + opt_nodeName) { + goog.asserts.assertInstanceof(value, ol.geom.Geometry); + var parentNode = objectStack[objectStack.length - 1].node; + goog.asserts.assert(ol.xml.isNode(parentNode)); + return ol.xml.createElementNS(parentNode.namespaceURI, + value.getType()); +}; + + +/** + * @inheritDoc + */ +ol.format.GML.prototype.writeGeometryNode = function(geometry) { + var geom = ol.xml.createElementNS('http://www.opengis.net/gml', 'geom'); + var context = {node: geom, srsName: this.srsName_}; + ol.xml.pushSerializeAndPop(/** @type {ol.xml.NodeStackItem} */ + (context), ol.format.GML.GEOMETRY_SERIALIZERS_, + ol.format.GML.GEOMETRY_NODE_FACTORY_, [geometry], []); + return geom; +}; diff --git a/test/spec/ol/format/gmlformat.test.js b/test/spec/ol/format/gmlformat.test.js index 6f952fe3ed..c21e4b227a 100644 --- a/test/spec/ol/format/gmlformat.test.js +++ b/test/spec/ol/format/gmlformat.test.js @@ -12,22 +12,24 @@ describe('ol.format.GML', function() { var format; beforeEach(function() { - format = new ol.format.GML(); + format = new ol.format.GML({srsName: 'CRS:84'}); }); describe('#readGeometry', function() { describe('point', function() { - it('can read a point geometry', function() { + it('can read and write a point geometry', function() { var text = '' + - ' 1 2' + + ' 1 2 0' + ''; var g = readGeometry(format, text); expect(g).to.be.an(ol.geom.Point); expect(g.getCoordinates()).to.eql([1, 2, 0]); + var serialized = format.writeGeometry(g); + expect(serialized.firstElementChild).to.xmleql(ol.xml.load(text)); }); });