diff --git a/src/ol/format/gmlformat.js b/src/ol/format/gmlformat.js index a6a8c2cda2..4dc15deff2 100644 --- a/src/ol/format/gmlformat.js +++ b/src/ol/format/gmlformat.js @@ -11,6 +11,7 @@ goog.require('ol.geom.GeometryCollection'); goog.require('ol.geom.LineString'); goog.require('ol.geom.MultiLineString'); goog.require('ol.geom.MultiPoint'); +goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); goog.require('ol.xml'); @@ -136,6 +137,28 @@ ol.format.GML.readMultiLineString_ = function(node, objectStack) { }; +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + * @return {ol.geom.MultiPolygon|undefined} MultiPolygon. + */ +ol.format.GML.readMultiPolygon_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'MultiPolygon'); + var polygons = ol.xml.pushParseAndPop( + /** @type {Array.} */ ([]), + ol.format.GML.MULTIPOLYGON_PARSERS_, node, objectStack); + if (goog.isDefAndNotNull(polygons)) { + var multiPolygon = new ol.geom.MultiPolygon(null); + multiPolygon.setPolygons(polygons); + return multiPolygon; + } else { + return undefined; + } +}; + + /** * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. @@ -162,6 +185,19 @@ ol.format.GML.lineStringMemberParser_ = function(node, objectStack) { }; +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @private + */ +ol.format.GML.polygonMemberParser_ = function(node, objectStack) { + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + goog.asserts.assert(node.localName == 'polygonMember' || + node.localName == 'polygonMembers'); + ol.xml.parse(ol.format.GML.POLYGONMEMBER_PARSERS_, node, objectStack); +}; + + /** * @param {Node} node Node. * @param {Array.<*>} objectStack Object stack. @@ -519,6 +555,7 @@ ol.format.GML.GEOMETRY_PARSERS_ = ol.xml.makeParsersNS( ol.format.GML.readMultiLineString_), 'LinearRing' : ol.xml.makeArrayPusher(ol.format.GML.readLinearRing_), 'Polygon': ol.xml.makeArrayPusher(ol.format.GML.readPolygon_), + 'MultiPolygon': ol.xml.makeArrayPusher(ol.format.GML.readMultiPolygon_), 'Surface': ol.xml.makeArrayPusher(ol.format.GML.readSurface_), 'Curve': ol.xml.makeArrayPusher(ol.format.GML.readCurve_), 'Envelope': ol.xml.makeArrayPusher(ol.format.GML.readEnvelope_) @@ -575,6 +612,20 @@ ol.format.GML.MULTILINESTRING_PARSERS_ = ol.xml.makeParsersNS( }); +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GML.MULTIPOLYGON_PARSERS_ = ol.xml.makeParsersNS( + ol.format.GML.NAMESPACE_URIS_, { + 'polygonMember': ol.xml.makeArrayPusher( + ol.format.GML.polygonMemberParser_), + 'polygonMembers': ol.xml.makeArrayPusher( + ol.format.GML.polygonMemberParser_) + }); + + /** * @const * @type {Object.>} @@ -599,6 +650,18 @@ ol.format.GML.LINESTRINGMEMBER_PARSERS_ = ol.xml.makeParsersNS( }); +/** + * @const + * @type {Object.>} + * @private + */ +ol.format.GML.POLYGONMEMBER_PARSERS_ = ol.xml.makeParsersNS( + ol.format.GML.NAMESPACE_URIS_, { + 'Polygon': ol.xml.makeArrayPusher( + ol.format.GML.readPolygon_) + }); + + /** * @const * @type {Object.>} diff --git a/test/spec/ol/format/gmlformat.test.js b/test/spec/ol/format/gmlformat.test.js index 9b54fa465e..8a83c79f71 100644 --- a/test/spec/ol/format/gmlformat.test.js +++ b/test/spec/ol/format/gmlformat.test.js @@ -247,6 +247,92 @@ describe('ol.format.GML', function() { }); + describe('multipolygon', function() { + + it('can read a singular multipolygon 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' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 1 2 3 2 3 4 1 2' + + ' ' + + ' ' + + ' ' + + ' ' + + ''; + var g = format.readGeometry(text); + expect(g).to.be.an(ol.geom.MultiPolygon); + 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]]], + [[[1, 2, 0], [3, 2, 0], [3, 4, 0], [1, 2, 0]]]]); + }); + + it('can read a plural multipolygon 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' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' 1 2 3 2 3 4 1 2' + + ' ' + + ' ' + + ' ' + + ' ' + + ''; + var g = format.readGeometry(text); + expect(g).to.be.an(ol.geom.MultiPolygon); + 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]]], + [[[1, 2, 0], [3, 2, 0], [3, 4, 0], [1, 2, 0]]]]); + }); + + }); + }); }); @@ -256,5 +342,6 @@ goog.require('ol.format.GML'); goog.require('ol.geom.LineString'); goog.require('ol.geom.MultiPoint'); goog.require('ol.geom.MultiLineString'); +goog.require('ol.geom.MultiPolygon'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon');