Files
openlayers/test/browser/spec/ol/render/webgl/MixedGeometryBatch.test.js

779 lines
26 KiB
JavaScript

import Feature from '../../../../../../src/ol/Feature.js';
import GeometryCollection from '../../../../../../src/ol/geom/GeometryCollection.js';
import LineString from '../../../../../../src/ol/geom/LineString.js';
import LinearRing from '../../../../../../src/ol/geom/LinearRing.js';
import MixedGeometryBatch from '../../../../../../src/ol/render/webgl/MixedGeometryBatch.js';
import MultiLineString from '../../../../../../src/ol/geom/MultiLineString.js';
import MultiPoint from '../../../../../../src/ol/geom/MultiPoint.js';
import MultiPolygon from '../../../../../../src/ol/geom/MultiPolygon.js';
import Point from '../../../../../../src/ol/geom/Point.js';
import Polygon from '../../../../../../src/ol/geom/Polygon.js';
import {getUid} from '../../../../../../src/ol/index.js';
describe('MixedGeometryBatch', function () {
let mixedBatch;
beforeEach(() => {
mixedBatch = new MixedGeometryBatch();
});
describe('#addFeatures', () => {
let features, spy;
beforeEach(() => {
features = [new Feature(), new Feature(), new Feature()];
spy = sinon.spy(mixedBatch, 'addFeature');
mixedBatch.addFeatures(features);
});
it('calls addFeature for each feature', () => {
expect(spy.callCount).to.be(3);
expect(spy.args[0][0]).to.be(features[0]);
expect(spy.args[1][0]).to.be(features[1]);
expect(spy.args[2][0]).to.be(features[2]);
});
});
describe('features with Point geometries', () => {
let geometry1, feature1, geometry2, feature2;
beforeEach(() => {
geometry1 = new Point([0, 1]);
feature1 = new Feature({
geometry: geometry1,
prop1: 'abcd',
prop2: 'efgh',
});
geometry2 = new Point([2, 3]);
feature2 = new Feature({
geometry: geometry2,
prop3: '1234',
prop4: '5678',
});
});
describe('#addFeature', () => {
beforeEach(() => {
mixedBatch.addFeature(feature1);
mixedBatch.addFeature(feature2);
});
it('puts the geometries in the point batch', () => {
const keys = Object.keys(mixedBatch.pointBatch.entries);
const uid1 = getUid(feature1);
const uid2 = getUid(feature2);
expect(keys).to.eql([uid1, uid2]);
expect(mixedBatch.pointBatch.entries[uid1]).to.eql({
feature: feature1,
properties: feature1.getProperties(),
flatCoordss: [[0, 1]],
});
expect(mixedBatch.pointBatch.entries[uid2]).to.eql({
feature: feature2,
properties: feature2.getProperties(),
flatCoordss: [[2, 3]],
});
});
it('computes the geometries count', () => {
expect(mixedBatch.pointBatch.geometriesCount).to.be(2);
});
it('leaves other batches untouched', () => {
expect(Object.keys(mixedBatch.polygonBatch.entries)).to.have.length(0);
expect(Object.keys(mixedBatch.lineStringBatch.entries)).to.have.length(
0
);
});
});
describe('#changeFeature', () => {
beforeEach(() => {
mixedBatch.addFeature(feature1);
mixedBatch.addFeature(feature2);
});
describe('modifying geometry and props', () => {
beforeEach(() => {
feature1.set('prop1', 'changed');
geometry1.setCoordinates([100, 101]);
mixedBatch.changeFeature(feature1);
});
it('updates the modified properties and geometry in the point batch', () => {
const entry = mixedBatch.pointBatch.entries[getUid(feature1)];
expect(entry.properties.prop1).to.eql('changed');
});
it('keeps geometry count the same', () => {
expect(mixedBatch.pointBatch.geometriesCount).to.be(2);
});
});
describe('changing the geometry', () => {
let newGeom;
beforeEach(() => {
newGeom = new Point([40, 41]);
feature1.setGeometry(newGeom);
mixedBatch.changeFeature(feature1);
});
it('updates the geometry in the point batch', () => {
const entry = mixedBatch.pointBatch.entries[getUid(feature1)];
expect(entry.flatCoordss).to.eql([[40, 41]]);
});
it('keeps geometry count the same', () => {
expect(mixedBatch.pointBatch.geometriesCount).to.be(2);
});
});
});
describe('#removeFeature', () => {
beforeEach(() => {
mixedBatch.addFeature(feature1);
mixedBatch.addFeature(feature2);
mixedBatch.removeFeature(feature1);
});
it('clears the entry related to this feature', () => {
const keys = Object.keys(mixedBatch.pointBatch.entries);
expect(keys).to.not.contain(getUid(feature1));
});
it('recompute geometry count', () => {
expect(mixedBatch.pointBatch.geometriesCount).to.be(1);
});
});
});
describe('features with LineString geometries', () => {
let geometry1, feature1, geometry2, feature2;
beforeEach(() => {
geometry1 = new LineString([
[0, 1],
[2, 3],
[4, 5],
[6, 7],
]);
feature1 = new Feature({
geometry: geometry1,
prop1: 'abcd',
prop2: 'efgh',
});
geometry2 = new LineString([
[8, 9],
[10, 11],
[12, 13],
]);
feature2 = new Feature({
geometry: geometry2,
prop3: '1234',
prop4: '5678',
});
});
describe('#addFeature', () => {
beforeEach(() => {
mixedBatch.addFeature(feature1);
mixedBatch.addFeature(feature2);
});
it('puts the geometries in the linestring batch', () => {
const keys = Object.keys(mixedBatch.lineStringBatch.entries);
const uid1 = getUid(feature1);
const uid2 = getUid(feature2);
expect(keys).to.eql([uid1, uid2]);
expect(mixedBatch.lineStringBatch.entries[uid1]).to.eql({
feature: feature1,
properties: feature1.getProperties(),
flatCoordss: [[0, 1, 2, 3, 4, 5, 6, 7]],
verticesCount: 4,
});
expect(mixedBatch.lineStringBatch.entries[uid2]).to.eql({
feature: feature2,
properties: feature2.getProperties(),
flatCoordss: [[8, 9, 10, 11, 12, 13]],
verticesCount: 3,
});
});
it('computes the aggregated metrics on all geoms', () => {
expect(mixedBatch.lineStringBatch.verticesCount).to.be(7);
expect(mixedBatch.lineStringBatch.geometriesCount).to.be(2);
});
it('leaves other batches untouched', () => {
expect(Object.keys(mixedBatch.polygonBatch.entries)).to.have.length(0);
expect(Object.keys(mixedBatch.pointBatch.entries)).to.have.length(0);
});
});
describe('#changeFeature', () => {
beforeEach(() => {
mixedBatch.addFeature(feature1);
mixedBatch.addFeature(feature2);
});
describe('modifying geometry and props', () => {
beforeEach(() => {
feature1.set('prop1', 'changed');
geometry1.appendCoordinate([100, 101]);
geometry1.appendCoordinate([102, 103]);
mixedBatch.changeFeature(feature1);
});
it('updates the modified properties and geometry in the linestring batch', () => {
const entry = mixedBatch.lineStringBatch.entries[getUid(feature1)];
expect(entry.properties.prop1).to.eql('changed');
expect(entry.verticesCount).to.eql(6);
expect(entry.flatCoordss).to.eql([
[0, 1, 2, 3, 4, 5, 6, 7, 100, 101, 102, 103],
]);
});
it('updates the aggregated metrics on all geoms', () => {
expect(mixedBatch.lineStringBatch.verticesCount).to.be(9);
expect(mixedBatch.lineStringBatch.geometriesCount).to.be(2);
});
});
describe('changing the geometry', () => {
let newGeom;
beforeEach(() => {
newGeom = new LineString([
[40, 41],
[42, 43],
]);
feature1.setGeometry(newGeom);
mixedBatch.changeFeature(feature1);
});
it('updates the geometry in the linestring batch', () => {
const entry = mixedBatch.lineStringBatch.entries[getUid(feature1)];
expect(entry.flatCoordss).to.eql([[40, 41, 42, 43]]);
});
it('updates the aggregated metrics on all geoms', () => {
expect(mixedBatch.lineStringBatch.verticesCount).to.be(5);
expect(mixedBatch.lineStringBatch.geometriesCount).to.be(2);
});
});
});
describe('#removeFeature', () => {
beforeEach(() => {
mixedBatch.addFeature(feature1);
mixedBatch.addFeature(feature2);
mixedBatch.removeFeature(feature1);
});
it('clears the entry related to this feature', () => {
const keys = Object.keys(mixedBatch.lineStringBatch.entries);
expect(keys).to.not.contain(getUid(feature1));
});
it('updates the aggregated metrics on all geoms', () => {
expect(mixedBatch.lineStringBatch.verticesCount).to.be(3);
expect(mixedBatch.lineStringBatch.geometriesCount).to.be(1);
});
});
});
describe('features with Polygon geometries', () => {
let geometry1, feature1, geometry2, feature2;
beforeEach(() => {
geometry1 = new Polygon([
[
[0, 1],
[2, 3],
[4, 5],
[6, 7],
],
[
[20, 21],
[22, 23],
[24, 25],
],
]);
feature1 = new Feature({
geometry: geometry1,
prop1: 'abcd',
prop2: 'efgh',
});
geometry2 = new Polygon([
[
[8, 9],
[10, 11],
[12, 13],
],
[
[30, 31],
[32, 33],
[34, 35],
],
[
[40, 41],
[42, 43],
[44, 45],
[46, 47],
],
]);
feature2 = new Feature({
geometry: geometry2,
prop3: '1234',
prop4: '5678',
});
});
describe('#addFeature', () => {
beforeEach(() => {
mixedBatch.addFeature(feature1);
mixedBatch.addFeature(feature2);
});
it('puts the polygons in the polygon batch', () => {
const keys = Object.keys(mixedBatch.polygonBatch.entries);
const uid1 = getUid(feature1);
const uid2 = getUid(feature2);
expect(keys).to.eql([uid1, uid2]);
expect(mixedBatch.polygonBatch.entries[uid1]).to.eql({
feature: feature1,
properties: feature1.getProperties(),
flatCoordss: [[0, 1, 2, 3, 4, 5, 6, 7, 20, 21, 22, 23, 24, 25]],
verticesCount: 7,
ringsCount: 2,
ringsVerticesCounts: [[4, 3]],
});
expect(mixedBatch.polygonBatch.entries[uid2]).to.eql({
feature: feature2,
properties: feature2.getProperties(),
flatCoordss: [
[
8, 9, 10, 11, 12, 13, 30, 31, 32, 33, 34, 35, 40, 41, 42, 43, 44,
45, 46, 47,
],
],
verticesCount: 10,
ringsCount: 3,
ringsVerticesCounts: [[3, 3, 4]],
});
});
it('computes the aggregated metrics on all polygons', () => {
expect(mixedBatch.polygonBatch.verticesCount).to.be(17);
expect(mixedBatch.polygonBatch.geometriesCount).to.be(2);
expect(mixedBatch.polygonBatch.ringsCount).to.be(5);
});
it('puts the linear rings in the linestring batch', () => {
const keys = Object.keys(mixedBatch.lineStringBatch.entries);
expect(keys).to.eql([getUid(feature1), getUid(feature2)]);
expect(mixedBatch.lineStringBatch.entries[getUid(feature1)]).to.eql({
feature: feature1,
properties: feature1.getProperties(),
flatCoordss: [
[0, 1, 2, 3, 4, 5, 6, 7],
[20, 21, 22, 23, 24, 25],
],
verticesCount: 7,
});
expect(mixedBatch.lineStringBatch.entries[getUid(feature2)]).to.eql({
feature: feature2,
properties: feature2.getProperties(),
flatCoordss: [
[8, 9, 10, 11, 12, 13],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45, 46, 47],
],
verticesCount: 10,
});
});
it('computes the aggregated metrics on all linestrings', () => {
expect(mixedBatch.lineStringBatch.verticesCount).to.be(17);
expect(mixedBatch.lineStringBatch.geometriesCount).to.be(5);
});
it('leaves point batch untouched', () => {
expect(Object.keys(mixedBatch.pointBatch.entries)).to.have.length(0);
});
});
describe('#changeFeature', () => {
beforeEach(() => {
mixedBatch.addFeature(feature1);
mixedBatch.addFeature(feature2);
});
describe('modifying geometry and props', () => {
beforeEach(() => {
feature1.set('prop1', 'changed');
geometry1.appendLinearRing(
new LinearRing([
[201, 202],
[203, 204],
[205, 206],
[207, 208],
])
);
mixedBatch.changeFeature(feature1);
});
it('updates the modified properties and geometry in the polygon batch', () => {
const entry = mixedBatch.polygonBatch.entries[getUid(feature1)];
expect(entry.properties.prop1).to.eql('changed');
expect(entry.verticesCount).to.eql(11);
expect(entry.ringsCount).to.eql(3);
expect(entry.ringsVerticesCounts).to.eql([[4, 3, 4]]);
});
it('updates the aggregated metrics on all geoms', () => {
expect(mixedBatch.polygonBatch.verticesCount).to.be(21);
expect(mixedBatch.polygonBatch.geometriesCount).to.be(2);
expect(mixedBatch.polygonBatch.ringsCount).to.be(6);
});
});
describe('changing the geometry', () => {
let newGeom;
beforeEach(() => {
newGeom = new Polygon([
[
[201, 202],
[203, 204],
[205, 206],
[207, 208],
],
]);
feature1.setGeometry(newGeom);
mixedBatch.changeFeature(feature1);
});
it('updates the geometry in the polygon batch', () => {
const entry = mixedBatch.polygonBatch.entries[getUid(feature1)];
expect(entry.feature).to.be(feature1);
expect(entry.verticesCount).to.eql(4);
expect(entry.ringsCount).to.eql(1);
expect(entry.ringsVerticesCounts).to.eql([[4]]);
expect(entry.flatCoordss).to.eql([
[201, 202, 203, 204, 205, 206, 207, 208],
]);
});
it('updates the aggregated metrics on all geoms', () => {
expect(mixedBatch.polygonBatch.verticesCount).to.be(14);
expect(mixedBatch.polygonBatch.geometriesCount).to.be(2);
expect(mixedBatch.polygonBatch.ringsCount).to.be(4);
});
});
});
describe('#removeFeature', () => {
beforeEach(() => {
mixedBatch.addFeature(feature1);
mixedBatch.addFeature(feature2);
mixedBatch.removeFeature(feature1);
});
it('clears the entry related to this feature', () => {
const keys = Object.keys(mixedBatch.polygonBatch.entries);
expect(keys).to.not.contain(getUid(feature1));
});
it('updates the aggregated metrics on all geoms', () => {
expect(mixedBatch.polygonBatch.verticesCount).to.be(10);
expect(mixedBatch.polygonBatch.geometriesCount).to.be(1);
expect(mixedBatch.polygonBatch.ringsCount).to.be(3);
});
});
});
describe('feature with nested geometries (collection, multi)', () => {
let feature, geomCollection, multiPolygon, multiPoint, multiLine;
beforeEach(() => {
multiPoint = new MultiPoint([
[101, 102],
[201, 202],
[301, 302],
]);
multiLine = new MultiLineString([
[
[0, 1],
[2, 3],
[4, 5],
[6, 7],
],
[
[8, 9],
[10, 11],
[12, 13],
],
]);
multiPolygon = new MultiPolygon([
[
[
[0, 1],
[2, 3],
[4, 5],
[6, 7],
],
[
[20, 21],
[22, 23],
[24, 25],
],
],
[
[
[8, 9],
[10, 11],
[12, 13],
],
[
[30, 31],
[32, 33],
[34, 35],
],
[
[40, 41],
[42, 43],
[44, 45],
[46, 47],
],
],
]);
geomCollection = new GeometryCollection([
multiPolygon,
multiLine,
multiPoint,
]);
feature = new Feature({
geometry: geomCollection,
prop3: '1234',
prop4: '5678',
});
});
describe('#addFeature', () => {
beforeEach(() => {
mixedBatch.addFeature(feature);
});
it('puts the polygons in the polygon batch', () => {
const uid = getUid(feature);
expect(mixedBatch.polygonBatch.entries[uid]).to.eql({
feature: feature,
properties: feature.getProperties(),
flatCoordss: [
[0, 1, 2, 3, 4, 5, 6, 7, 20, 21, 22, 23, 24, 25],
[
8, 9, 10, 11, 12, 13, 30, 31, 32, 33, 34, 35, 40, 41, 42, 43, 44,
45, 46, 47,
],
],
verticesCount: 17,
ringsCount: 5,
ringsVerticesCounts: [
[4, 3],
[3, 3, 4],
],
});
});
it('puts the polygon rings and linestrings in the linestring batch', () => {
const uid = getUid(feature);
expect(mixedBatch.lineStringBatch.entries[uid]).to.eql({
feature: feature,
properties: feature.getProperties(),
flatCoordss: [
[0, 1, 2, 3, 4, 5, 6, 7],
[20, 21, 22, 23, 24, 25],
[8, 9, 10, 11, 12, 13],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45, 46, 47],
[0, 1, 2, 3, 4, 5, 6, 7],
[8, 9, 10, 11, 12, 13],
],
verticesCount: 24,
});
});
it('puts the points in the linestring batch', () => {
const uid = getUid(feature);
expect(mixedBatch.pointBatch.entries[uid]).to.eql({
feature: feature,
properties: feature.getProperties(),
flatCoordss: [
[101, 102],
[201, 202],
[301, 302],
],
});
});
it('computes the aggregated metrics on all polygons', () => {
expect(mixedBatch.polygonBatch.verticesCount).to.be(17);
expect(mixedBatch.polygonBatch.geometriesCount).to.be(2);
expect(mixedBatch.polygonBatch.ringsCount).to.be(5);
});
it('computes the aggregated metrics on all linestring', () => {
expect(mixedBatch.lineStringBatch.verticesCount).to.be(24);
expect(mixedBatch.lineStringBatch.geometriesCount).to.be(7);
});
it('computes the aggregated metrics on all points', () => {
expect(mixedBatch.pointBatch.geometriesCount).to.be(3);
});
});
describe('#changeFeature', () => {
beforeEach(() => {
mixedBatch.addFeature(feature);
});
describe('modifying geometry', () => {
beforeEach(() => {
multiLine.appendLineString(
new LineString([
[500, 501],
[502, 503],
[504, 505],
[506, 507],
])
);
multiPolygon.appendPolygon(
new Polygon([
[
[201, 202],
[203, 204],
[205, 206],
[207, 208],
[209, 210],
],
])
);
mixedBatch.changeFeature(feature);
});
it('updates the geometries in the polygon batch', () => {
const entry = mixedBatch.polygonBatch.entries[getUid(feature)];
expect(entry).to.eql({
feature: feature,
properties: feature.getProperties(),
flatCoordss: [
[0, 1, 2, 3, 4, 5, 6, 7, 20, 21, 22, 23, 24, 25],
[
8, 9, 10, 11, 12, 13, 30, 31, 32, 33, 34, 35, 40, 41, 42, 43,
44, 45, 46, 47,
],
[201, 202, 203, 204, 205, 206, 207, 208, 209, 210],
],
verticesCount: 22,
ringsCount: 6,
ringsVerticesCounts: [[4, 3], [3, 3, 4], [5]],
});
});
it('updates the geometries in the linestring batch', () => {
const entry = mixedBatch.lineStringBatch.entries[getUid(feature)];
expect(entry).to.eql({
feature: feature,
properties: feature.getProperties(),
flatCoordss: [
[0, 1, 2, 3, 4, 5, 6, 7],
[20, 21, 22, 23, 24, 25],
[8, 9, 10, 11, 12, 13],
[30, 31, 32, 33, 34, 35],
[40, 41, 42, 43, 44, 45, 46, 47],
[201, 202, 203, 204, 205, 206, 207, 208, 209, 210],
[0, 1, 2, 3, 4, 5, 6, 7],
[8, 9, 10, 11, 12, 13],
[500, 501, 502, 503, 504, 505, 506, 507],
],
verticesCount: 33,
});
});
it('updates the aggregated metrics on the polygon batch', () => {
expect(mixedBatch.polygonBatch.verticesCount).to.be(22);
expect(mixedBatch.polygonBatch.geometriesCount).to.be(3);
expect(mixedBatch.polygonBatch.ringsCount).to.be(6);
});
it('updates the aggregated metrics on the linestring batch', () => {
expect(mixedBatch.lineStringBatch.verticesCount).to.be(33);
expect(mixedBatch.lineStringBatch.geometriesCount).to.be(9);
});
});
describe('changing the geometry', () => {
beforeEach(() => {
feature.setGeometry(
new Polygon([
[
[201, 202],
[203, 204],
[205, 206],
[207, 208],
],
])
);
mixedBatch.changeFeature(feature);
});
it('updates the geometries in the polygon batch', () => {
const entry = mixedBatch.polygonBatch.entries[getUid(feature)];
expect(entry).to.eql({
feature: feature,
properties: feature.getProperties(),
flatCoordss: [[201, 202, 203, 204, 205, 206, 207, 208]],
verticesCount: 4,
ringsCount: 1,
ringsVerticesCounts: [[4]],
});
});
it('updates the geometries in the linestring batch', () => {
const entry = mixedBatch.lineStringBatch.entries[getUid(feature)];
expect(entry).to.eql({
feature: feature,
properties: feature.getProperties(),
flatCoordss: [[201, 202, 203, 204, 205, 206, 207, 208]],
verticesCount: 4,
});
});
it('updates the aggregated metrics on the polygon batch', () => {
expect(mixedBatch.polygonBatch.verticesCount).to.be(4);
expect(mixedBatch.polygonBatch.geometriesCount).to.be(1);
expect(mixedBatch.polygonBatch.ringsCount).to.be(1);
});
it('updates the aggregated metrics on the linestring batch', () => {
expect(mixedBatch.lineStringBatch.verticesCount).to.be(4);
expect(mixedBatch.lineStringBatch.geometriesCount).to.be(1);
});
it('updates the aggregated metrics on the point batch', () => {
const keys = Object.keys(mixedBatch.pointBatch.entries);
expect(keys).to.not.contain(getUid(feature));
expect(mixedBatch.pointBatch.geometriesCount).to.be(0);
});
});
});
describe('#removeFeature', () => {
beforeEach(() => {
mixedBatch.addFeature(feature);
mixedBatch.removeFeature(feature);
});
it('clears all entries in the polygon batch', () => {
const keys = Object.keys(mixedBatch.polygonBatch.entries);
expect(keys).to.have.length(0);
expect(mixedBatch.polygonBatch.verticesCount).to.be(0);
expect(mixedBatch.polygonBatch.geometriesCount).to.be(0);
expect(mixedBatch.polygonBatch.ringsCount).to.be(0);
});
it('clears all entries in the linestring batch', () => {
const keys = Object.keys(mixedBatch.lineStringBatch.entries);
expect(keys).to.have.length(0);
expect(mixedBatch.lineStringBatch.verticesCount).to.be(0);
expect(mixedBatch.lineStringBatch.geometriesCount).to.be(0);
});
it('clears all entries in the point batch', () => {
const keys = Object.keys(mixedBatch.pointBatch.entries);
expect(keys).to.have.length(0);
expect(mixedBatch.pointBatch.geometriesCount).to.be(0);
});
});
});
describe('#clear', () => {
beforeEach(() => {
const feature1 = new Feature(
new Polygon([
[
[201, 202],
[203, 204],
[205, 206],
[207, 208],
],
])
);
const feature2 = new Feature(new Point([201, 202]));
mixedBatch.addFeature(feature1);
mixedBatch.addFeature(feature2);
mixedBatch.clear();
});
it('clears polygon batch', () => {
expect(Object.keys(mixedBatch.polygonBatch.entries)).to.have.length(0);
expect(mixedBatch.polygonBatch.geometriesCount).to.be(0);
expect(mixedBatch.polygonBatch.verticesCount).to.be(0);
expect(mixedBatch.polygonBatch.ringsCount).to.be(0);
});
it('clears linestring batch', () => {
expect(Object.keys(mixedBatch.lineStringBatch.entries)).to.have.length(0);
expect(mixedBatch.lineStringBatch.geometriesCount).to.be(0);
expect(mixedBatch.lineStringBatch.verticesCount).to.be(0);
});
it('clears point batch', () => {
expect(Object.keys(mixedBatch.pointBatch.entries)).to.have.length(0);
expect(mixedBatch.pointBatch.geometriesCount).to.be(0);
});
});
});