Accept polygons and flat coordinates in MultiPolygon constructor

This commit is contained in:
ahocevar
2018-07-07 17:31:35 +02:00
parent 0ec0491ef6
commit ce97cee6a6
7 changed files with 59 additions and 90 deletions

View File

@@ -122,11 +122,7 @@ GML3.prototype.readMultiSurface_ = function(node, objectStack) {
const polygons = pushParseAndPop([], const polygons = pushParseAndPop([],
this.MULTISURFACE_PARSERS_, node, objectStack, this); this.MULTISURFACE_PARSERS_, node, objectStack, this);
if (polygons) { if (polygons) {
const multiPolygon = new MultiPolygon(null); return new MultiPolygon(polygons);
multiPolygon.setPolygons(polygons);
return multiPolygon;
} else {
return undefined;
} }
}; };

View File

@@ -337,11 +337,7 @@ GMLBase.prototype.readMultiPolygon = function(node, objectStack) {
/** @type {Array.<module:ol/geom/Polygon>} */ /** @type {Array.<module:ol/geom/Polygon>} */
const polygons = pushParseAndPop([], this.MULTIPOLYGON_PARSERS_, node, objectStack, this); const polygons = pushParseAndPop([], this.MULTIPOLYGON_PARSERS_, node, objectStack, this);
if (polygons) { if (polygons) {
const multiPolygon = new MultiPolygon(null); return new MultiPolygon(polygons);
multiPolygon.setPolygons(polygons);
return multiPolygon;
} else {
return undefined;
} }
}; };

View File

