ol 7.0.0-dev.1658443472213 → 7.0.0-dev.1658733468997
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Overlay.d.ts +3 -25
- package/Overlay.d.ts.map +1 -1
- package/Overlay.js +3 -25
- package/Overlay.js.map +1 -1
- package/package.json +2 -1
- package/render/webgl/BatchRenderer.d.ts +92 -0
- package/render/webgl/BatchRenderer.d.ts.map +1 -0
- package/render/webgl/BatchRenderer.js +165 -0
- package/render/webgl/BatchRenderer.js.map +1 -0
- package/render/webgl/LineStringBatchRenderer.d.ts +27 -0
- package/render/webgl/LineStringBatchRenderer.d.ts.map +1 -0
- package/render/webgl/LineStringBatchRenderer.js +114 -0
- package/render/webgl/LineStringBatchRenderer.js.map +1 -0
- package/render/webgl/MixedGeometryBatch.d.ts +306 -0
- package/render/webgl/MixedGeometryBatch.d.ts.map +1 -0
- package/render/webgl/MixedGeometryBatch.js +342 -0
- package/render/webgl/MixedGeometryBatch.js.map +1 -0
- package/render/webgl/PointBatchRenderer.d.ts +26 -0
- package/render/webgl/PointBatchRenderer.d.ts.map +1 -0
- package/render/webgl/PointBatchRenderer.js +102 -0
- package/render/webgl/PointBatchRenderer.js.map +1 -0
- package/render/webgl/PolygonBatchRenderer.d.ts +25 -0
- package/render/webgl/PolygonBatchRenderer.d.ts.map +1 -0
- package/render/webgl/PolygonBatchRenderer.js +110 -0
- package/render/webgl/PolygonBatchRenderer.js.map +1 -0
- package/render/webgl/constants.d.ts +43 -0
- package/render/webgl/constants.d.ts.map +1 -0
- package/render/webgl/constants.js +26 -0
- package/render/webgl/constants.js.map +1 -0
- package/render/webgl/utils.d.ts +76 -0
- package/render/webgl/utils.d.ts.map +1 -0
- package/render/webgl/utils.js +257 -0
- package/render/webgl/utils.js.map +1 -0
- package/renderer/webgl/Layer.d.ts +0 -98
- package/renderer/webgl/Layer.d.ts.map +1 -1
- package/renderer/webgl/Layer.js +0 -134
- package/renderer/webgl/Layer.js.map +1 -1
- package/renderer/webgl/PointsLayer.d.ts +4 -1
- package/renderer/webgl/PointsLayer.d.ts.map +1 -1
- package/renderer/webgl/PointsLayer.js +15 -8
- package/renderer/webgl/PointsLayer.js.map +1 -1
- package/renderer/webgl/TileLayer.js +1 -1
- package/renderer/webgl/TileLayer.js.map +1 -1
- package/renderer/webgl/VectorLayer.d.ts +142 -0
- package/renderer/webgl/VectorLayer.d.ts.map +1 -0
- package/renderer/webgl/VectorLayer.js +304 -0
- package/renderer/webgl/VectorLayer.js.map +1 -0
- package/renderer/webgl/shaders.d.ts +43 -0
- package/renderer/webgl/shaders.d.ts.map +1 -0
- package/renderer/webgl/shaders.js +53 -0
- package/renderer/webgl/shaders.js.map +1 -0
- package/src/Overlay.js +3 -25
- package/src/render/webgl/BatchRenderer.js +201 -0
- package/src/render/webgl/LineStringBatchRenderer.js +116 -0
- package/src/render/webgl/MixedGeometryBatch.js +364 -0
- package/src/render/webgl/PointBatchRenderer.js +97 -0
- package/src/render/webgl/PolygonBatchRenderer.js +117 -0
- package/src/render/webgl/constants.js +27 -0
- package/src/render/webgl/utils.js +351 -0
- package/src/renderer/webgl/Layer.js +0 -160
- package/src/renderer/webgl/PointsLayer.js +16 -12
- package/src/renderer/webgl/TileLayer.js +1 -1
- package/src/renderer/webgl/VectorLayer.js +409 -0
- package/src/renderer/webgl/shaders.js +198 -0
- package/src/webgl/Helper.js +30 -45
- package/src/worker/webgl.js +1 -1
- package/util.js +1 -1
- package/webgl/Helper.d.ts +17 -25
- package/webgl/Helper.d.ts.map +1 -1
- package/webgl/Helper.js +29 -43
- package/webgl/Helper.js.map +1 -1
- package/worker/webgl.js +1 -1
- package/worker/webgl.js.map +1 -1
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ol/render/webgl/BatchRenderer
|
|
3
|
+
*/
|
|
4
|
+
import {WebGLWorkerMessageType} from './constants.js';
|
|
5
|
+
import {abstract} from '../../util.js';
|
|
6
|
+
import {
|
|
7
|
+
create as createTransform,
|
|
8
|
+
makeInverse as makeInverseTransform,
|
|
9
|
+
multiply as multiplyTransform,
|
|
10
|
+
translate as translateTransform,
|
|
11
|
+
} from '../../transform.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {Object} CustomAttribute A description of a custom attribute to be passed on to the GPU, with a value different
|
|
15
|
+
* for each feature.
|
|
16
|
+
* @property {string} name Attribute name.
|
|
17
|
+
* @property {function(import("../../Feature").default):number} callback This callback computes the numerical value of the
|
|
18
|
+
* attribute for a given feature.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
let workerMessageCounter = 0;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @classdesc Abstract class for batch renderers.
|
|
25
|
+
* Batch renderers are meant to render the geometries contained in a {@link module:ol/render/webgl/GeometryBatch}
|
|
26
|
+
* instance. They are responsible for generating render instructions and transforming them into WebGL buffers.
|
|
27
|
+
*/
|
|
28
|
+
class AbstractBatchRenderer {
|
|
29
|
+
/**
|
|
30
|
+
* @param {import("../../webgl/Helper.js").default} helper WebGL helper instance
|
|
31
|
+
* @param {Worker} worker WebGL worker instance
|
|
32
|
+
* @param {string} vertexShader Vertex shader
|
|
33
|
+
* @param {string} fragmentShader Fragment shader
|
|
34
|
+
* @param {Array<CustomAttribute>} customAttributes List of custom attributes
|
|
35
|
+
*/
|
|
36
|
+
constructor(helper, worker, vertexShader, fragmentShader, customAttributes) {
|
|
37
|
+
/**
|
|
38
|
+
* @type {import("../../webgl/Helper.js").default}
|
|
39
|
+
* @private
|
|
40
|
+
*/
|
|
41
|
+
this.helper_ = helper;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @type {Worker}
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
this.worker_ = worker;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @type {WebGLProgram}
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
this.program_ = this.helper_.getProgram(fragmentShader, vertexShader);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* A list of attributes used by the renderer.
|
|
57
|
+
* @type {Array<import('../../webgl/Helper.js').AttributeDescription>}
|
|
58
|
+
* @protected
|
|
59
|
+
*/
|
|
60
|
+
this.attributes = [];
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @type {Array<CustomAttribute>}
|
|
64
|
+
* @protected
|
|
65
|
+
*/
|
|
66
|
+
this.customAttributes = customAttributes;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Rebuild rendering instructions and webgl buffers based on the provided frame state
|
|
71
|
+
* Note: this is a costly operation.
|
|
72
|
+
* @param {import("./MixedGeometryBatch.js").GeometryBatch} batch Geometry batch
|
|
73
|
+
* @param {import("../../PluggableMap").FrameState} frameState Frame state.
|
|
74
|
+
* @param {import("../../geom/Geometry.js").Type} geometryType Geometry type
|
|
75
|
+
* @param {function(): void} callback Function called once the render buffers are updated
|
|
76
|
+
*/
|
|
77
|
+
rebuild(batch, frameState, geometryType, callback) {
|
|
78
|
+
// store transform for rendering instructions
|
|
79
|
+
batch.renderInstructionsTransform = this.helper_.makeProjectionTransform(
|
|
80
|
+
frameState,
|
|
81
|
+
createTransform()
|
|
82
|
+
);
|
|
83
|
+
this.generateRenderInstructions(batch);
|
|
84
|
+
this.generateBuffers_(batch, geometryType, callback);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Render the geometries in the batch. This will also update the current transform used for rendering according to
|
|
89
|
+
* the invert transform of the webgl buffers
|
|
90
|
+
* @param {import("./MixedGeometryBatch.js").GeometryBatch} batch Geometry batch
|
|
91
|
+
* @param {import("../../transform.js").Transform} currentTransform Transform
|
|
92
|
+
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
|
|
93
|
+
* @param {number} offsetX X offset
|
|
94
|
+
*/
|
|
95
|
+
render(batch, currentTransform, frameState, offsetX) {
|
|
96
|
+
// multiply the current projection transform with the invert of the one used to fill buffers
|
|
97
|
+
this.helper_.makeProjectionTransform(frameState, currentTransform);
|
|
98
|
+
translateTransform(currentTransform, offsetX, 0);
|
|
99
|
+
multiplyTransform(currentTransform, batch.invertVerticesBufferTransform);
|
|
100
|
+
|
|
101
|
+
// enable program, buffers and attributes
|
|
102
|
+
this.helper_.useProgram(this.program_, frameState);
|
|
103
|
+
this.helper_.bindBuffer(batch.verticesBuffer);
|
|
104
|
+
this.helper_.bindBuffer(batch.indicesBuffer);
|
|
105
|
+
this.helper_.enableAttributes(this.attributes);
|
|
106
|
+
|
|
107
|
+
const renderCount = batch.indicesBuffer.getSize();
|
|
108
|
+
this.helper_.drawElements(0, renderCount);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Rebuild rendering instructions based on the provided frame state
|
|
113
|
+
* This is specific to the geometry type and has to be implemented by subclasses.
|
|
114
|
+
* @param {import("./MixedGeometryBatch.js").GeometryBatch} batch Geometry batch
|
|
115
|
+
* @protected
|
|
116
|
+
*/
|
|
117
|
+
generateRenderInstructions(batch) {
|
|
118
|
+
abstract();
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Rebuild internal webgl buffers for rendering based on the current rendering instructions;
|
|
123
|
+
* This is asynchronous: webgl buffers wil _not_ be updated right away
|
|
124
|
+
* @param {import("./MixedGeometryBatch.js").GeometryBatch} batch Geometry batch
|
|
125
|
+
* @param {import("../../geom/Geometry.js").Type} geometryType Geometry type
|
|
126
|
+
* @param {function(): void} callback Function called once the render buffers are updated
|
|
127
|
+
* @private
|
|
128
|
+
*/
|
|
129
|
+
generateBuffers_(batch, geometryType, callback) {
|
|
130
|
+
const messageId = workerMessageCounter++;
|
|
131
|
+
|
|
132
|
+
let messageType;
|
|
133
|
+
switch (geometryType) {
|
|
134
|
+
case 'Polygon':
|
|
135
|
+
messageType = WebGLWorkerMessageType.GENERATE_POLYGON_BUFFERS;
|
|
136
|
+
break;
|
|
137
|
+
case 'Point':
|
|
138
|
+
messageType = WebGLWorkerMessageType.GENERATE_POINT_BUFFERS;
|
|
139
|
+
break;
|
|
140
|
+
case 'LineString':
|
|
141
|
+
messageType = WebGLWorkerMessageType.GENERATE_LINE_STRING_BUFFERS;
|
|
142
|
+
break;
|
|
143
|
+
default:
|
|
144
|
+
// pass
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** @type {import('./constants.js').WebGLWorkerGenerateBuffersMessage} */
|
|
148
|
+
const message = {
|
|
149
|
+
id: messageId,
|
|
150
|
+
type: messageType,
|
|
151
|
+
renderInstructions: batch.renderInstructions.buffer,
|
|
152
|
+
renderInstructionsTransform: batch.renderInstructionsTransform,
|
|
153
|
+
customAttributesCount: this.customAttributes.length,
|
|
154
|
+
};
|
|
155
|
+
this.worker_.postMessage(message, [batch.renderInstructions.buffer]);
|
|
156
|
+
|
|
157
|
+
// leave ownership of render instructions
|
|
158
|
+
batch.renderInstructions = null;
|
|
159
|
+
|
|
160
|
+
const handleMessage =
|
|
161
|
+
/**
|
|
162
|
+
* @param {*} event Event.
|
|
163
|
+
* @this {AbstractBatchRenderer}
|
|
164
|
+
*/
|
|
165
|
+
function (event) {
|
|
166
|
+
const received = event.data;
|
|
167
|
+
|
|
168
|
+
// this is not the response to our request: skip
|
|
169
|
+
if (received.id !== messageId) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// we've received our response: stop listening
|
|
174
|
+
this.worker_.removeEventListener('message', handleMessage);
|
|
175
|
+
|
|
176
|
+
// store transform & invert transform for webgl buffers
|
|
177
|
+
batch.verticesBufferTransform = received.renderInstructionsTransform;
|
|
178
|
+
makeInverseTransform(
|
|
179
|
+
batch.invertVerticesBufferTransform,
|
|
180
|
+
batch.verticesBufferTransform
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
// copy & flush received buffers to GPU
|
|
184
|
+
batch.verticesBuffer.fromArrayBuffer(received.vertexBuffer);
|
|
185
|
+
this.helper_.flushBufferData(batch.verticesBuffer);
|
|
186
|
+
batch.indicesBuffer.fromArrayBuffer(received.indexBuffer);
|
|
187
|
+
this.helper_.flushBufferData(batch.indicesBuffer);
|
|
188
|
+
|
|
189
|
+
// take back ownership of the render instructions for further use
|
|
190
|
+
batch.renderInstructions = new Float32Array(
|
|
191
|
+
received.renderInstructions
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
callback();
|
|
195
|
+
}.bind(this);
|
|
196
|
+
|
|
197
|
+
this.worker_.addEventListener('message', handleMessage);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export default AbstractBatchRenderer;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ol/render/webgl/LineStringBatchRenderer
|
|
3
|
+
*/
|
|
4
|
+
import AbstractBatchRenderer from './BatchRenderer.js';
|
|
5
|
+
import {AttributeType} from '../../webgl/Helper.js';
|
|
6
|
+
import {transform2D} from '../../geom/flat/transform.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Names of attributes made available to the vertex shader.
|
|
10
|
+
* Please note: changing these *will* break custom shaders!
|
|
11
|
+
* @enum {string}
|
|
12
|
+
*/
|
|
13
|
+
export const Attributes = {
|
|
14
|
+
SEGMENT_START: 'a_segmentStart',
|
|
15
|
+
SEGMENT_END: 'a_segmentEnd',
|
|
16
|
+
PARAMETERS: 'a_parameters',
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
class LineStringBatchRenderer extends AbstractBatchRenderer {
|
|
20
|
+
/**
|
|
21
|
+
* @param {import("../../webgl/Helper.js").default} helper WebGL helper instance
|
|
22
|
+
* @param {Worker} worker WebGL worker instance
|
|
23
|
+
* @param {string} vertexShader Vertex shader
|
|
24
|
+
* @param {string} fragmentShader Fragment shader
|
|
25
|
+
* @param {Array<import('./BatchRenderer.js').CustomAttribute>} customAttributes List of custom attributes
|
|
26
|
+
*/
|
|
27
|
+
constructor(helper, worker, vertexShader, fragmentShader, customAttributes) {
|
|
28
|
+
super(helper, worker, vertexShader, fragmentShader, customAttributes);
|
|
29
|
+
|
|
30
|
+
// vertices for lines must hold both a position (x,y) and an offset (dx,dy)
|
|
31
|
+
this.attributes = [
|
|
32
|
+
{
|
|
33
|
+
name: Attributes.SEGMENT_START,
|
|
34
|
+
size: 2,
|
|
35
|
+
type: AttributeType.FLOAT,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: Attributes.SEGMENT_END,
|
|
39
|
+
size: 2,
|
|
40
|
+
type: AttributeType.FLOAT,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: Attributes.PARAMETERS,
|
|
44
|
+
size: 1,
|
|
45
|
+
type: AttributeType.FLOAT,
|
|
46
|
+
},
|
|
47
|
+
].concat(
|
|
48
|
+
customAttributes.map(function (attribute) {
|
|
49
|
+
return {
|
|
50
|
+
name: 'a_' + attribute.name,
|
|
51
|
+
size: 1,
|
|
52
|
+
type: AttributeType.FLOAT,
|
|
53
|
+
};
|
|
54
|
+
})
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Render instructions for lines are structured like so:
|
|
60
|
+
* [ customAttr0, ... , customAttrN, numberOfVertices0, x0, y0, ... , xN, yN, numberOfVertices1, ... ]
|
|
61
|
+
* @param {import("./MixedGeometryBatch.js").LineStringGeometryBatch} batch Linestring geometry batch
|
|
62
|
+
* @override
|
|
63
|
+
*/
|
|
64
|
+
generateRenderInstructions(batch) {
|
|
65
|
+
// here we anticipate the amount of render instructions for lines:
|
|
66
|
+
// 2 instructions per vertex for position (x and y)
|
|
67
|
+
// + 1 instruction per line per custom attributes
|
|
68
|
+
// + 1 instruction per line (for vertices count)
|
|
69
|
+
const totalInstructionsCount =
|
|
70
|
+
2 * batch.verticesCount +
|
|
71
|
+
(1 + this.customAttributes.length) * batch.geometriesCount;
|
|
72
|
+
if (
|
|
73
|
+
!batch.renderInstructions ||
|
|
74
|
+
batch.renderInstructions.length !== totalInstructionsCount
|
|
75
|
+
) {
|
|
76
|
+
batch.renderInstructions = new Float32Array(totalInstructionsCount);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// loop on features to fill the render instructions
|
|
80
|
+
let batchEntry;
|
|
81
|
+
const flatCoords = [];
|
|
82
|
+
let renderIndex = 0;
|
|
83
|
+
let value;
|
|
84
|
+
for (const featureUid in batch.entries) {
|
|
85
|
+
batchEntry = batch.entries[featureUid];
|
|
86
|
+
for (let i = 0, ii = batchEntry.flatCoordss.length; i < ii; i++) {
|
|
87
|
+
flatCoords.length = batchEntry.flatCoordss[i].length;
|
|
88
|
+
transform2D(
|
|
89
|
+
batchEntry.flatCoordss[i],
|
|
90
|
+
0,
|
|
91
|
+
flatCoords.length,
|
|
92
|
+
2,
|
|
93
|
+
batch.renderInstructionsTransform,
|
|
94
|
+
flatCoords
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
// custom attributes
|
|
98
|
+
for (let k = 0, kk = this.customAttributes.length; k < kk; k++) {
|
|
99
|
+
value = this.customAttributes[k].callback(batchEntry.feature);
|
|
100
|
+
batch.renderInstructions[renderIndex++] = value;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// vertices count
|
|
104
|
+
batch.renderInstructions[renderIndex++] = flatCoords.length / 2;
|
|
105
|
+
|
|
106
|
+
// looping on points for positions
|
|
107
|
+
for (let j = 0, jj = flatCoords.length; j < jj; j += 2) {
|
|
108
|
+
batch.renderInstructions[renderIndex++] = flatCoords[j];
|
|
109
|
+
batch.renderInstructions[renderIndex++] = flatCoords[j + 1];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export default LineStringBatchRenderer;
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module ol/render/webgl/MixedGeometryBatch
|
|
3
|
+
*/
|
|
4
|
+
import WebGLArrayBuffer from '../../webgl/Buffer.js';
|
|
5
|
+
import {ARRAY_BUFFER, DYNAMIC_DRAW, ELEMENT_ARRAY_BUFFER} from '../../webgl.js';
|
|
6
|
+
import {create as createTransform} from '../../transform.js';
|
|
7
|
+
import {getUid} from '../../util.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Object} GeometryBatchItem Object that holds a reference to a feature as well as the raw coordinates of its various geometries
|
|
11
|
+
* @property {import("../../Feature").default} feature Feature
|
|
12
|
+
* @property {Array<Array<number>>} flatCoordss Array of flat coordinates arrays, one for each geometry related to the feature
|
|
13
|
+
* @property {number} [verticesCount] Only defined for linestring and polygon batches
|
|
14
|
+
* @property {number} [ringsCount] Only defined for polygon batches
|
|
15
|
+
* @property {Array<Array<number>>} [ringsVerticesCounts] Array of vertices counts in each ring for each geometry; only defined for polygons batches
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {PointGeometryBatch|LineStringGeometryBatch|PolygonGeometryBatch} GeometryBatch
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @typedef {Object} PolygonGeometryBatch A geometry batch specific to polygons
|
|
24
|
+
* @property {Object<string, GeometryBatchItem>} entries Dictionary of all entries in the batch with associated computed values.
|
|
25
|
+
* One entry corresponds to one feature. Key is feature uid.
|
|
26
|
+
* @property {number} geometriesCount Amount of geometries in the batch.
|
|
27
|
+
* @property {Float32Array} renderInstructions Render instructions for polygons are structured like so:
|
|
28
|
+
* [ numberOfRings, numberOfVerticesInRing0, ..., numberOfVerticesInRingN, x0, y0, customAttr0, ..., xN, yN, customAttrN, numberOfRings,... ]
|
|
29
|
+
* @property {WebGLArrayBuffer} verticesBuffer Vertices WebGL buffer
|
|
30
|
+
* @property {WebGLArrayBuffer} indicesBuffer Indices WebGL buffer
|
|
31
|
+
* @property {import("../../transform.js").Transform} renderInstructionsTransform Converts world space coordinates to screen space; applies to the rendering instructions
|
|
32
|
+
* @property {import("../../transform.js").Transform} verticesBufferTransform Converts world space coordinates to screen space; applies to the webgl vertices buffer
|
|
33
|
+
* @property {import("../../transform.js").Transform} invertVerticesBufferTransform Screen space to world space; applies to the webgl vertices buffer
|
|
34
|
+
* @property {number} verticesCount Amount of vertices from geometries in the batch.
|
|
35
|
+
* @property {number} ringsCount How many outer and inner rings in this batch.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @typedef {Object} LineStringGeometryBatch A geometry batch specific to lines
|
|
40
|
+
* @property {Object<string, GeometryBatchItem>} entries Dictionary of all entries in the batch with associated computed values.
|
|
41
|
+
* One entry corresponds to one feature. Key is feature uid.
|
|
42
|
+
* @property {number} geometriesCount Amount of geometries in the batch.
|
|
43
|
+
* @property {Float32Array} renderInstructions Render instructions for polygons are structured like so:
|
|
44
|
+
* [ numberOfRings, numberOfVerticesInRing0, ..., numberOfVerticesInRingN, x0, y0, customAttr0, ..., xN, yN, customAttrN, numberOfRings,... ]
|
|
45
|
+
* @property {WebGLArrayBuffer} verticesBuffer Vertices WebGL buffer
|
|
46
|
+
* @property {WebGLArrayBuffer} indicesBuffer Indices WebGL buffer
|
|
47
|
+
* @property {import("../../transform.js").Transform} renderInstructionsTransform Converts world space coordinates to screen space; applies to the rendering instructions
|
|
48
|
+
* @property {import("../../transform.js").Transform} verticesBufferTransform Converts world space coordinates to screen space; applies to the webgl vertices buffer
|
|
49
|
+
* @property {import("../../transform.js").Transform} invertVerticesBufferTransform Screen space to world space; applies to the webgl vertices buffer
|
|
50
|
+
* @property {number} verticesCount Amount of vertices from geometries in the batch.
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @typedef {Object} PointGeometryBatch A geometry batch specific to points
|
|
55
|
+
* @property {Object<string, GeometryBatchItem>} entries Dictionary of all entries in the batch with associated computed values.
|
|
56
|
+
* One entry corresponds to one feature. Key is feature uid.
|
|
57
|
+
* @property {number} geometriesCount Amount of geometries in the batch.
|
|
58
|
+
* @property {Float32Array} renderInstructions Render instructions for polygons are structured like so:
|
|
59
|
+
* [ numberOfRings, numberOfVerticesInRing0, ..., numberOfVerticesInRingN, x0, y0, customAttr0, ..., xN, yN, customAttrN, numberOfRings,... ]
|
|
60
|
+
* @property {WebGLArrayBuffer} verticesBuffer Vertices WebGL buffer
|
|
61
|
+
* @property {WebGLArrayBuffer} indicesBuffer Indices WebGL buffer
|
|
62
|
+
* @property {import("../../transform.js").Transform} renderInstructionsTransform Converts world space coordinates to screen space; applies to the rendering instructions
|
|
63
|
+
* @property {import("../../transform.js").Transform} verticesBufferTransform Converts world space coordinates to screen space; applies to the webgl vertices buffer
|
|
64
|
+
* @property {import("../../transform.js").Transform} invertVerticesBufferTransform Screen space to world space; applies to the webgl vertices buffer
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @classdesc This class is used to group several geometries of various types together for faster rendering.
|
|
69
|
+
* Three inner batches are maintained for polygons, lines and points. Each time a feature is added, changed or removed
|
|
70
|
+
* from the batch, these inner batches are modified accordingly in order to keep them up-to-date.
|
|
71
|
+
*
|
|
72
|
+
* A feature can be present in several inner batches, for example a polygon geometry will be present in the polygon batch
|
|
73
|
+
* and its linar rings will be present in the line batch. Multi geometries are also broken down into individual geometries
|
|
74
|
+
* and added to the corresponding batches in a recursive manner.
|
|
75
|
+
*
|
|
76
|
+
* Corresponding {@link module:ol/render/webgl/BatchRenderer} instances are then used to generate the render instructions
|
|
77
|
+
* and WebGL buffers (vertices and indices) for each inner batches; render instructions are stored on the inner batches,
|
|
78
|
+
* alongside the transform used to convert world coords to screen coords at the time these instructions were generated.
|
|
79
|
+
* The resulting WebGL buffers are stored on the batches as well.
|
|
80
|
+
*
|
|
81
|
+
* An important aspect of geometry batches is that there is no guarantee that render instructions and WebGL buffers
|
|
82
|
+
* are synchronized, i.e. render instructions can describe a new state while WebGL buffers might not have been written yet.
|
|
83
|
+
* This is why two world-to-screen transforms are stored on each batch: one for the render instructions and one for
|
|
84
|
+
* the WebGL buffers.
|
|
85
|
+
*/
|
|
86
|
+
class MixedGeometryBatch {
|
|
87
|
+
constructor() {
|
|
88
|
+
/**
|
|
89
|
+
* @type {PolygonGeometryBatch}
|
|
90
|
+
*/
|
|
91
|
+
this.polygonBatch = {
|
|
92
|
+
entries: {},
|
|
93
|
+
geometriesCount: 0,
|
|
94
|
+
verticesCount: 0,
|
|
95
|
+
ringsCount: 0,
|
|
96
|
+
renderInstructions: new Float32Array(0),
|
|
97
|
+
verticesBuffer: new WebGLArrayBuffer(ARRAY_BUFFER, DYNAMIC_DRAW),
|
|
98
|
+
indicesBuffer: new WebGLArrayBuffer(ELEMENT_ARRAY_BUFFER, DYNAMIC_DRAW),
|
|
99
|
+
renderInstructionsTransform: createTransform(),
|
|
100
|
+
verticesBufferTransform: createTransform(),
|
|
101
|
+
invertVerticesBufferTransform: createTransform(),
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @type {PointGeometryBatch}
|
|
106
|
+
*/
|
|
107
|
+
this.pointBatch = {
|
|
108
|
+
entries: {},
|
|
109
|
+
geometriesCount: 0,
|
|
110
|
+
renderInstructions: new Float32Array(0),
|
|
111
|
+
verticesBuffer: new WebGLArrayBuffer(ARRAY_BUFFER, DYNAMIC_DRAW),
|
|
112
|
+
indicesBuffer: new WebGLArrayBuffer(ELEMENT_ARRAY_BUFFER, DYNAMIC_DRAW),
|
|
113
|
+
renderInstructionsTransform: createTransform(),
|
|
114
|
+
verticesBufferTransform: createTransform(),
|
|
115
|
+
invertVerticesBufferTransform: createTransform(),
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @type {LineStringGeometryBatch}
|
|
120
|
+
*/
|
|
121
|
+
this.lineStringBatch = {
|
|
122
|
+
entries: {},
|
|
123
|
+
geometriesCount: 0,
|
|
124
|
+
verticesCount: 0,
|
|
125
|
+
renderInstructions: new Float32Array(0),
|
|
126
|
+
verticesBuffer: new WebGLArrayBuffer(ARRAY_BUFFER, DYNAMIC_DRAW),
|
|
127
|
+
indicesBuffer: new WebGLArrayBuffer(ELEMENT_ARRAY_BUFFER, DYNAMIC_DRAW),
|
|
128
|
+
renderInstructionsTransform: createTransform(),
|
|
129
|
+
verticesBufferTransform: createTransform(),
|
|
130
|
+
invertVerticesBufferTransform: createTransform(),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @param {Array<import("../../Feature").default>} features Array of features to add to the batch
|
|
136
|
+
*/
|
|
137
|
+
addFeatures(features) {
|
|
138
|
+
for (let i = 0; i < features.length; i++) {
|
|
139
|
+
this.addFeature(features[i]);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* @param {import("../../Feature").default} feature Feature to add to the batch
|
|
145
|
+
*/
|
|
146
|
+
addFeature(feature) {
|
|
147
|
+
const geometry = feature.getGeometry();
|
|
148
|
+
if (!geometry) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
this.addGeometry_(geometry, feature);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @param {import("../../Feature").default} feature Feature
|
|
156
|
+
* @return {GeometryBatchItem} Batch item added (or existing one)
|
|
157
|
+
* @private
|
|
158
|
+
*/
|
|
159
|
+
addFeatureEntryInPointBatch_(feature) {
|
|
160
|
+
const uid = getUid(feature);
|
|
161
|
+
if (!(uid in this.pointBatch.entries)) {
|
|
162
|
+
this.pointBatch.entries[uid] = {
|
|
163
|
+
feature: feature,
|
|
164
|
+
flatCoordss: [],
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
return this.pointBatch.entries[uid];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* @param {import("../../Feature").default} feature Feature
|
|
172
|
+
* @return {GeometryBatchItem} Batch item added (or existing one)
|
|
173
|
+
* @private
|
|
174
|
+
*/
|
|
175
|
+
addFeatureEntryInLineStringBatch_(feature) {
|
|
176
|
+
const uid = getUid(feature);
|
|
177
|
+
if (!(uid in this.lineStringBatch.entries)) {
|
|
178
|
+
this.lineStringBatch.entries[uid] = {
|
|
179
|
+
feature: feature,
|
|
180
|
+
flatCoordss: [],
|
|
181
|
+
verticesCount: 0,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
return this.lineStringBatch.entries[uid];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* @param {import("../../Feature").default} feature Feature
|
|
189
|
+
* @return {GeometryBatchItem} Batch item added (or existing one)
|
|
190
|
+
* @private
|
|
191
|
+
*/
|
|
192
|
+
addFeatureEntryInPolygonBatch_(feature) {
|
|
193
|
+
const uid = getUid(feature);
|
|
194
|
+
if (!(uid in this.polygonBatch.entries)) {
|
|
195
|
+
this.polygonBatch.entries[uid] = {
|
|
196
|
+
feature: feature,
|
|
197
|
+
flatCoordss: [],
|
|
198
|
+
verticesCount: 0,
|
|
199
|
+
ringsCount: 0,
|
|
200
|
+
ringsVerticesCounts: [],
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
return this.polygonBatch.entries[uid];
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* @param {import("../../Feature").default} feature Feature
|
|
208
|
+
* @private
|
|
209
|
+
*/
|
|
210
|
+
clearFeatureEntryInPointBatch_(feature) {
|
|
211
|
+
const entry = this.pointBatch.entries[getUid(feature)];
|
|
212
|
+
if (!entry) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
this.pointBatch.geometriesCount -= entry.flatCoordss.length;
|
|
216
|
+
delete this.pointBatch.entries[getUid(feature)];
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* @param {import("../../Feature").default} feature Feature
|
|
221
|
+
* @private
|
|
222
|
+
*/
|
|
223
|
+
clearFeatureEntryInLineStringBatch_(feature) {
|
|
224
|
+
const entry = this.lineStringBatch.entries[getUid(feature)];
|
|
225
|
+
if (!entry) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
this.lineStringBatch.verticesCount -= entry.verticesCount;
|
|
229
|
+
this.lineStringBatch.geometriesCount -= entry.flatCoordss.length;
|
|
230
|
+
delete this.lineStringBatch.entries[getUid(feature)];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* @param {import("../../Feature").default} feature Feature
|
|
235
|
+
* @private
|
|
236
|
+
*/
|
|
237
|
+
clearFeatureEntryInPolygonBatch_(feature) {
|
|
238
|
+
const entry = this.polygonBatch.entries[getUid(feature)];
|
|
239
|
+
if (!entry) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
this.polygonBatch.verticesCount -= entry.verticesCount;
|
|
243
|
+
this.polygonBatch.ringsCount -= entry.ringsCount;
|
|
244
|
+
this.polygonBatch.geometriesCount -= entry.flatCoordss.length;
|
|
245
|
+
delete this.polygonBatch.entries[getUid(feature)];
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @param {import("../../geom").Geometry} geometry Geometry
|
|
250
|
+
* @param {import("../../Feature").default} feature Feature
|
|
251
|
+
* @private
|
|
252
|
+
*/
|
|
253
|
+
addGeometry_(geometry, feature) {
|
|
254
|
+
const type = geometry.getType();
|
|
255
|
+
let flatCoords;
|
|
256
|
+
let verticesCount;
|
|
257
|
+
let batchEntry;
|
|
258
|
+
switch (type) {
|
|
259
|
+
case 'GeometryCollection':
|
|
260
|
+
/** @type {import("../../geom").GeometryCollection} */ (geometry)
|
|
261
|
+
.getGeometries()
|
|
262
|
+
.map((geom) => this.addGeometry_(geom, feature));
|
|
263
|
+
break;
|
|
264
|
+
case 'MultiPolygon':
|
|
265
|
+
/** @type {import("../../geom").MultiPolygon} */ (geometry)
|
|
266
|
+
.getPolygons()
|
|
267
|
+
.map((polygon) => this.addGeometry_(polygon, feature));
|
|
268
|
+
break;
|
|
269
|
+
case 'MultiLineString':
|
|
270
|
+
/** @type {import("../../geom").MultiLineString} */ (geometry)
|
|
271
|
+
.getLineStrings()
|
|
272
|
+
.map((line) => this.addGeometry_(line, feature));
|
|
273
|
+
break;
|
|
274
|
+
case 'MultiPoint':
|
|
275
|
+
/** @type {import("../../geom").MultiPoint} */ (geometry)
|
|
276
|
+
.getPoints()
|
|
277
|
+
.map((point) => this.addGeometry_(point, feature));
|
|
278
|
+
break;
|
|
279
|
+
case 'Polygon':
|
|
280
|
+
const polygonGeom = /** @type {import("../../geom").Polygon} */ (
|
|
281
|
+
geometry
|
|
282
|
+
);
|
|
283
|
+
batchEntry = this.addFeatureEntryInPolygonBatch_(feature);
|
|
284
|
+
flatCoords = polygonGeom.getFlatCoordinates();
|
|
285
|
+
verticesCount = flatCoords.length / 2;
|
|
286
|
+
const ringsCount = polygonGeom.getLinearRingCount();
|
|
287
|
+
const ringsVerticesCount = polygonGeom
|
|
288
|
+
.getEnds()
|
|
289
|
+
.map((end, ind, arr) =>
|
|
290
|
+
ind > 0 ? (end - arr[ind - 1]) / 2 : end / 2
|
|
291
|
+
);
|
|
292
|
+
this.polygonBatch.verticesCount += verticesCount;
|
|
293
|
+
this.polygonBatch.ringsCount += ringsCount;
|
|
294
|
+
this.polygonBatch.geometriesCount++;
|
|
295
|
+
batchEntry.flatCoordss.push(flatCoords);
|
|
296
|
+
batchEntry.ringsVerticesCounts.push(ringsVerticesCount);
|
|
297
|
+
batchEntry.verticesCount += verticesCount;
|
|
298
|
+
batchEntry.ringsCount += ringsCount;
|
|
299
|
+
polygonGeom
|
|
300
|
+
.getLinearRings()
|
|
301
|
+
.map((ring) => this.addGeometry_(ring, feature));
|
|
302
|
+
break;
|
|
303
|
+
case 'Point':
|
|
304
|
+
const pointGeom = /** @type {import("../../geom").Point} */ (geometry);
|
|
305
|
+
batchEntry = this.addFeatureEntryInPointBatch_(feature);
|
|
306
|
+
flatCoords = pointGeom.getFlatCoordinates();
|
|
307
|
+
this.pointBatch.geometriesCount++;
|
|
308
|
+
batchEntry.flatCoordss.push(flatCoords);
|
|
309
|
+
break;
|
|
310
|
+
case 'LineString':
|
|
311
|
+
case 'LinearRing':
|
|
312
|
+
const lineGeom = /** @type {import("../../geom").LineString} */ (
|
|
313
|
+
geometry
|
|
314
|
+
);
|
|
315
|
+
batchEntry = this.addFeatureEntryInLineStringBatch_(feature);
|
|
316
|
+
flatCoords = lineGeom.getFlatCoordinates();
|
|
317
|
+
verticesCount = flatCoords.length / 2;
|
|
318
|
+
this.lineStringBatch.verticesCount += verticesCount;
|
|
319
|
+
this.lineStringBatch.geometriesCount++;
|
|
320
|
+
batchEntry.flatCoordss.push(flatCoords);
|
|
321
|
+
batchEntry.verticesCount += verticesCount;
|
|
322
|
+
break;
|
|
323
|
+
default:
|
|
324
|
+
// pass
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* @param {import("../../Feature").default} feature Feature
|
|
330
|
+
*/
|
|
331
|
+
changeFeature(feature) {
|
|
332
|
+
this.clearFeatureEntryInPointBatch_(feature);
|
|
333
|
+
this.clearFeatureEntryInPolygonBatch_(feature);
|
|
334
|
+
this.clearFeatureEntryInLineStringBatch_(feature);
|
|
335
|
+
const geometry = feature.getGeometry();
|
|
336
|
+
if (!geometry) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
this.addGeometry_(geometry, feature);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* @param {import("../../Feature").default} feature Feature
|
|
344
|
+
*/
|
|
345
|
+
removeFeature(feature) {
|
|
346
|
+
this.clearFeatureEntryInPointBatch_(feature);
|
|
347
|
+
this.clearFeatureEntryInPolygonBatch_(feature);
|
|
348
|
+
this.clearFeatureEntryInLineStringBatch_(feature);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
clear() {
|
|
352
|
+
this.polygonBatch.entries = {};
|
|
353
|
+
this.polygonBatch.geometriesCount = 0;
|
|
354
|
+
this.polygonBatch.verticesCount = 0;
|
|
355
|
+
this.polygonBatch.ringsCount = 0;
|
|
356
|
+
this.lineStringBatch.entries = {};
|
|
357
|
+
this.lineStringBatch.geometriesCount = 0;
|
|
358
|
+
this.lineStringBatch.verticesCount = 0;
|
|
359
|
+
this.pointBatch.entries = {};
|
|
360
|
+
this.pointBatch.geometriesCount = 0;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export default MixedGeometryBatch;
|