Skip to content

Commit

Permalink
feat(l7): feat heatmap layer
Browse files Browse the repository at this point in the history
  • Loading branch information
mipha.ly@alibaba-inc.com committed Feb 27, 2019
1 parent cc5b1ee commit 109f3f1
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 169 deletions.
9 changes: 0 additions & 9 deletions demos/heatmap.html
Expand Up @@ -42,15 +42,6 @@
}
})
.render();

/* scene.PointLayer({
zIndex: 3
})
.source(data)
.shape('2d:circle')
.size(2)
.color('#EE2C2C')
.render();*/
});
});
</script>
Expand Down
@@ -1,6 +1,6 @@
import BufferBase from './bufferBase';
import { colorScales } from '../../attr/colorscales';
import * as THREE from '../../core/three';
import BufferBase from '../bufferBase';
import { colorScales } from '../../../attr/colorscales';
import * as THREE from '../../../core/three';


export default class HeatmapBuffer extends BufferBase {
Expand Down
55 changes: 0 additions & 55 deletions src/layer/heatmap.js

This file was deleted.

144 changes: 44 additions & 100 deletions src/layer/heatmapLayer.js
@@ -1,111 +1,55 @@
import Layer from '../core/layer';
import HeatmapBuffer from '../geom/buffer/heatmap';
import { createColorRamp } from '../geom/buffer/heatmap';
import { HeatmapIntensityMaterial, HeatmapColorizeMaterial } from '../geom/material/heatmapMateial';
import Renderpass from '../core/engine/renderpass';
import * as THREE from '../core/three';

export default class HeatmapLayer extends Layer {
import gridBuffer from '../geom/buffer/heatmap/grid';
import DrawGrid from './render/heatmap/gird';
import DrawHexagon from './render/heatmap/hexagon';
import drawHeatmap from './render/heatmap/heatmap';
import hexagonBuffer from '../geom/buffer/heatmap/hexagon';

export default class HeatMapLayer extends Layer {
shape(type) {
this.shapeType = type;
return this;
}
render() {
this.init();
const bbox = this._calBoundingBox(this.layerData);
const colors = this.get('styleOptions').rampColors;
this.colorRamp = createColorRamp(colors);
this._createIntensityPass(bbox);
this._createColorizePass(bbox);
this._prepareRender();
return this;
}

_createIntensityPass(bbox) {
const style = this.get('styleOptions');
const data = this.layerData;
// get attributes data
const buffer = new HeatmapBuffer({
data
});
const attributes = buffer.attributes;
// create geometery
const geometry = new THREE.BufferGeometry();
// geometry.setIndex(attributes.indices);
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.vertices, 3));
geometry.addAttribute('a_dir', new THREE.Float32BufferAttribute(attributes.dirs, 2));
geometry.addAttribute('a_weight', new THREE.Float32BufferAttribute(attributes.weights, 1));
// set material
const material = new HeatmapIntensityMaterial({
intensity: style.intensity,
radius: style.radius,
zoom: this.scene.getZoom()
});
const mesh = new THREE.Mesh(geometry, material);
// set camera
const passOrth = new THREE.OrthographicCamera(bbox.width / -2, bbox.width / 2, bbox.height / 2, bbox.height / -2, 1, 10000);
passOrth.position.set(bbox.minX + bbox.width / 2, bbox.minY + bbox.height / 2, 1000);
// renderpass
const renderpass = new Renderpass({
renderer: this.scene._engine._renderer,
camera: passOrth,
size: {
width: 10000,
height: 10000 * (bbox.height / bbox.width)
},
clear: {
clearColor: 0x000000,
clearAlpha: 1.0
}
});
renderpass.add(mesh);
renderpass.render();
this.intensityPass = renderpass;
const scene = this.scene;
render();
function render() {
requestAnimationFrame(render);
renderpass.render();
mesh.material.uniforms.u_zoom.value = scene.getZoom();
_prepareRender() {
this.init();
this.type = 'heatmap';
switch (this.shapeType) {
case 'grid' :
this._drawGrid();
break;
case 'hexagon' :
this._drawHexagon();
break;
default:
drawHeatmap(this);
}
}
_createColorizePass(bbox) {
// create plane geometry
const geometery = new THREE.PlaneBufferGeometry(bbox.width, bbox.height);
const material = new HeatmapColorizeMaterial({
texture: this.intensityPass.texture,
colorRamp: this.colorRamp
});
const mesh = new THREE.Mesh(geometery, material);
mesh.position.set(bbox.minX + bbox.width / 2, bbox.minY + bbox.height / 2, 0.0);
this.add(mesh);
_drawHexagon() {
const style = this.get('styleOptions');
const { radius } = this.layerSource.data;
this._buffer = new hexagonBuffer(this.layerData);
const config = {
...style,
radius
};
const Mesh = new DrawHexagon(this._buffer, config);
this.add(Mesh);
}

_calBoundingBox(data) {
let minX = Infinity;
let minY = Infinity;
let maxX = -Infinity;
let maxY = -Infinity;
for (let i = 0; i < data.length; i++) {
const p = data[i].coordinates;
if (p[0] < minX) {
minX = p[0];
} else if (p[0] > maxX) {
maxX = p[0];
}
if (p[1] < minY) {
minY = p[1];
} else if (p[1] > maxY) {
maxY = p[1];
}
}
const width = maxX - minX;
const height = maxY - minY;

return {
minX,
maxX,
minY,
maxY,
width,
height
_drawGrid() {
const style = this.get('styleOptions');
const { xOffset, yOffset } = this.layerSource.data;
this._buffer = new gridBuffer(this.layerData);
const config = {
...style,
xOffset,
yOffset
};
const girdMesh = new DrawGrid(this._buffer, config);
this.add(girdMesh);
}


}
2 changes: 0 additions & 2 deletions src/layer/index.js
Expand Up @@ -5,14 +5,12 @@ import LineLayer from './lineLayer';
import ImageLayer from './imageLayer';
import RasterLayer from './rasterLayer';
import HeatmapLayer from './heatmapLayer';
import HeatMapLayer from './heatmap';

registerLayer('PolygonLayer', PolygonLayer);
registerLayer('PointLayer', PointLayer);
registerLayer('LineLayer', LineLayer);
registerLayer('ImageLayer', ImageLayer);
registerLayer('RasterLayer', RasterLayer);
registerLayer('HeatMapLayer', HeatMapLayer);
registerLayer('HeatmapLayer', HeatmapLayer);

export { LAYER_MAP } from './factory';
Expand Down
105 changes: 105 additions & 0 deletions src/layer/render/heatmap/heatmap.js
@@ -0,0 +1,105 @@
import HeatmapBuffer from '../../../geom/buffer/heatmap/heatmap';
import { createColorRamp } from '../../../geom/buffer/heatmap/heatmap';
import { HeatmapIntensityMaterial, HeatmapColorizeMaterial } from '../../../geom/material/heatmapMateial';
import Renderpass from '../../../core/engine/renderpass';
import * as THREE from '../../../core/three';

export default function drawHeatmap(layer) {
const bbox = calBoundingBox(layer.layerData);
const colors = layer.get('styleOptions').rampColors;
layer.colorRamp = createColorRamp(colors);
createIntensityPass(layer, bbox);
createColorizePass(layer, bbox);
}

function createIntensityPass(layer, bbox) {
const style = layer.get('styleOptions');
const data = layer.layerData;
// get attributes data
const buffer = new HeatmapBuffer({
data
});
const attributes = buffer.attributes;
// create geometery
const geometry = new THREE.BufferGeometry();
// geometry.setIndex(attributes.indices);
geometry.addAttribute('position', new THREE.Float32BufferAttribute(attributes.vertices, 3));
geometry.addAttribute('a_dir', new THREE.Float32BufferAttribute(attributes.dirs, 2));
geometry.addAttribute('a_weight', new THREE.Float32BufferAttribute(attributes.weights, 1));
// set material
const material = new HeatmapIntensityMaterial({
intensity: style.intensity,
radius: style.radius,
zoom: layer.scene.getZoom()
});
const mesh = new THREE.Mesh(geometry, material);
// set camera
const passOrth = new THREE.OrthographicCamera(bbox.width / -2, bbox.width / 2, bbox.height / 2, bbox.height / -2, 1, 10000);
passOrth.position.set(bbox.minX + bbox.width / 2, bbox.minY + bbox.height / 2, 1000);
// renderpass
const renderpass = new Renderpass({
renderer: layer.scene._engine._renderer,
camera: passOrth,
size: {
width: 10000,
height: 10000 * (bbox.height / bbox.width)
},
clear: {
clearColor: 0x000000,
clearAlpha: 1.0
}
});
renderpass.add(mesh);
renderpass.render();
layer.intensityPass = renderpass;
const scene = layer.scene;
render();
function render() {
requestAnimationFrame(render);
renderpass.render();
mesh.material.uniforms.u_zoom.value = scene.getZoom();
}
}
function createColorizePass(layer, bbox) {
// create plane geometry
const geometery = new THREE.PlaneBufferGeometry(bbox.width, bbox.height);
const material = new HeatmapColorizeMaterial({
texture: layer.intensityPass.texture,
colorRamp: layer.colorRamp
});
const mesh = new THREE.Mesh(geometery, material);
mesh.position.set(bbox.minX + bbox.width / 2, bbox.minY + bbox.height / 2, 0.0);
layer.add(mesh);
}

function calBoundingBox(data) {
let minX = Infinity;
let minY = Infinity;
let maxX = -Infinity;
let maxY = -Infinity;
for (let i = 0; i < data.length; i++) {
const p = data[i].coordinates;
if (p[0] < minX) {
minX = p[0];
} else if (p[0] > maxX) {
maxX = p[0];
}
if (p[1] < minY) {
minY = p[1];
} else if (p[1] > maxY) {
maxY = p[1];
}
}
const width = maxX - minX;
const height = maxY - minY;

return {
minX,
maxX,
minY,
maxY,
width,
height
};
}

0 comments on commit 109f3f1

Please sign in to comment.