mirror of https://gitee.com/antv-l7/antv-l7
fix(heat-map): 渲染逻辑 & bbox
This commit is contained in:
parent
ae0d5cf9cc
commit
b0df153670
|
@ -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,
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue