diff --git a/src/ol/format/GML3.js b/src/ol/format/GML3.js index 73288c0f71..78887c527e 100644 --- a/src/ol/format/GML3.js +++ b/src/ol/format/GML3.js @@ -122,11 +122,7 @@ GML3.prototype.readMultiSurface_ = function(node, objectStack) { const polygons = pushParseAndPop([], this.MULTISURFACE_PARSERS_, node, objectStack, this); if (polygons) { - const multiPolygon = new MultiPolygon(null); - multiPolygon.setPolygons(polygons); - return multiPolygon; - } else { - return undefined; + return new MultiPolygon(polygons); } }; diff --git a/src/ol/format/GMLBase.js b/src/ol/format/GMLBase.js index 57044a7adb..4965f4782c 100644 --- a/src/ol/format/GMLBase.js +++ b/src/ol/format/GMLBase.js @@ -337,11 +337,7 @@ GMLBase.prototype.readMultiPolygon = function(node, objectStack) { /** @type {Array.} */ const polygons = pushParseAndPop([], this.MULTIPOLYGON_PARSERS_, node, objectStack, this); if (polygons) { - const multiPolygon = new MultiPolygon(null); - multiPolygon.setPolygons(polygons); - return multiPolygon; - } else { - return undefined; + return new MultiPolygon(polygons); } }; diff --git a/src/ol/format/KML.js b/src/ol/format/KML.js index a9fce973aa..215e93c280 100644 --- a/src/ol/format/KML.js +++ b/src/ol/format/KML.js @@ -1108,8 +1108,7 @@ function readMultiGeometry(node, objectStack) { multiGeometry = new MultiLineString(geometries); setCommonGeometryProperties(multiGeometry, geometries); } else if (type == GeometryType.POLYGON) { - multiGeometry = new MultiPolygon(null); - multiGeometry.setPolygons(geometries); + multiGeometry = new MultiPolygon(geometries); setCommonGeometryProperties(multiGeometry, geometries); } else if (type == GeometryType.GEOMETRY_COLLECTION) { multiGeometry = new GeometryCollection(geometries); diff --git a/src/ol/format/MVT.js b/src/ol/format/MVT.js index 3ce33daeb9..618b5aea81 100644 --- a/src/ol/format/MVT.js +++ b/src/ol/format/MVT.js @@ -311,7 +311,7 @@ MVT.prototype.createFeature_ = function(pbf, rawFeature, opt_options) { values[this.layerName_] = rawFeature.layer.name; const flatCoordinates = []; - let ends = []; + const ends = []; this.readRawGeometry_(pbf, rawFeature, flatCoordinates, ends); const geometryType = getGeometryType(type, ends.length); @@ -333,8 +333,7 @@ MVT.prototype.createFeature_ = function(pbf, rawFeature, opt_options) { offset = end; } if (endss.length > 1) { - ends = endss; - geom = new MultiPolygon(null); + geom = new MultiPolygon(flatCoordinates, GeometryLayout.XY, endss); } else { geom = new Polygon(flatCoordinates, GeometryLayout.XY, ends); } diff --git a/src/ol/geom/MultiPolygon.js b/src/ol/geom/MultiPolygon.js index 365b2e5e4e..6670d922ee 100644 --- a/src/ol/geom/MultiPolygon.js +++ b/src/ol/geom/MultiPolygon.js @@ -26,11 +26,15 @@ import {quantizeMultiArray} from '../geom/flat/simplify.js'; * * @constructor * @extends {module:ol/geom/SimpleGeometry} - * @param {Array.>>} coordinates Coordinates. + * @param {Array.>>|Array.} coordinates + * Coordinates. (For internal use, flat coordinats in combination with + * `opt_layout` and `opt_endss` are also accepted). * @param {module:ol/geom/GeometryLayout=} opt_layout Layout. + * @param {Array.} opt_endss Array of ends for internal use with flat + * coordinates. * @api */ -const MultiPolygon = function(coordinates, opt_layout) { +const MultiPolygon = function(coordinates, opt_layout, opt_endss) { SimpleGeometry.call(this); @@ -76,7 +80,33 @@ const MultiPolygon = function(coordinates, opt_layout) { */ this.orientedFlatCoordinates_ = null; - this.setCoordinates(coordinates, opt_layout); + if (!opt_endss && !Array.isArray(coordinates[0])) { + let layout = this.getLayout(); + const flatCoordinates = []; + const endss = []; + for (let i = 0, ii = coordinates.length; i < ii; ++i) { + const polygon = coordinates[i]; + if (i === 0) { + layout = polygon.getLayout(); + } + const offset = flatCoordinates.length; + const ends = polygon.getEnds(); + for (let j = 0, jj = ends.length; j < jj; ++j) { + ends[j] += offset; + } + extend(flatCoordinates, polygon.getFlatCoordinates()); + endss.push(ends); + } + opt_layout = layout; + coordinates = flatCoordinates; + opt_endss = endss; + } + if (opt_layout !== undefined && opt_endss) { + this.setFlatCoordinatesInternal(opt_layout, coordinates); + this.endss_ = opt_endss; + } else { + this.setCoordinates(coordinates, opt_layout); + } }; @@ -115,17 +145,14 @@ MultiPolygon.prototype.appendPolygon = function(polygon) { * @api */ MultiPolygon.prototype.clone = function() { - const multiPolygon = new MultiPolygon(null); - const len = this.endss_.length; const newEndss = new Array(len); for (let i = 0; i < len; ++i) { newEndss[i] = this.endss_[i].slice(); } - multiPolygon.setFlatCoordinates( - this.layout, this.flatCoordinates.slice(), newEndss); - return multiPolygon; + return new MultiPolygon( + this.flatCoordinates.slice(), this.layout, newEndss); }; @@ -260,10 +287,7 @@ MultiPolygon.prototype.getSimplifiedGeometryInternal = function(squaredTolerance this.flatCoordinates, 0, this.endss_, this.stride, Math.sqrt(squaredTolerance), simplifiedFlatCoordinates, 0, simplifiedEndss); - const simplifiedMultiPolygon = new MultiPolygon(null); - simplifiedMultiPolygon.setFlatCoordinates( - GeometryLayout.XY, simplifiedFlatCoordinates, simplifiedEndss); - return simplifiedMultiPolygon; + return new MultiPolygon(simplifiedFlatCoordinates, GeometryLayout.XY, simplifiedEndss); }; @@ -343,66 +367,27 @@ MultiPolygon.prototype.intersectsExtent = function(extent) { /** * Set the coordinates of the multipolygon. - * @param {Array.>>} coordinates Coordinates. + * @param {!Array.>>} coordinates Coordinates. * @param {module:ol/geom/GeometryLayout=} opt_layout Layout. * @override * @api */ MultiPolygon.prototype.setCoordinates = function(coordinates, opt_layout) { - if (!coordinates) { - this.setFlatCoordinates(GeometryLayout.XY, null, this.endss_); - } else { - this.setLayout(opt_layout, coordinates, 3); - if (!this.flatCoordinates) { - this.flatCoordinates = []; - } - const endss = deflateMultiCoordinatesArray( - this.flatCoordinates, 0, coordinates, this.stride, this.endss_); - if (endss.length === 0) { - this.flatCoordinates.length = 0; - } else { - const lastEnds = endss[endss.length - 1]; - this.flatCoordinates.length = lastEnds.length === 0 ? - 0 : lastEnds[lastEnds.length - 1]; - } - this.changed(); + this.setLayout(opt_layout, coordinates, 3); + if (!this.flatCoordinates) { + this.flatCoordinates = []; + } + const endss = deflateMultiCoordinatesArray( + this.flatCoordinates, 0, coordinates, this.stride, this.endss_); + if (endss.length === 0) { + this.flatCoordinates.length = 0; + } else { + const lastEnds = endss[endss.length - 1]; + this.flatCoordinates.length = lastEnds.length === 0 ? + 0 : lastEnds[lastEnds.length - 1]; } -}; - - -/** - * @param {module:ol/geom/GeometryLayout} layout Layout. - * @param {Array.} flatCoordinates Flat coordinates. - * @param {Array.>} endss Endss. - */ -MultiPolygon.prototype.setFlatCoordinates = function(layout, flatCoordinates, endss) { - this.setFlatCoordinatesInternal(layout, flatCoordinates); - this.endss_ = endss; this.changed(); }; -/** - * @param {Array.} polygons Polygons. - */ -MultiPolygon.prototype.setPolygons = function(polygons) { - let layout = this.getLayout(); - const flatCoordinates = []; - const endss = []; - for (let i = 0, ii = polygons.length; i < ii; ++i) { - const polygon = polygons[i]; - if (i === 0) { - layout = polygon.getLayout(); - } - const offset = flatCoordinates.length; - const ends = polygon.getEnds(); - for (let j = 0, jj = ends.length; j < jj; ++j) { - ends[j] += offset; - } - extend(flatCoordinates, polygon.getFlatCoordinates()); - endss.push(ends); - } - this.setFlatCoordinates(layout, flatCoordinates, endss); -}; - export default MultiPolygon; diff --git a/test/rendering/ol/style/text.test.js b/test/rendering/ol/style/text.test.js index 5d3923fce5..eb6423d7cb 100644 --- a/test/rendering/ol/style/text.test.js +++ b/test/rendering/ol/style/text.test.js @@ -302,8 +302,7 @@ describe('ol.rendering.style.Text', function() { it('renders text along a MultiPolygon', function(done) { createMap('canvas'); let geom = new Polygon(polygon, 'XY', [polygon.length]); - const multiPolygon = new MultiPolygon(null); - multiPolygon.appendPolygon(geom); + const multiPolygon = new MultiPolygon([geom]); geom = geom.clone(); geom.translate(0, 30); multiPolygon.appendPolygon(geom); diff --git a/test/spec/ol/geom/multipolygon.test.js b/test/spec/ol/geom/multipolygon.test.js index 4d8f0fa634..8a7f206295 100644 --- a/test/spec/ol/geom/multipolygon.test.js +++ b/test/spec/ol/geom/multipolygon.test.js @@ -4,22 +4,17 @@ import Polygon from '../../../../src/ol/geom/Polygon.js'; describe('ol.geom.MultiPolygon', function() { - it('can be constructed with a null geometry', function() { + it('cannot be constructed with a null geometry', function() { expect(function() { return new MultiPolygon(null); - }).not.to.throwException(); + }).to.throwException(); }); describe('with a null MultiPolygon', function() { - let multiPolygon; - beforeEach(function() { - multiPolygon = new MultiPolygon(null); - }); - it('can append polygons', function() { - multiPolygon.appendPolygon( - new Polygon([[[0, 0], [0, 2], [1, 1], [2, 0]]])); + const multiPolygon = new MultiPolygon([ + new Polygon([[[0, 0], [0, 2], [1, 1], [2, 0]]])]); expect(multiPolygon.getCoordinates()).to.eql( [[[[0, 0], [0, 2], [1, 1], [2, 0]]]]); multiPolygon.appendPolygon(