fix(heat-map): 渲染逻辑 & bbox

This commit is contained in:
mipha.ly 2019-03-14 14:35:59 +08:00
parent ae0d5cf9cc
commit b0df153670
4 changed files with 104 additions and 23 deletions

View File

@ -18,10 +18,69 @@
<script src="./assets/dat.gui.min.js"></script> <script src="./assets/dat.gui.min.js"></script>
<script src="../build/L7.js"></script> <script src="../build/L7.js"></script>
<script> <script>
const data1 = {
type: 'FeatureCollection',
features: [{
type: 'Feature',
properties: {
value: 550,
address: '浙江省'
},
geometry: {
type: 'Point',
coordinates: [ 120.5751451280382, 29.98157497829861 ]
}
},
{
type: 'Feature',
properties: {
value: 2100,
address: '广东省'
},
geometry: {
type: 'Point',
coordinates: [ 113.818805, 22.664838 ]
}
},
{
type: 'Feature',
properties: {
value: 420,
address: '北京'
},
geometry: {
type: 'Point',
coordinates: [ 116.40899441189237, 39.940829535590275 ]
}
},
{
type: 'Feature',
properties: {
value: 2000,
address: '辽宁省'
},
geometry: {
type: 'Point',
coordinates: [ 122.689323, 40.80727 ]
}
},
{
type: 'Feature',
properties: {
value: 7000,
address: '河南省'
},
geometry: {
type: 'Point',
coordinates: [ 112.903898, 34.075266 ]
}
}
]
};
const scene = new L7.Scene({ const scene = new L7.Scene({
id: 'map', id: 'map',
mapStyle: 'dark', // 样式URL mapStyle: 'dark', // 样式URL
center: [ -155, 60 ], center: [ 120.5751451280382, 29.98157497829861 ],
pitch: 0, pitch: 0,
zoom: 4.5 zoom: 4.5
}); });
@ -31,8 +90,8 @@ scene.on('loaded', () => {
scene.HeatmapLayer({ scene.HeatmapLayer({
zIndex: 2 zIndex: 2
}) })
.source(data) .source(data1)
.size('mag', [ 0, 1 ]) // weight映射通道 .size('value', [ 0, 1 ]) // weight映射通道
.style({ .style({
intensity: 3, intensity: 3,
radius: 20, radius: 20,

View File

@ -89,7 +89,10 @@ export default class Layer extends Base {
const zoom = this.scene.getZoom(); const zoom = this.scene.getZoom();
object.material.setUniformsValue('u_time', this.scene._engine.clock.getElapsedTime()); object.material.setUniformsValue('u_time', this.scene._engine.clock.getElapsedTime());
object.material.setUniformsValue('u_zoom', zoom); object.material.setUniformsValue('u_zoom', zoom);
};
object.onAfterRender = () => { // 每次渲染后改变状态
this.afterRender();
}; };
// 更新 // 更新
if (this._needUpdateFilter) { // 动态更新数据过滤 if (this._needUpdateFilter) { // 动态更新数据过滤
@ -120,7 +123,6 @@ export default class Layer extends Base {
// }).then(data => { // }).then(data => {
// console.log(data); // console.log(data);
// }); // });
return this; return this;
} }
color(field, values) { color(field, values) {
@ -624,7 +626,11 @@ export default class Layer extends Base {
this.scene.off('zoomchange', this._zoomchangeHander); this.scene.off('zoomchange', this._zoomchangeHander);
this.destroyed = true; this.destroyed = true;
} }
_preRender() { preRender() {
}
afterRender() {
} }
} }

View File

@ -2,7 +2,7 @@ import Layer from '../core/layer';
import gridBuffer from '../geom/buffer/heatmap/grid'; import gridBuffer from '../geom/buffer/heatmap/grid';
import DrawGrid from './render/heatmap/gird'; import DrawGrid from './render/heatmap/gird';
import DrawHexagon from './render/heatmap/hexagon'; import DrawHexagon from './render/heatmap/hexagon';
import drawHeatmap from './render/heatmap/heatmap'; import { drawHeatmap, updateIntensityPass } from './render/heatmap/heatmap';
import hexagonBuffer from '../geom/buffer/heatmap/hexagon'; import hexagonBuffer from '../geom/buffer/heatmap/hexagon';
export default class HeatMapLayer extends Layer { export default class HeatMapLayer extends Layer {
@ -56,4 +56,10 @@ export default class HeatMapLayer extends Layer {
this.add(girdMesh); this.add(girdMesh);
} }
afterRender() {
if (this.shapeType !== 'grid' || this.shapeType !== 'hexagon') {
updateIntensityPass(this);
}
}
} }

View File

@ -4,8 +4,9 @@ import { HeatmapIntensityMaterial, HeatmapColorizeMaterial } from '../../../geom
import Renderpass from '../../../core/engine/renderpass'; import Renderpass from '../../../core/engine/renderpass';
import * as THREE from '../../../core/three'; import * as THREE from '../../../core/three';
export default function drawHeatmap(layer) { export function drawHeatmap(layer) {
const bbox = calBoundingBox(layer.layerData); const bbox = calBoundingBox(layer.layerData);
layer.dataBbox = bbox;
const colors = layer.get('styleOptions').rampColors; const colors = layer.get('styleOptions').rampColors;
layer.colorRamp = createColorRamp(colors); layer.colorRamp = createColorRamp(colors);
createIntensityPass(layer, bbox); createIntensityPass(layer, bbox);
@ -33,15 +34,15 @@ function createIntensityPass(layer, bbox) {
zoom: layer.scene.getZoom() zoom: layer.scene.getZoom()
}); });
const mesh = new THREE.Mesh(geometry, material); const mesh = new THREE.Mesh(geometry, material);
// set camera // set camera
const passOrth = new THREE.OrthographicCamera(bbox.width / -2, bbox.width / 2, bbox.height / 2, bbox.height / -2, 1, 10000); 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); passOrth.position.set(bbox.minX + bbox.width / 2, bbox.minY + bbox.height / 2, 1000);
// renderpass // renderpass
const renderer = layer.scene._engine._renderer; const renderer = layer.scene._engine._renderer;
// get extension for bilinear texture interpolation:https://threejs.org/docs/#api/en/textures/DataTexture // get extension for bilinear texture interpolation:https://threejs.org/docs/#api/en/textures/DataTexture
const gl = renderer.domElement.getContext('webgl') || /* const gl = renderer.domElement.getContext('webgl') ||
renderer.domElement.getContext('experimental-webgl'); renderer.domElement.getContext('experimental-webgl');
gl.getExtension('OES_texture_float_linear'); gl.getExtension('OES_texture_float_linear');*/
const renderpass = new Renderpass({ const renderpass = new Renderpass({
renderer, renderer,
camera: passOrth, camera: passOrth,
@ -66,18 +67,21 @@ function createIntensityPass(layer, bbox) {
renderpass.add(mesh); renderpass.add(mesh);
renderpass.render(); renderpass.render();
layer.intensityPass = renderpass; layer.intensityPass = renderpass;
const scene = layer.scene; layer.intensityMesh = mesh;
render(); updateIntensityPass(layer);
function render() {
requestAnimationFrame(render);
const zoom = scene.getZoom();
mesh.material.uniforms.u_zoom.value = zoom;
const passWidth = Math.min(10000, Math.pow(zoom, 2.0) * 300);
const passHeight = passWidth * (bbox.height / bbox.width);
renderpass.pass.setSize(passWidth, passHeight);
renderpass.render();
}
} }
export function updateIntensityPass(layer) {
const mesh = layer.intensityMesh;
const zoom = layer.scene.getZoom();
const bbox = layer.dataBbox;
mesh.material.uniforms.u_zoom.value = zoom;
const passWidth = Math.min(5000, Math.pow(zoom, 2.0) * 300);
const passHeight = passWidth * (bbox.height / bbox.width);
layer.intensityPass.pass.setSize(passWidth, passHeight);
layer.intensityPass.render();
}
function createColorizePass(layer, bbox) { function createColorizePass(layer, bbox) {
// create plane geometry // create plane geometry
const geometery = new THREE.PlaneBufferGeometry(bbox.width, bbox.height); const geometery = new THREE.PlaneBufferGeometry(bbox.width, bbox.height);
@ -108,9 +112,16 @@ function calBoundingBox(data) {
maxY = p[1]; maxY = p[1];
} }
} }
minX -= ((maxX - minX) * 0.5);
maxX += ((maxX - minX) * 0.5);
minY -= ((maxY - minY) * 0.5);
maxY -= ((maxY - minY) * 0.5);
const width = maxX - minX; const width = maxX - minX;
const height = maxY - minY; const height = maxY - minY;
return { return {
minX, minX,
maxX, maxX,
@ -120,4 +131,3 @@ function calBoundingBox(data) {
height height
}; };
} }