Webgl points renderer / slight improvements following review
Also fixes a lint error.
This commit is contained in:
@@ -287,30 +287,50 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
|||||||
*/
|
*/
|
||||||
this.featureCache_ = {};
|
this.featureCache_ = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amount of features in the cache.
|
||||||
|
* @type {number}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
this.featureCount_ = 0;
|
||||||
|
|
||||||
const source = this.getLayer().getSource();
|
const source = this.getLayer().getSource();
|
||||||
this.sourceListenKeys_ = [
|
this.sourceListenKeys_ = [
|
||||||
listen(source, VectorEventType.ADDFEATURE, this.handleSourceFeatureChanged_, this),
|
listen(source, VectorEventType.ADDFEATURE, this.handleSourceFeatureAdded_, this),
|
||||||
listen(source, VectorEventType.CHANGEFEATURE, this.handleSourceFeatureChanged_, this),
|
listen(source, VectorEventType.CHANGEFEATURE, this.handleSourceFeatureChanged_, this),
|
||||||
listen(source, VectorEventType.REMOVEFEATURE, this.handleSourceFeatureDelete_, this)
|
listen(source, VectorEventType.REMOVEFEATURE, this.handleSourceFeatureDelete_, this)
|
||||||
];
|
];
|
||||||
source.getFeatures().forEach(function(feature) {
|
source.forEachFeature(function(feature) {
|
||||||
const uid = getUid(feature);
|
this.featureCache_[getUid(feature)] = {
|
||||||
this.featureCache_[uid] = {
|
|
||||||
feature: feature,
|
feature: feature,
|
||||||
properties: feature.getProperties(),
|
properties: feature.getProperties(),
|
||||||
geometry: feature.getGeometry()
|
geometry: feature.getGeometry()
|
||||||
};
|
};
|
||||||
|
this.featureCount_++;
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import("../../source/Vector.js").VectorSourceEvent} event Event.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
handleSourceFeatureAdded_(event) {
|
||||||
|
const feature = event.feature;
|
||||||
|
this.featureCache_[getUid(feature)] = {
|
||||||
|
feature: feature,
|
||||||
|
properties: feature.getProperties(),
|
||||||
|
geometry: feature.getGeometry()
|
||||||
|
};
|
||||||
|
this.featureCount_++;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("../../source/Vector.js").VectorSourceEvent} event Event.
|
* @param {import("../../source/Vector.js").VectorSourceEvent} event Event.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
handleSourceFeatureChanged_(event) {
|
handleSourceFeatureChanged_(event) {
|
||||||
const feature = event.feature;
|
const feature = event.feature;
|
||||||
const uid = getUid(feature);
|
this.featureCache_[getUid(feature)] = {
|
||||||
this.featureCache_[uid] = {
|
|
||||||
feature: feature,
|
feature: feature,
|
||||||
properties: feature.getProperties(),
|
properties: feature.getProperties(),
|
||||||
geometry: feature.getGeometry()
|
geometry: feature.getGeometry()
|
||||||
@@ -323,8 +343,8 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
|||||||
*/
|
*/
|
||||||
handleSourceFeatureDelete_(event) {
|
handleSourceFeatureDelete_(event) {
|
||||||
const feature = event.feature;
|
const feature = event.feature;
|
||||||
const uid = getUid(feature);
|
delete this.featureCache_[getUid(feature)];
|
||||||
delete this.featureCache_[uid];
|
this.featureCount_--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -403,32 +423,29 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
|||||||
const projectionTransform = createTransform();
|
const projectionTransform = createTransform();
|
||||||
this.helper.makeProjectionTransform(frameState, projectionTransform);
|
this.helper.makeProjectionTransform(frameState, projectionTransform);
|
||||||
|
|
||||||
const featureUids = Object.keys(this.featureCache_);
|
|
||||||
|
|
||||||
// here we anticipate the amount of render instructions that we well generate
|
// here we anticipate the amount of render instructions that we well generate
|
||||||
// this can be done since we know that for normal render we only have x, y as base instructions,
|
// this can be done since we know that for normal render we only have x, y as base instructions,
|
||||||
// and x, y, r, g, b, a and featureUid for hit render instructions
|
// and x, y, r, g, b, a and featureUid for hit render instructions
|
||||||
// and we also know the amount of custom attributes to append to these
|
// and we also know the amount of custom attributes to append to these
|
||||||
const totalInstructionsCount = (2 + this.customAttributes.length) * featureUids.length;
|
const totalInstructionsCount = (2 + this.customAttributes.length) * this.featureCount_;
|
||||||
if (!this.renderInstructions_ || this.renderInstructions_.length !== totalInstructionsCount) {
|
if (!this.renderInstructions_ || this.renderInstructions_.length !== totalInstructionsCount) {
|
||||||
this.renderInstructions_ = new Float32Array(totalInstructionsCount);
|
this.renderInstructions_ = new Float32Array(totalInstructionsCount);
|
||||||
}
|
}
|
||||||
if (this.hitDetectionEnabled_) {
|
if (this.hitDetectionEnabled_) {
|
||||||
const totalHitInstructionsCount = (7 + this.customAttributes.length) * featureUids.length;
|
const totalHitInstructionsCount = (7 + this.customAttributes.length) * this.featureCount_;
|
||||||
if (!this.hitRenderInstructions_ || this.hitRenderInstructions_.length !== totalHitInstructionsCount) {
|
if (!this.hitRenderInstructions_ || this.hitRenderInstructions_.length !== totalHitInstructionsCount) {
|
||||||
this.hitRenderInstructions_ = new Float32Array(totalHitInstructionsCount);
|
this.hitRenderInstructions_ = new Float32Array(totalHitInstructionsCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop on features to fill the buffer
|
// loop on features to fill the buffer
|
||||||
let featureUid, featureCache, geometry;
|
let featureCache, geometry;
|
||||||
const tmpCoords = [];
|
const tmpCoords = [];
|
||||||
const tmpColor = [];
|
const tmpColor = [];
|
||||||
let renderIndex = 0;
|
let renderIndex = 0;
|
||||||
let hitIndex = 0;
|
let hitIndex = 0;
|
||||||
let hitColor;
|
let hitColor;
|
||||||
for (let i = 0; i < featureUids.length; i++) {
|
for (const featureUid in this.featureCache_) {
|
||||||
featureUid = featureUids[i];
|
|
||||||
featureCache = this.featureCache_[featureUid];
|
featureCache = this.featureCache_[featureUid];
|
||||||
geometry = /** @type {import("../../geom").Point} */(featureCache.geometry);
|
geometry = /** @type {import("../../geom").Point} */(featureCache.geometry);
|
||||||
if (!geometry || geometry.getType() !== GeometryType.POINT) {
|
if (!geometry || geometry.getType() !== GeometryType.POINT) {
|
||||||
|
|||||||
@@ -123,7 +123,10 @@ class WebGLRenderTarget {
|
|||||||
*/
|
*/
|
||||||
readPixel(x, y) {
|
readPixel(x, y) {
|
||||||
if (x < 0 || y < 0 || x > this.size_[0] || y >= this.size_[1]) {
|
if (x < 0 || y < 0 || x > this.size_[0] || y >= this.size_[1]) {
|
||||||
tmpArray4[0] = tmpArray4[1] = tmpArray4[2] = tmpArray4[3] = 0;
|
tmpArray4[0] = 0;
|
||||||
|
tmpArray4[1] = 0;
|
||||||
|
tmpArray4[2] = 0;
|
||||||
|
tmpArray4[3] = 0;
|
||||||
return tmpArray4;
|
return tmpArray4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -425,7 +425,7 @@ describe('ol.renderer.webgl.PointsLayer', function() {
|
|||||||
vertexShader: simpleVertexShader,
|
vertexShader: simpleVertexShader,
|
||||||
fragmentShader: simpleFragmentShader
|
fragmentShader: simpleFragmentShader
|
||||||
});
|
});
|
||||||
expect(Object.keys(renderer.featureCache_).length).to.be(0);
|
expect(renderer.featureCount_).to.be(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('contains the features initially present in the source', function() {
|
it('contains the features initially present in the source', function() {
|
||||||
@@ -434,7 +434,7 @@ describe('ol.renderer.webgl.PointsLayer', function() {
|
|||||||
vertexShader: simpleVertexShader,
|
vertexShader: simpleVertexShader,
|
||||||
fragmentShader: simpleFragmentShader
|
fragmentShader: simpleFragmentShader
|
||||||
});
|
});
|
||||||
expect(Object.keys(renderer.featureCache_).length).to.be(3);
|
expect(renderer.featureCount_).to.be(3);
|
||||||
expect(getCache(features[0], renderer).feature).to.be(features[0]);
|
expect(getCache(features[0], renderer).feature).to.be(features[0]);
|
||||||
expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry());
|
expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry());
|
||||||
expect(getCache(features[0], renderer).properties['test']).to.be(features[0].get('test'));
|
expect(getCache(features[0], renderer).properties['test']).to.be(features[0].get('test'));
|
||||||
@@ -453,10 +453,10 @@ describe('ol.renderer.webgl.PointsLayer', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
source.addFeature(features[0]);
|
source.addFeature(features[0]);
|
||||||
expect(Object.keys(renderer.featureCache_).length).to.be(1);
|
expect(renderer.featureCount_).to.be(1);
|
||||||
|
|
||||||
source.addFeature(features[1]);
|
source.addFeature(features[1]);
|
||||||
expect(Object.keys(renderer.featureCache_).length).to.be(2);
|
expect(renderer.featureCount_).to.be(2);
|
||||||
|
|
||||||
expect(getCache(features[0], renderer).feature).to.be(features[0]);
|
expect(getCache(features[0], renderer).feature).to.be(features[0]);
|
||||||
expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry());
|
expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry());
|
||||||
@@ -473,10 +473,10 @@ describe('ol.renderer.webgl.PointsLayer', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
source.addFeatures(features);
|
source.addFeatures(features);
|
||||||
expect(Object.keys(renderer.featureCache_).length).to.be(3);
|
expect(renderer.featureCount_).to.be(3);
|
||||||
|
|
||||||
source.removeFeature(features[1]);
|
source.removeFeature(features[1]);
|
||||||
expect(Object.keys(renderer.featureCache_).length).to.be(2);
|
expect(renderer.featureCount_).to.be(2);
|
||||||
|
|
||||||
expect(getCache(features[0], renderer).feature).to.be(features[0]);
|
expect(getCache(features[0], renderer).feature).to.be(features[0]);
|
||||||
expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry());
|
expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry());
|
||||||
@@ -496,7 +496,7 @@ describe('ol.renderer.webgl.PointsLayer', function() {
|
|||||||
features[0].set('test', 'updated');
|
features[0].set('test', 'updated');
|
||||||
features[0].set('added', true);
|
features[0].set('added', true);
|
||||||
features[0].getGeometry().setCoordinates([10, 20]);
|
features[0].getGeometry().setCoordinates([10, 20]);
|
||||||
expect(Object.keys(renderer.featureCache_).length).to.be(3);
|
expect(renderer.featureCount_).to.be(3);
|
||||||
|
|
||||||
expect(getCache(features[0], renderer).feature).to.be(features[0]);
|
expect(getCache(features[0], renderer).feature).to.be(features[0]);
|
||||||
expect(getCache(features[0], renderer).geometry.getCoordinates()).to.eql([10, 20]);
|
expect(getCache(features[0], renderer).geometry.getCoordinates()).to.eql([10, 20]);
|
||||||
|
|||||||
Reference in New Issue
Block a user