diff --git a/src/ol/format/gmlformat.js b/src/ol/format/gmlformat.js index c430399067..78848b537e 100644 --- a/src/ol/format/gmlformat.js +++ b/src/ol/format/gmlformat.js @@ -112,6 +112,46 @@ ol.format.GML.readLineString_ = function(node, objectStack) { }; +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Array.<(Array.)>} flat coordinates. + */ +ol.format.GML.patchesParser_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'patches'); + var result = ol.xml.pushParseAndPop( + /** @type {Array.>} */ ([null]), + ol.format.GML.PATCHES_PARSERS_, node, objectStack); + if (!goog.isDef(result)) { + return null; + } else { + return result; + } +}; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {Array.<(Array.)>} flat coordinates. + */ +ol.format.GML.polygonPatchParser_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'PolygonPatch'); + var result = ol.xml.pushParseAndPop( + /** @type {Array.>} */ ([null]), + ol.format.GML.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack); + if (!goog.isDef(result)) { + return null; + } else { + return result; + } +}; + + /** * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. @@ -221,6 +261,37 @@ ol.format.GML.readPolygon_ = function(node, objectStack) { }; +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {ol.geom.Polygon|undefined} Polygon. + */ +ol.format.GML.readSurface_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'Surface'); + var flatLinearRings = ol.xml.pushParseAndPop( + /** @type {Array.>} */ ([null]), + ol.format.GML.SURFACE_PARSERS_, node, objectStack); + if (goog.isDefAndNotNull(flatLinearRings) && + !goog.isNull(flatLinearRings[0])) { + var polygon = new ol.geom.Polygon(null); + var flatCoordinates = flatLinearRings[0]; + var ends = [flatCoordinates.length]; + var i, ii; + for (i = 1, ii = flatLinearRings.length; i < ii; ++i) { + goog.array.extend(flatCoordinates, flatLinearRings[i]); + ends.push(flatCoordinates.length); + } + polygon.setFlatCoordinates( + ol.geom.GeometryLayout.XYZ, flatCoordinates, ends); + return polygon; + } else { + return undefined; + } +}; + + /** * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. @@ -288,7 +359,8 @@ ol.format.GML.GEOMETRY_PARSERS_ = ol.xml.makeParsersNS( 'Point': ol.xml.makeArrayPusher(ol.format.GML.readPoint_), 'LineString': ol.xml.makeArrayPusher(ol.format.GML.readLineString_), 'LinearRing' : ol.xml.makeArrayPusher(ol.format.GML.readLinearRing_), - 'Polygon': ol.xml.makeArrayPusher(ol.format.GML.readPolygon_) + 'Polygon': ol.xml.makeArrayPusher(ol.format.GML.readPolygon_), + 'Surface': ol.xml.makeArrayPusher(ol.format.GML.readSurface_) }); @@ -316,6 +388,28 @@ ol.format.GML.FLAT_LINEAR_RINGS_PARSERS_ = ol.xml.makeParsersNS( }); +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GML.SURFACE_PARSERS_ = ol.xml.makeParsersNS( + ol.format.GML.NAMESPACE_URIS_, { + 'patches': ol.xml.makeReplacer(ol.format.GML.patchesParser_) + }); + + +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GML.PATCHES_PARSERS_ = ol.xml.makeParsersNS( + ol.format.GML.NAMESPACE_URIS_, { + 'PolygonPatch': ol.xml.makeReplacer(ol.format.GML.polygonPatchParser_) + }); + + /** * @const * @type {Object.>} diff --git a/test/spec/ol/format/gmlformat.test.js b/test/spec/ol/format/gmlformat.test.js index 7809c56672..8f19474913 100644 --- a/test/spec/ol/format/gmlformat.test.js +++ b/test/spec/ol/format/gmlformat.test.js @@ -69,6 +69,41 @@ describe('ol.format.GML', function() { }); + describe('surface', function() { + + it('can read a surface geometry', function() { + var text = + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 1 2 3 2 3 4 1 2' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 2 3 2 5 4 5 2 3' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 3 4 3 6 5 6 3 4' + + ' ' + + ' ' + + ' ' + + ' ' + + ''; + var g = format.readGeometry(text); + expect(g).to.be.an(ol.geom.Polygon); + expect(g.getCoordinates()).to.eql([[[1, 2, 0], [3, 2, 0], [3, 4, 0], + [1, 2, 0]], [[2, 3, 0], [2, 5, 0], [4, 5, 0], [2, 3, 0]], + [[3, 4, 0], [3, 6, 0], [5, 6, 0], [3, 4, 0]]]); + }); + + }); + }); });