diff --git a/src/ol/format/gml2.js b/src/ol/format/gml2.js index 57272acbcf..c57bae5391 100644 --- a/src/ol/format/gml2.js +++ b/src/ol/format/gml2.js @@ -328,10 +328,7 @@ ol.format.GML2.prototype.writeCurveOrLineString_ = function(node, geometry, obje } if (node.nodeName === 'LineString' || node.nodeName === 'LineStringSegment') { - var coordinates = ol.xml.createElementNS(node.namespaceURI, 'coordinates'); - coordinates.setAttribute('decimal', '.'); - coordinates.setAttribute('cs', ','); - coordinates.setAttribute('ts', ' '); + var coordinates = this.createCoordinatesNode_(node.namespaceURI); node.appendChild(coordinates); this.writeCoordinates_(coordinates, geometry, objectStack); } else if (node.nodeName === 'Curve') { @@ -343,6 +340,21 @@ ol.format.GML2.prototype.writeCurveOrLineString_ = function(node, geometry, obje }; +/** + * @param {string} namespaceURI XML namespace. + * @returns {Node} coordinates node. + * @private + */ +ol.format.GML2.prototype.createCoordinatesNode_ = function(namespaceURI) { + var coordinates = ol.xml.createElementNS(namespaceURI, 'coordinates'); + coordinates.setAttribute('decimal', '.'); + coordinates.setAttribute('cs', ','); + coordinates.setAttribute('ts', ' '); + + return coordinates; +}; + + /** * @param {Node} node Node. * @param {ol.geom.LineString|ol.geom.LinearRing} value Geometry. @@ -379,6 +391,79 @@ ol.format.GML2.prototype.writeCurveSegments_ = function(node, line, objectStack) }; +/** + * @param {Node} node Node. + * @param {ol.geom.Polygon} geometry Polygon geometry. + * @param {Array.<*>} objectStack Node stack. + * @private + */ +ol.format.GML2.prototype.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) { + var context = objectStack[objectStack.length - 1]; + var srsName = context['srsName']; + if (node.nodeName !== 'PolygonPatch' && srsName) { + node.setAttribute('srsName', srsName); + } + if (node.nodeName === 'Polygon' || node.nodeName === 'PolygonPatch') { + var rings = geometry.getLinearRings(); + ol.xml.pushSerializeAndPop( + {node: node, srsName: srsName}, + ol.format.GML2.RING_SERIALIZERS_, + this.RING_NODE_FACTORY_, + rings, objectStack, undefined, this); + } else if (node.nodeName === 'Surface') { + var patches = ol.xml.createElementNS(node.namespaceURI, 'patches'); + node.appendChild(patches); + this.writeSurfacePatches_( + patches, geometry, objectStack); + } +}; + + +/** + * @param {*} value Value. + * @param {Array.<*>} objectStack Object stack. + * @param {string=} opt_nodeName Node name. + * @return {Node} Node. + * @private + */ +ol.format.GML2.prototype.RING_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) { + var context = objectStack[objectStack.length - 1]; + var parentNode = context.node; + var exteriorWritten = context['exteriorWritten']; + if (exteriorWritten === undefined) { + context['exteriorWritten'] = true; + } + return ol.xml.createElementNS(parentNode.namespaceURI, + exteriorWritten !== undefined ? 'innerBoundaryIs' : 'outerBoundaryIs'); +}; + + +/** + * @param {Node} node Node. + * @param {ol.geom.Polygon} polygon Polygon geometry. + * @param {Array.<*>} objectStack Node stack. + * @private + */ +ol.format.GML2.prototype.writeSurfacePatches_ = function(node, polygon, objectStack) { + var child = ol.xml.createElementNS(node.namespaceURI, 'PolygonPatch'); + node.appendChild(child); + this.writeSurfaceOrPolygon_(child, polygon, objectStack); +}; + + +/** + * @param {Node} node Node. + * @param {ol.geom.LinearRing} ring LinearRing geometry. + * @param {Array.<*>} objectStack Node stack. + * @private + */ +ol.format.GML2.prototype.writeRing_ = function(node, ring, objectStack) { + var linearRing = ol.xml.createElementNS(node.namespaceURI, 'LinearRing'); + node.appendChild(linearRing); + this.writeLinearRing_(linearRing, ring, objectStack); +}; + + /** * @param {Array.} point Point geometry. * @param {string=} opt_srsName Optional srsName @@ -443,16 +528,14 @@ ol.format.GML2.prototype.writeLineStringOrCurveMember_ = function(node, line, ob * @private */ ol.format.GML2.prototype.writeLinearRing_ = function(node, geometry, objectStack) { -}; - - -/** - * @param {Node} node Node. - * @param {ol.geom.Polygon} geometry Polygon geometry. - * @param {Array.<*>} objectStack Node stack. - * @private - */ -ol.format.GML2.prototype.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) { + var context = objectStack[objectStack.length - 1]; + var srsName = context['srsName']; + if (srsName) { + node.setAttribute('srsName', srsName); + } + var coordinates = this.createCoordinatesNode_(node.namespaceURI); + node.appendChild(coordinates); + this.writeCoordinates_(coordinates, geometry, objectStack); }; @@ -507,3 +590,15 @@ ol.format.GML2.GEOMETRY_SERIALIZERS_ = { ol.format.GML2.prototype.writeEnvelope) } }; + + +/** + * @type {Object.>} + * @private + */ +ol.format.GML2.RING_SERIALIZERS_ = { + 'http://www.opengis.net/gml': { + 'outerBoundaryIs': ol.xml.makeChildAppender(ol.format.GML2.prototype.writeRing_), + 'innerBoundaryIs': ol.xml.makeChildAppender(ol.format.GML2.prototype.writeRing_) + } +}; diff --git a/test/spec/ol/format/gml.test.js b/test/spec/ol/format/gml.test.js index e2147c862c..4d31b029a3 100644 --- a/test/spec/ol/format/gml.test.js +++ b/test/spec/ol/format/gml.test.js @@ -136,12 +136,12 @@ describe('ol.format.GML2', function() { var node; var featureNS = 'http://www.openlayers.org/'; beforeEach(function() { - node = ol.xml.createElementNS(featureNS, 'lines'); + node = ol.xml.createElementNS(featureNS, 'layer'); }); it('can serialize a LineString', function() { var expected = - '' + + '' + ' ' + ' ' + @@ -165,6 +165,37 @@ describe('ol.format.GML2', function() { expect(node).to.xmleql(ol.xml.parse(expected)); }); + + it('can serialize a Polygon', function() { + var expected = + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 2,1.1 4.2,3 6,5.2' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' '; + + var feature = new ol.Feature({ + geometry: new ol.geom.Polygon([[[1.1, 2], [3, 4.2], [5.2, 6]]]) + }); + feature.setId(1); + var objectStack = [{ + featureNS: featureNS, + srsName: 'EPSG:4326' + }]; + format.writeFeatureElement(node, feature, objectStack); + + expect(node).to.xmleql(ol.xml.parse(expected)); + }); }); });