From ea0e544ff9116f9c3191e2711f5242c7da9d0f26 Mon Sep 17 00:00:00 2001
From: "mipha.ly" <mipha.ly@alibaba-inc.com>
Date: Thu, 14 Mar 2019 14:35:59 +0800
Subject: [PATCH] =?UTF-8?q?fix(heat-map):=20=E6=B8=B2=E6=9F=93=E9=80=BB?=
 =?UTF-8?q?=E8=BE=91=20&=20bbox?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 demos/heatmap.html                  | 65 +++++++++++++++++++++++++++--
 src/core/layer.js                   | 10 ++++-
 src/layer/heatmapLayer.js           |  8 +++-
 src/layer/render/heatmap/heatmap.js | 44 +++++++++++--------
 4 files changed, 104 insertions(+), 23 deletions(-)

diff --git a/demos/heatmap.html b/demos/heatmap.html
index 23a2d6464a..84bd74387e 100644
--- a/demos/heatmap.html
+++ b/demos/heatmap.html
@@ -18,10 +18,69 @@
 <script src="./assets/dat.gui.min.js"></script>
 <script src="../build/L7.js"></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({
   id: 'map',
   mapStyle: 'dark', // 样式URL
-  center: [ -155, 60 ],
+  center: [ 120.5751451280382, 29.98157497829861 ],
   pitch: 0,
   zoom: 4.5
 });
@@ -31,8 +90,8 @@ scene.on('loaded', () => {
     scene.HeatmapLayer({
       zIndex: 2
     })
-    .source(data)
-    .size('mag', [ 0, 1 ]) // weight映射通道
+    .source(data1)
+    .size('value', [ 0, 1 ]) // weight映射通道
     .style({
       intensity: 3,
       radius: 20,
diff --git a/src/core/layer.js b/src/core/layer.js
index 90f49cc2d3..ef474d51a0 100644
--- a/src/core/layer.js
+++ b/src/core/layer.js
@@ -89,7 +89,10 @@ export default class Layer extends Base {
       const zoom = this.scene.getZoom();
       object.material.setUniformsValue('u_time', this.scene._engine.clock.getElapsedTime());
       object.material.setUniformsValue('u_zoom', zoom);
+    };
 
+    object.onAfterRender = () => { // 每次渲染后改变状态
+      this.afterRender();
     };
     // 更新
     if (this._needUpdateFilter) { // 动态更新数据过滤
@@ -120,7 +123,6 @@ export default class Layer extends Base {
     // }).then(data => {
     //   console.log(data);
     // });
-
     return this;
   }
   color(field, values) {
@@ -624,7 +626,11 @@ export default class Layer extends Base {
     this.scene.off('zoomchange', this._zoomchangeHander);
     this.destroyed = true;
   }
-  _preRender() {
+  preRender() {
+
+  }
+
+  afterRender() {
 
   }
 }
diff --git a/src/layer/heatmapLayer.js b/src/layer/heatmapLayer.js
index e6e1bf5724..203814e5b6 100644
--- a/src/layer/heatmapLayer.js
+++ b/src/layer/heatmapLayer.js
@@ -2,7 +2,7 @@ import Layer from '../core/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 { drawHeatmap, updateIntensityPass } from './render/heatmap/heatmap';
 import hexagonBuffer from '../geom/buffer/heatmap/hexagon';
 
 export default class HeatMapLayer extends Layer {
@@ -56,4 +56,10 @@ export default class HeatMapLayer extends Layer {
     this.add(girdMesh);
   }
 
+  afterRender() {
+    if (this.shapeType !== 'grid' || this.shapeType !== 'hexagon') {
+      updateIntensityPass(this);
+    }
+  }
+
 }
diff --git a/src/layer/render/heatmap/heatmap.js b/src/layer/render/heatmap/heatmap.js
index 07b7bb4cd4..72c90bbdb6 100644
--- a/src/layer/render/heatmap/heatmap.js
+++ b/src/layer/render/heatmap/heatmap.js
@@ -4,8 +4,9 @@ import { HeatmapIntensityMaterial, HeatmapColorizeMaterial } from '../../../geom
 import Renderpass from '../../../core/engine/renderpass';
 import * as THREE from '../../../core/three';
 
-export default function drawHeatmap(layer) {
+export function drawHeatmap(layer) {
   const bbox = calBoundingBox(layer.layerData);
+  layer.dataBbox = bbox;
   const colors = layer.get('styleOptions').rampColors;
   layer.colorRamp = createColorRamp(colors);
   createIntensityPass(layer, bbox);
@@ -33,15 +34,15 @@ function createIntensityPass(layer, bbox) {
     zoom: layer.scene.getZoom()
   });
   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);
   passOrth.position.set(bbox.minX + bbox.width / 2, bbox.minY + bbox.height / 2, 1000);
-    // renderpass
+  // renderpass
   const renderer = layer.scene._engine._renderer;
   // 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');
-  gl.getExtension('OES_texture_float_linear');
+  gl.getExtension('OES_texture_float_linear');*/
   const renderpass = new Renderpass({
     renderer,
     camera: passOrth,
@@ -66,18 +67,21 @@ function createIntensityPass(layer, bbox) {
   renderpass.add(mesh);
   renderpass.render();
   layer.intensityPass = renderpass;
-  const scene = layer.scene;
-  render();
-  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();
-  }
+  layer.intensityMesh = mesh;
+  updateIntensityPass(layer);
 }
+
+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) {
     // create plane geometry
   const geometery = new THREE.PlaneBufferGeometry(bbox.width, bbox.height);
@@ -108,9 +112,16 @@ function calBoundingBox(data) {
       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 height = maxY - minY;
 
+
   return {
     minX,
     maxX,
@@ -120,4 +131,3 @@ function calBoundingBox(data) {
     height
   };
 }
-