Skip to content

Commit

Permalink
stop-based heatmap color ramps
Browse files Browse the repository at this point in the history
  • Loading branch information
mourner committed Sep 14, 2017
1 parent 625c655 commit 000975c
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 41 deletions.
42 changes: 2 additions & 40 deletions src/render/draw_heatmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,6 @@ import type TileCoord from '../source/tile_coord';

module.exports = drawHeatmap;

const defaultRampColors = {
'0': 'rgba(20, 160, 240, 0)',
'5': 'rgb(20, 190, 240)',
'10': 'rgb(20, 220, 240)',
'15': 'rgb(20, 250, 240)',
'20': 'rgb(20, 250, 160)',
'25': 'rgb(135, 250, 80)',
'30': 'rgb(250, 250, 0)',
'35': 'rgb(250, 180, 0)',
'40': 'rgb(250, 110, 0)',
'45': 'rgb(250, 40, 0)',
'50': 'rgb(180, 40, 40)',
'55': 'rgb(110, 40, 80)',
'60': 'rgb(80, 40, 110)',
'65': 'rgb(50, 40, 140)',
'70': 'rgb(20, 40, 170)',
'100': 'rgb(20, 40, 170)'
};

function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapStyleLayer, coords: Array<TileCoord>) {
if (painter.isOpaquePass) return;

Expand Down Expand Up @@ -95,8 +76,7 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
const colorRamp = window.colorRamp = getColorRamp(defaultRampColors);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, colorRamp);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, layer.colorRamp);

renderTextureToMap(gl, painter, layer);

Expand All @@ -106,7 +86,7 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS
function renderToTexture(gl, painter) {
gl.activeTexture(gl.TEXTURE1);

var ext = gl.getExtension('OES_texture_half_float');
const ext = gl.getExtension('OES_texture_half_float');
gl.getExtension('OES_texture_half_float_linear');

let texture = painter.viewportTexture;
Expand Down Expand Up @@ -165,21 +145,3 @@ function renderTextureToMap(gl, painter, layer) {

gl.enable(gl.DEPTH_TEST);
}

function getColorRamp(colors) {
const canvas = window.document.createElement('canvas');
const ctx = canvas.getContext('2d');

canvas.width = 256;
canvas.height = 1;

const gradient = ctx.createLinearGradient(1, 0, 256, 0);
for (const stop in colors) {
gradient.addColorStop(+stop / 100, colors[stop]);
}

ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 256, 1);

return new Uint8Array(ctx.getImageData(0, 0, 256, 1).data);
}
22 changes: 21 additions & 1 deletion src/style-spec/reference/v8.json
Original file line number Diff line number Diff line change
Expand Up @@ -3007,7 +3007,27 @@
},
"heatmap-color": {
"type": "color",
"default": "#000000",
"default": {
"stops": [
[0, "rgba(20, 160, 240, 0)"],
[0.05, "rgb(20, 190, 240)"],
[0.10, "rgb(20, 220, 240)"],
[0.15, "rgb(20, 250, 240)"],
[0.20, "rgb(20, 250, 160)"],
[0.25, "rgb(135, 250, 80)"],
[0.30, "rgb(250, 250, 0)"],
[0.35, "rgb(250, 180, 0)"],
[0.40, "rgb(250, 110, 0)"],
[0.45, "rgb(250, 40, 0)"],
[0.50, "rgb(180, 40, 40)"],
[0.55, "rgb(110, 40, 80)"],
[0.60, "rgb(80, 40, 110)"],
[0.65, "rgb(50, 40, 140)"],
[0.70, "rgb(20, 40, 170)"],
[1, "rgb(20, 40, 170)"]
],
"default": "rgba(0, 0, 0, 0)"
},
"doc": "The fill color of the heatmap.",
"function": "interpolated",
"zoom-function": true,
Expand Down
22 changes: 22 additions & 0 deletions src/style/style_layer/heatmap_style_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,28 @@ class HeatmapStyleLayer extends StyleLayer {
createBucket(options) {
return new HeatmapBucket(options);
}

constructor(layer) {
super(layer);
this.colorRamp = new Uint8Array(256 * 4);
if (!this.getPaintProperty('heatmap-color')) {
this.setPaintProperty('heatmap-color', this._paintSpecifications['heatmap-color'].default);
}
}

_applyPaintDeclaration(name: any, declaration: any, options: any, globalOptions: any, animationLoop: any, zoomHistory: any) {
super._applyPaintDeclaration(name, declaration, options, globalOptions, animationLoop, zoomHistory);
if (name === 'heatmap-color') {
const len = this.colorRamp.length;
for (let i = 0; i < len; i += 4) {
const pxColor = this.getPaintValue('heatmap-color', {zoom: i / len});
this.colorRamp[i + 0] = Math.floor(pxColor[0] * 255);
this.colorRamp[i + 1] = Math.floor(pxColor[1] * 255);
this.colorRamp[i + 2] = Math.floor(pxColor[2] * 255);
this.colorRamp[i + 3] = Math.floor(pxColor[3] * 255);
}
}
}
}

module.exports = HeatmapStyleLayer;

0 comments on commit 000975c

Please sign in to comment.