Use the new webgl renderer in the heatmap layer

This commit is contained in:
Olivier Guyot
2018-11-15 16:33:52 +01:00
parent 51becf1c2e
commit 494b817f47
2 changed files with 87 additions and 46 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
import Map from '../src/ol/Map.js'; import Map from '../src/ol/CompositeMap.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import KML from '../src/ol/format/KML.js'; import KML from '../src/ol/format/KML.js';
import {Heatmap as HeatmapLayer, Tile as TileLayer} from '../src/ol/layer.js'; import {Heatmap as HeatmapLayer, Tile as TileLayer} from '../src/ol/layer.js';
+86 -45
View File
@@ -10,6 +10,7 @@ import {assign} from '../obj.js';
import RenderEventType from '../render/EventType.js'; import RenderEventType from '../render/EventType.js';
import Icon from '../style/Icon.js'; import Icon from '../style/Icon.js';
import Style from '../style/Style.js'; import Style from '../style/Style.js';
import WebGLPointsLayerRenderer from "../renderer/webgl-new/PointsLayer";
/** /**
@@ -135,25 +136,25 @@ class Heatmap extends VectorLayer {
weightFunction = weight; weightFunction = weight;
} }
this.setStyle(function(feature, resolution) { // this.setStyle(function(feature, resolution) {
const weight = weightFunction(feature); // const weight = weightFunction(feature);
const opacity = weight !== undefined ? clamp(weight, 0, 1) : 1; // const opacity = weight !== undefined ? clamp(weight, 0, 1) : 1;
// cast to 8 bits // // cast to 8 bits
const index = (255 * opacity) | 0; // const index = (255 * opacity) | 0;
let style = this.styleCache_[index]; // let style = this.styleCache_[index];
if (!style) { // if (!style) {
style = [ // style = [
new Style({ // new Style({
image: new Icon({ // image: new Icon({
opacity: opacity, // opacity: opacity,
src: this.circleImage_ // src: this.circleImage_
}) // })
}) // })
]; // ];
this.styleCache_[index] = style; // this.styleCache_[index] = style;
} // }
return style; // return style;
}.bind(this)); // }.bind(this));
// For performance reasons, don't sort the features before rendering. // For performance reasons, don't sort the features before rendering.
// The render order is not relevant for a heatmap representation. // The render order is not relevant for a heatmap representation.
@@ -167,19 +168,19 @@ class Heatmap extends VectorLayer {
* @private * @private
*/ */
createCircle_() { createCircle_() {
const radius = this.getRadius(); // const radius = this.getRadius();
const blur = this.getBlur(); // const blur = this.getBlur();
const halfSize = radius + blur + 1; // const halfSize = radius + blur + 1;
const size = 2 * halfSize; // const size = 2 * halfSize;
const context = createCanvasContext2D(size, size); // const context = createCanvasContext2D(size, size);
context.shadowOffsetX = context.shadowOffsetY = this.shadow_; // context.shadowOffsetX = context.shadowOffsetY = this.shadow_;
context.shadowBlur = blur; // context.shadowBlur = blur;
context.shadowColor = '#000'; // context.shadowColor = '#000';
context.beginPath(); // context.beginPath();
const center = halfSize - this.shadow_; // const center = halfSize - this.shadow_;
context.arc(center, center, radius, 0, Math.PI * 2, true); // context.arc(center, center, radius, 0, Math.PI * 2, true);
context.fill(); // context.fill();
return context.canvas.toDataURL(); // return context.canvas.toDataURL();
} }
/** /**
@@ -233,19 +234,19 @@ class Heatmap extends VectorLayer {
* @private * @private
*/ */
handleRender_(event) { handleRender_(event) {
const context = event.context; // const context = event.context;
const canvas = context.canvas; // const canvas = context.canvas;
const image = context.getImageData(0, 0, canvas.width, canvas.height); // const image = context.getImageData(0, 0, canvas.width, canvas.height);
const view8 = image.data; // const view8 = image.data;
for (let i = 0, ii = view8.length; i < ii; i += 4) { // for (let i = 0, ii = view8.length; i < ii; i += 4) {
const alpha = view8[i + 3] * 4; // const alpha = view8[i + 3] * 4;
if (alpha) { // if (alpha) {
view8[i] = this.gradient_[alpha]; // view8[i] = this.gradient_[alpha];
view8[i + 1] = this.gradient_[alpha + 1]; // view8[i + 1] = this.gradient_[alpha + 1];
view8[i + 2] = this.gradient_[alpha + 2]; // view8[i + 2] = this.gradient_[alpha + 2];
} // }
} // }
context.putImageData(image, 0, 0); // context.putImageData(image, 0, 0);
} }
/** /**
@@ -277,6 +278,46 @@ class Heatmap extends VectorLayer {
setRadius(radius) { setRadius(radius) {
this.set(Property.RADIUS, radius); this.set(Property.RADIUS, radius);
} }
/**
* @inheritDoc
*/
createRenderer() {
return new WebGLPointsLayerRenderer(this, {
fragmentShader: `
precision mediump float;
uniform float u_opacity;
varying vec2 v_texCoord;
void main(void) {
gl_FragColor.rgb = vec3(1.0, 1.0, 1.0);
vec2 texCoord = v_texCoord * 2.0 - vec2(1.0, 1.0);
float sqRadius = texCoord.x * texCoord.x + texCoord.y * texCoord.y;
float alpha = 1.0 - sqRadius;
if (alpha <= 0.0) {
discard;
}
gl_FragColor.a = alpha * 0.1;
}`,
postProcessingShader: `
precision mediump float;
uniform sampler2D u_image;
varying vec2 v_texCoord;
varying vec2 v_screenCoord;
void main() {
vec4 color = texture2D(u_image, v_texCoord);
gl_FragColor.rgb = vec3(color.a, 0.3 + color.a * 0.6, 0.5);
gl_FragColor.a = smoothstep(0.0, 0.2, color.a);
}`,
sizeCallback: function() {
return 50;
},
});
}
} }