ArcGIS API for JavaScript 是ESRI 推出面向 WEB 端 GIS API,可构建引人注目的web 地图应用程序,通过交互式用户体验和令人惊叹的2D和3D可视化来释放地理时空大数据的潜力。同时提供了一个轻量级接口来访问SceneView的WebGL上下文,因此可以创建与内置层相同的方式与场景交互的自定义可视化。开发人员可以直接编写WebGL代码,也可以与第三方WebGL库集成
基于three.js 和arcgis js api webgl 三维热力图heatmap3dRenderer 扩展类
define(['dojo/_base/declare',"esri/Graphic","esri/views/3d/externalRenderers","utils/Intensity"],function(
declare,
Graphic,
externalRenderers,
Intensity
){
varTHREE= window.THREE;varCANVAS_MAX_SIZE=2048;var heatmap3dRenderer =declare([],{
constructor:function(view, data, options){
this.view = view;if(!Array.isArray(data)){
this.data =[data];}else{
this.data = data;}constOPTIONS={
interactive:false,
min:0,
max:100,
size:13,
gradient:{
0.25:'rgb(0,0,255)',0.55:'rgb(0,255,0)',0.85:'yellow',1.0:'rgb(255,0,0)'},
gridScale:0.5}this.options =this.extend({
},OPTIONS, options,{
points:this.data
});},
setup:function(context){
this.renderer =newTHREE.WebGLRenderer({
context: context.gl,// 可用于将渲染器附加到已有的渲染环境(RenderingContext)中
premultipliedAlpha:false,// renderer是否假设颜色有 premultiplied alpha. 默认为true});this.renderer.setPixelRatio(window.devicePixelRatio);// 设置设备像素比。通常用于避免HiDPI设备上绘图模糊this.renderer.setViewport(0,0,this.view.width,this.view.height);// 视口大小设置// Make sure it does not clear anything before renderingthis.renderer.autoClear =false;this.renderer.autoClearDepth =false;this.renderer.autoClearColor =false;// this.renderer.autoClearStencil = false;// The ArcGIS JS API renders to custom offscreen buffers, and not to the default framebuffers.// We have to inject this bit of code into the three.js runtime in order for it to bind those// buffers instead of the default ones.var originalSetRenderTarget =this.renderer.setRenderTarget.bind(this.renderer);this.renderer.setRenderTarget=function(target){
originalSetRenderTarget(target);if(target ==null){
context.bindRenderTarget();}};this.scene =newTHREE.Scene();this.camera =newTHREE.PerspectiveCamera();const axesHelper =newTHREE.AxesHelper(1);
axesHelper.position.copy(1000000,100000,100000);this.scene.add(axesHelper);this._setupScene(context);},
transparentObject:function(geometry, material){
var obj =newTHREE.Object3D();var mesh =newTHREE.Mesh(geometry, material);
mesh.material.side =THREE.BackSide;
mesh.renderOrder =0;
obj.add(mesh)var mesh =newTHREE.Mesh(geometry, material.clone());
mesh.material.side =THREE.FrontSide;// front faces
mesh.renderOrder =1;
obj.add(mesh);return obj
},
_setupScene:function(context){
var scope =this;let minX =Infinity,
minY =Infinity,
maxX =-Infinity,
maxY =-Infinity;const vs =[];for(let i =0, len = scope.data.length; i < len; i++){
const{
coordinate,
lnglat,
xy
}= scope.data[i];const coord = coordinate || lnglat || xy;if(!coord){
console.warn('not find coordinate');continue;}const v = scope.coordinateToVector3(coord);
vs.push(v);const{
x,
y
}= v;
minX = Math.min(minX, x);
minY = Math.min(minY, y);
maxX = Math.max(maxX, x);
maxY = Math.max(maxY, y);}let{
gridScale,
altitude
}