cesium热力图小结

      热力图常用于展示在某个地理区域内,数据点(如人群密度、交通流量、气象数据等)的分布情况。颜色的变化表示数据强度的变化。例如,红色表示较高的密度,绿色表示较低的密度。

这里我一共使用了两种方式实现热力图方式

第一种:heatmap.js库很久没维护,不建议使用

存在边界问题,对于四至点的坐标,这里笔者以画图为例,只会渲染创建的canvas边界内容导致热力图失真

//创建热力图对象
let heatmapInstance = h337.create({
    container: document.querySelector('#cesiumContainer'),
    radius: 25, //给定半径
    maxOpacity: 0.8,
    minOpacity: 0,
});
let heatmapData = [{
    "lng": 116.191031,
    "lat": 39.988585,
    "count": 10
},
...
];
let xMin = 180, yMin = 90, xMax = 0, yMax = 0;
//获取热力图数据的矩形范围
heatmapData.forEach(data => {
    xMin = Math.min(data.lng, xMin);
    yMin = Math.min(data.lat, yMin);
    xMax = Math.max(data.lng, xMax);
    yMax = Math.max(data.lat, yMax);
})
//热力图数据矩形范围的长和宽
let w = xMax - xMin;
let h = yMax - yMin;
//定义用于绘制热力图画布的宽高
let canvasWidth = w * 500;
let canvasHeight = h * 500;
//将经纬度数据坐标转换到画布的坐标系上
let convertData = [];
heatmapData.forEach(data => {
    let x = (data.lng - xMin) / w * canvasWidth;
    let y = -(data.lat - yMax) / h * canvasHeight;
    convertData.push({
        x: x,
        y: y,
        value: data.count
    })
})
heatmapInstance.setData({
    data: convertData,
    max:100
});
let eneity = viewer.entities.add({
    rectangle: {
        coordinates: rect,
        material:  heatmapInstance._renderer.canvas
    }
})

第二种:cesium-heatmap.js(推荐使用)

调用

     let arr = [
        // { x: 120.30693844543929, y: 37.620287586410306, value: 100 },
        // { x: 120.28656436922547, y: 37.57640461112017, value: 120 },
        // { x: 120.28488071005563, y: 37.57589062801232, value: 60 },
        { x: 120.28509677734766, y: 37.57769661997805, value: 50 },
        { x: 120.21137298932902, y: 37.58452670037166, value: 70 },
        { x: 120.28711110984104, y: 37.577876694578165, value: 100 },
        { x: 120.20392240925057, y: 37.61653805327714, value: 90 },
        { x: 120.25916108392813, y: 37.53335589495749, value: 40 },
      ];
      //初始化热力图
      this.heatMap = new HeatMap(window.$viewer, arr);
      //创建热力图
      this.heatMap.create();

 封装的热力图类,需要安装turf库以及cesium-heatmap.js

/* 
viewer:Cesium.Viewer实例
data:热力图数据
数据格式:
      let arr = [
      {x: 120.30693844543929, y: 37.620287586410306, value: 100},
      {x: 120.28656436922547, y: 37.57640461112017, value: 120},
      {x: 120.28488071005563, y: 37.57589062801232, value: 60},
      {x: 120.28509677734766, y: 37.57769661997805, value: 50},
      {x: 120.21137298932902, y: 37.58452670037166, value: 70},
      {x: 120.28711110984104, y: 37.577876694578165, value: 100},
      {x: 120.20392240925057, y: 37.61653805327714, value: 90},
      {x: 120.25916108392813, y: 37.53335589495749, value: 40}
      ];
options:热力图配置项
maxOpacity:热力图最大透明度
gradient:热力图渐变颜色

*/
//创建热力图类方法
export default class HeatMap {
    constructor(viewer, data, options = {
        maxOpacity: 0.7,
        gradient: {
            ".3": "#d9e7fc",
            ".65": "#2a7aed",
            ".8": "#fbd801",
            ".95": "#18c3a1",
        },

    }) {
        this.viewer = viewer;
        this.options = options;
        this.valueMin = null;
        this.valueMax = null;
        this.data = data
        //根据传入数据求出边界范围
        const { bounds, valueMin, valueMax } = this.initBounds(data)
        this.valueMin = valueMin
        this.valueMax = valueMax
        this.bounds = bounds
        this.heatMap=null
    }
    initBounds(arr) {
        if (!Array.isArray(arr) || arr.length <= 1) {
            // console.warn("热力图数据为空或格式不正确,返回默认边界范围");
            return {
                bounds: { west: -180, east: 180, south: -90, north: 90 },
                valueMax: Infinity,
                valueMin: -Infinity,
            };
        }

        let xMax = -180;
        let xMin = 180;
        let yMax = -90;
        let yMin = 90;
        let valueMax = -Infinity;
        let valueMin = Infinity;

        for (let i = 0; i < arr.length; i++) {
            xMax = Math.max(xMax, arr[i].x);
            xMin = Math.min(xMin, arr[i].x);
            yMax = Math.max(yMax, arr[i].y);
            yMin = Math.min(yMin, arr[i].y);
            valueMax = Math.max(valueMax, arr[i].value);
            valueMin = Math.min(valueMin, arr[i].value);
        }

        return {
            bounds: { 'west': xMin, 'east': xMax, 'south': yMin, 'north': yMax }, // 边界范围
            valueMax,
            valueMin,
        };
    }
    //创建热力图层
    create() {
        this.heatMap = CesiumHeatmap.create(this.viewer, this.bounds, this.options);
        this.heatMap.setWGS84Data(this.valueMin, this.valueMax, this.data);
        let arr=this.data.map(item=>{
            return [item.x,item.y]
        })

        //飞行到中心点
        let centerPos=turf.points(arr);
        var center = turf.center(centerPos);
        //转成笛卡尔
        var centerCartesian = Cesium.Cartesian3.fromDegrees(...center.geometry.coordinates, 2e4);
        window.$viewer.camera.flyTo({
            destination:centerCartesian,
            orientation: {
              heading: Cesium.Math.toRadians(0.0),
              pitch: Cesium.Math.toRadians(-90.0),
              roll: 0.0,
            },
          });
    }
    //更新数据
    update(data) {
        this.heatMap.setWGS84Data(this.valueMin, this.valueMax, data);
    }

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值