三维地图前端arcgis_arcgis for javascript第二篇---三维地图上呈现热力图

本文介绍了如何在Vue项目中利用ArcGIS的JavaScript API,在三维地图上展示热力图。通过创建CanvasLayer,转换数据并设置渐变色带,实现了地图相机移动时热力图的实时更新。示例代码中使用了dojo的lang.hitch方法,并给出了配置热力图颜色和半径的示例。
摘要由CSDN通过智能技术生成

结合vue。

官方给出的热力图实例不满足需求要求在三维场景下展示,而官方的热力图仅支持MapView。

我这里的代码就是搬过来用的,但是,照搬的有问题,找了很有的原因原来是dojo里面的lang.hitch这个找不着,于是查阅了一些资料,这里参考的是这一篇

loadModules([

"dojo/_base/lang",    //重要

"esri/Map",

"esri/views/MapView",

"esri/views/SceneView"

], option)

.then(([

lang,

Map, MapView,

SceneView

]) => {

const map = new Map({ //实例化地图

basemap: "satellite",

ground: "world-elevation",

logo: false

});

const view = new SceneView({ //实例化地图视图

container: "viewDiv",

map,

camera: {

position: {

x: 121.40105,

y: 31.40200,

z: 5000

},

tilt: 0

}

});

/**封装热力图*/

class HeatLayer {

constructor(obj) {

this.view = obj.view

this.config = obj.config

this.canvas = null

this.context = null

this.minnum = 1

this.maxnum = 1

this.visible = true

this.createCanvas()

}

/*创建Canvaslayer的容器canvas,添加到map的layers下面*/

createCanvas() {

let canvas = document.createElement('canvas');

canvas.width = this.view.width;

canvas.height = this.view.height;

canvas.setAttribute("id", "heatmap");

canvas.style.position = "absolute";

canvas.style.top = 0;

canvas.style.left = 0;

let parent = document.getElementsByClassName("esri-view-surface")[0];

parent.appendChild(canvas);

this.canvas = canvas;

this.context = document.getElementById("heatmap").getContext('2d');

this.startMapEventListeners()

}

/*转换数据*/

convertHeatmapData(data) {

var heatPluginData = [];

for (let i = 0; i < data.length; i++) {

let screenpoint = this.view.toScreen(new Point({

longitude: data[i][0],

latitude: data[i][1],

}));

//console.log(screenpoint)

// 判断数据是否带有权重,未带有权重属性是默认为1

if (data[0].length == 3) {

heatPluginData.push([Math.round(screenpoint.x), Math.round(screenpoint.y), data[i][2]]);

} else {

heatPluginData.push([Math.round(screenpoint.x), Math.round(screenpoint.y), 1]);

}

if (this.minnum > data[i][2]) {

this.minnum = data[i][2]

}

if (this.maxnum < data[i][2]) {

this.maxnum = data[i][2]

}

}

return {

points: heatPluginData,

min: this.minnum,

max: this.maxnum

};

}

//添加点数据

addPoint(data) {

this.data = data;

let points = this.convertHeatmapData(data);

//console.log(points)

points.points.forEach(point => {

this.context.beginPath();

let alpha = (point[2] - points.min) / (points.max - points.min);

this.context.globalAlpha = alpha;

this.context.arc(point[0], point[1], this.config.radius, 0, Math.PI * 2, true);

//绘制一个放射渐变样式的圆

let gradient = this.context.createRadialGradient(point[0], point[1], 0, point[0], point[1], this.config.radius);

gradient.addColorStop(0, 'rgba(0,0,0,1)');

gradient.addColorStop(1, 'rgba(0,0,0,0)');

this.context.fillStyle = gradient;

this.context.closePath();

this.context.fill();

});

this.MapColors();

//console.log('haol')

}

//设置渐变色带

getColorPaint() {

let paletteCanvas = document.createElement('canvas');

let paletteCtx = paletteCanvas.getContext('2d');

let gradientConfig = this.config.gradient;

paletteCanvas.width = 256

paletteCanvas.height = 1

let gradient = paletteCtx.createLinearGradient(0, 0, 256, 1);

for (let key in gradientConfig) {

gradient.addColorStop(key, gradientConfig[key])

}

paletteCtx.fillStyle = gradient;

paletteCtx.fillRect(0, 0, 256, 1);

return paletteCtx.getImageData(0, 0, 256, 1).data

}

//映射颜色

MapColors() {

let palette = this.getColorPaint();

let img = this.context.getImageData(0, 0, this.canvas.width, this.canvas.height)

let imgData = img.data;

for (let i = 0; i < imgData.length; i++) {

let alpha = imgData[i];

let offset = alpha * 4;

if (!offset) {

continue

}

//映射颜色RGB值

imgData[i - 3] = palette[offset];

imgData[i - 2] = palette[offset + 1];

imgData[i - 1] = palette[offset + 2];

}

this.context.putImageData(img, 0, 0, 0, 0, this.canvas.width, this.canvas.height);

}

/*刷新layer*/

freshenLayer() {

this.clearCanvas();

this.addPoint(this.data);

}

/*清除渲染效果*/

clearCanvas() {

this.context.clearRect(0, 0, this.view.width, this.view.height);

}

/*添加监听*/

startMapEventListeners() {

let view = this.view;

view.watch("extent", lang.hitch(this, ()=>{

if (!this.visible) return;

this.freshenLayer();

//console.log('执行了吗')

}));

view.watch("camera", lang.hitch(this, ()=>{

if (!this.visible) return;

this.freshenLayer();

//console.log('执行了吗')

}));

}

}

//配置热力图的颜色、半径

var config = {

radius: 15,

gradient: {

'0.2':'rgba(0,0,255,0.2)',

'0.3':'rgba(43,111,231,0.3)',

'0.4':'rgba(2,192,241,0.4)',

'0.6':'rgba(44,222,148,0.6)',

'0.8':'rgba(254,237,83,0.8)',

'0.95':'rgba(255,118,50,0.9)',

'1':'rgba(255,64,28,1)'

}

};

//定时器,等地图初始化完成再绘制热力图,要不然找不到view,可以将定时器里面的内容放到view.when()内部

setTimeout(()=>{

var heatmap = new HeatLayer({

view,

config

});

heatmap.addPoint([["118.66124335378005","28.92588513213444",40],["118.08115584871544","29.04952406765118",66],["118.38722644164108","29.059406055009923",32],["118.41649535128697","29.135673493885232",80],["118.55019107002441","29.300640724771107",25],["118.57374080604751","28.685810835578355",76],["118.70453463048833","28.824715624332843",58],["118.86481914446486","28.946912041540134",67],["118.8727276271301","28.972530779387345",100]]);

},5000)

}).catch((err) => {

console.warn(err)

});

效果如:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值