@@ -1108,8 +1108,7 @@ function readMultiGeometry(node, objectStack) {
multiGeometry = new MultiLineString(geometries); multiGeometry = new MultiLineString(geometries);
setCommonGeometryProperties(multiGeometry, geometries); setCommonGeometryProperties(multiGeometry, geometries);
} else if (type == GeometryType.POLYGON) { } else if (type == GeometryType.POLYGON) {
multiGeometry = new MultiPolygon(null); multiGeometry = new MultiPolygon(geometries);
multiGeometry.setPolygons(geometries);
setCommonGeometryProperties(multiGeometry, geometries); setCommonGeometryProperties(multiGeometry, geometries);
} else if (type == GeometryType.GEOMETRY_COLLECTION) { } else if (type == GeometryType.GEOMETRY_COLLECTION) {
multiGeometry = new GeometryCollection(geometries); multiGeometry = new GeometryCollection(geometries);

View File

@@ -311,7 +311,7 @@ MVT.prototype.createFeature_ = function(pbf, rawFeature, opt_options) {
values[this.layerName_] = rawFeature.layer.name; values[this.layerName_] = rawFeature.layer.name;
const flatCoordinates = []; const flatCoordinates = [];
let ends = []; const ends = [];
this.readRawGeometry_(pbf, rawFeature, flatCoordinates, ends); this.readRawGeometry_(pbf, rawFeature, flatCoordinates, ends);
const geometryType = getGeometryType(type, ends.length); const geometryType = getGeometryType(type, ends.length);
@@ -333,8 +333,7 @@ MVT.prototype.createFeature_ = function(pbf, rawFeature, opt_options) {
offset = end; offset = end;
} }
if (endss.length > 1) { if (endss.length > 1) {
ends = endss; geom = new MultiPolygon(flatCoordinates, GeometryLayout.XY, endss);
geom = new MultiPolygon(null);
} else { } else {
geom = new Polygon(flatCoordinates, GeometryLayout.XY, ends); geom = new Polygon(flatCoordinates, GeometryLayout.XY, ends);
} }

View File

@@ -26,11 +26,15 @@ import {quantizeMultiArray} from '../geom/flat/simplify.js';
* *
* @constructor * @constructor
* @extends {module:ol/geom/SimpleGeometry} * @extends {module:ol/geom/SimpleGeometry}
* @param {Array.<Array.<Array.<module:ol/coordinate~Coordinate>>>} coordinates Coordinates. * @param {Array.<Array.<Array.<module:ol/coordinate~Coordinate>>>|Array.<number>} 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 {module:ol/geom/GeometryLayout=} opt_layout Layout.
* @param {Array.<number>} opt_endss Array of ends for internal use with flat
* coordinates.
* @api * @api
*/ */
const MultiPolygon = function(coordinates, opt_layout) { const MultiPolygon = function(coordinates, opt_layout, opt_endss) {
SimpleGeometry.call(this); SimpleGeometry.call(this);
@@ -76,7 +80,33 @@ const MultiPolygon = function(coordinates, opt_layout) {
*/ */
this.orientedFlatCoordinates_ = null; 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 * @api
*/ */
MultiPolygon.prototype.clone = function() { MultiPolygon.prototype.clone = function() {
const multiPolygon = new MultiPolygon(null);
const len = this.endss_.length; const len = this.endss_.length;
const newEndss = new Array(len); const newEndss = new Array(len);
for (let i = 0; i < len; ++i) { for (let i = 0; i < len; ++i) {
newEndss[i] = this.endss_[i].slice(); newEndss[i] = this.endss_[i].slice();
} }
multiPolygon.setFlatCoordinates( return new MultiPolygon(
this.layout, this.flatCoordinates.slice(), newEndss); this.flatCoordinates.slice(), this.layout, newEndss);
return multiPolygon;
}; };
@@ -260,10 +287,7 @@ MultiPolygon.prototype.getSimplifiedGeometryInternal = function(squaredTolerance
this.flatCoordinates, 0, this.endss_, this.stride, this.flatCoordinates, 0, this.endss_, this.stride,
Math.sqrt(squaredTolerance), Math.sqrt(squaredTolerance),
simplifiedFlatCoordinates, 0, simplifiedEndss); simplifiedFlatCoordinates, 0, simplifiedEndss);
const simplifiedMultiPolygon = new MultiPolygon(null); return new MultiPolygon(simplifiedFlatCoordinates, GeometryLayout.XY, simplifiedEndss);
simplifiedMultiPolygon.setFlatCoordinates(
GeometryLayout.XY, simplifiedFlatCoordinates, simplifiedEndss);
return simplifiedMultiPolygon;
}; };
@@ -343,66 +367,27 @@ MultiPolygon.prototype.intersectsExtent = function(extent) {
/** /**
* Set the coordinates of the multipolygon. * Set the coordinates of the multipolygon.
* @param {Array.<Array.<Array.<module:ol/coordinate~Coordinate>>>} coordinates Coordinates. * @param {!Array.<Array.<Array.<module:ol/coordinate~Coordinate>>>} coordinates Coordinates.
* @param {module:ol/geom/GeometryLayout=} opt_layout Layout. * @param {module:ol/geom/GeometryLayout=} opt_layout Layout.
* @override * @override
* @api * @api
*/ */
MultiPolygon.prototype.setCoordinates = function(coordinates, opt_layout) { MultiPolygon.prototype.setCoordinates = function(coordinates, opt_layout) {
if (!coordinates) { this.setLayout(opt_layout, coordinates, 3);
this.setFlatCoordinates(GeometryLayout.XY, null, this.endss_); if (!this.flatCoordinates) {
} else { this.flatCoordinates = [];
this.setLayout(opt_layout, coordinates, 3); }
if (!this.flatCoordinates) { const endss = deflateMultiCoordinatesArray(
this.flatCoordinates = []; this.flatCoordinates, 0, coordinates, this.stride, this.endss_);
} if (endss.length === 0) {
const endss = deflateMultiCoordinatesArray( this.flatCoordinates.length = 0;
this.flatCoordinates, 0, coordinates, this.stride, this.endss_); } else {
if (endss.length === 0) { const lastEnds = endss[endss.length - 1];
this.flatCoordinates.length = 0; this.flatCoordinates.length = lastEnds.length === 0 ?
} else { 0 : lastEnds[lastEnds.length - 1];
const lastEnds = endss[endss.length - 1];
this.flatCoordinates.length = lastEnds.length === 0 ?
0 : lastEnds[lastEnds.length - 1];
}
this.changed();
} }
};
/**
* @param {module:ol/geom/GeometryLayout} layout Layout.
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {Array.<Array.<number>>} endss Endss.
*/
MultiPolygon.prototype.setFlatCoordinates = function(layout, flatCoordinates, endss) {
this.setFlatCoordinatesInternal(layout, flatCoordinates);
this.endss_ = endss;
this.changed(); this.changed();
}; };
/**
* @param {Array.<module:ol/geom/Polygon>} 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; export default MultiPolygon;

View File

@@ -302,8 +302,7 @@ describe('ol.rendering.style.Text', function() {
it('renders text along a MultiPolygon', function(done) { it('renders text along a MultiPolygon', function(done) {
createMap('canvas'); createMap('canvas');
let geom = new Polygon(polygon, 'XY', [polygon.length]); let geom = new Polygon(polygon, 'XY', [polygon.length]);
const multiPolygon = new MultiPolygon(null); const multiPolygon = new MultiPolygon([geom]);
multiPolygon.appendPolygon(geom);
geom = geom.clone(); geom = geom.clone();
geom.translate(0, 30); geom.translate(0, 30);
multiPolygon.appendPolygon(geom); multiPolygon.appendPolygon(geom);

View File

@@ -4,22 +4,17 @@ import Polygon from '../../../../src/ol/geom/Polygon.js';
describe('ol.geom.MultiPolygon', function() { 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() { expect(function() {
return new MultiPolygon(null); return new MultiPolygon(null);
}).not.to.throwException(); }).to.throwException();
}); });
describe('with a null MultiPolygon', function() { describe('with a null MultiPolygon', function() {
let multiPolygon;
beforeEach(function() {
multiPolygon = new MultiPolygon(null);
});
it('can append polygons', function() { it('can append polygons', function() {
multiPolygon.appendPolygon( const multiPolygon = new MultiPolygon([
new Polygon([[[0, 0], [0, 2], [1, 1], [2, 0]]])); new Polygon([[[0, 0], [0, 2], [1, 1], [2, 0]]])]);
expect(multiPolygon.getCoordinates()).to.eql( expect(multiPolygon.getCoordinates()).to.eql(
[[[[0, 0], [0, 2], [1, 1], [2, 0]]]]); [[[[0, 0], [0, 2], [1, 1], [2, 0]]]]);
multiPolygon.appendPolygon( multiPolygon.appendPolygon(