cesium 热力图(基于CesiumHeatmap源码修改后实现)

13 篇文章 0 订阅
8 篇文章 0 订阅

一、热力图效果图

二、核心代码

    // 模拟热力图坐标范围及核心代码
    loadCesiumHeatMapFun(){
      let tmpXYList = [
        new Cesium.Cartographic(111.2300232,39.5279085, 0),
        new Cesium.Cartographic(111.2300178,39.5256063, 0),
        new Cesium.Cartographic(111.198801,39.5256635, 0),
        new Cesium.Cartographic(111.1988154,39.527964, 0),
      ]

       //生成矩形
      var bound = new Cesium.Rectangle.fromCartographicArray(tmpXYList)
      // 随机生成矩形范围内的点坐标
      let tPoints = turf.randomPoint(Number(this.xyList), {bbox: [bound.west, bound.south, bound.east, bound.north]}) 
      var searchWithin = turf.polygon([[
                            [111.2300232,39.5279085],
                            [111.2300178,39.5256063],
                            [111.198801,39.5256635],
                            [111.1988154,39.527964],
                            [111.2300232,39.5279085]
                        ]]);
      // 返回多边形内的所有点
      var ptsWithin = turf.pointsWithinPolygon(tPoints, searchWithin); 

      let tmpMarksList = []
      let heatMax = 0
      let heatPoints = []
      tmpXYList.forEach( xy => {
        this.sampleHeightsCoordinate([xy.longitude,xy.latitude],3,(posi) => {
          tmpMarksList.push(posi)
        })
      })

      // 对随机生成的点添加value值
      ptsWithin.features.forEach(dl => {
        var val = Math.floor(Math.random() * 100);
        heatMax = Math.max(heatMax, val);
        let coord = dl.geometry.coordinates
        var point = {
          x: coord[0],
          y: coord[1],
          value: val
        };
        heatPoints.push(point);
      })
      
      let temTime = setInterval(() => {
        if(ptsWithin.features.length === heatPoints.length && tmpXYList.length === tmpMarksList.length){
          heatMap1 ? '' : heatMap1 = window.CesiumHeatmap.create(cesiumHeatViewer,bound,tmpMarksList,{ // heatmap相应参数
            radius: 20,
            maxOpacity: .6,
            minOpacity: 0,
            blur: .75,
            gradient: {
                '0.95':'red',
                '0.85':'orange',
                '0.75':'yellow',
                '0.55':'blue',
                '0.3':'green',
            },
          })
          let valueMin = 0;
          heatMap1.setWGS84Data(valueMin, heatMax, heatPoints);

          clearInterval(temTime)
        }
      }, 120);
    }

三、完整代码 

<template>
  <div id="CesiumHeatMapDiv" v-if="cesiumHeatMapIsShow">
    <table style="text-align: right;">
      <tr>
        <td colspan="2" style="text-align: left">
          <span style="font-size: 18px; font-weight: 600;">模拟热力图</span>
          <div class="closeCesiumHeatMap" @click="handCloserCesiumHeatMap"></div>
        </td>
      </tr>
      <tr>
        <td colspan="2">
          <div
            style="height: 4px;background-color: rgba(29,164,220,0.6);margin: 4px;"
          ></div>
        </td>
      </tr>
      <tr>
        <td>坐标数量:</td>
        <td>
          <el-input-number
            class="inputNumWidth"
            v-model="xyList"
            :max="99999"
            :min="5000"
            :step="5000"
            @change="handlxlChange"
          ></el-input-number>
        </td>
      </tr>
      <tr>
        <td colspan="2">
          <el-button size="mini" :disabled="isDrawCesiumHeatMap" @click="loadCesiumHeatMap">加载热力图</el-button>
          <el-button size="mini" @click="clearCesiumHeatMap">清除</el-button>
        </td>
      </tr>
    </table>
  </div>
</template>
<script>
import * as turf from '@turf/turf'
import CesiumHeatmap from "../../../../../static/cesium-heatmap/CesiumHeatmap";

let cesiumHeatViewer = undefined
let heatMap1 = undefined
let timeInterval = undefined

export default {
  name: "cesiumHeatMap",
  data() {
    return {
      cesiumHeatMapIsShow: false,
      isDrawCesiumHeatMap: false,
      xyList: 5000, 
    };
  },
  methods: {
    handlxlChange(){
      this.loadCesiumHeatMap()
    },

    /**
     * @description: 组件调用入口方法
     */    
    openCesiumHeatMap(viewer) {
      cesiumHeatViewer = viewer
      this.cesiumHeatMapIsShow = true;
    },

    handCloserCesiumHeatMap() {
      this.cesiumHeatMapIsShow = false;
      cesiumHeatViewer = undefined
      this.clearCesiumHeatMap()
    },
    
    loadCesiumHeatMap(){
      this.clearCesiumHeatMap()
      this.isDrawCesiumHeatMap = true
      
      this.loadCesiumHeatMapFun()
      
      timeInterval = setInterval(() => {
        this.loadCesiumHeatMapFun()
      }, 5000);
    },

    // 模拟代码
    loadCesiumHeatMapFun(){
      let tmpXYList = [
        new Cesium.Cartographic(111.2300232,39.5279085, 0),
        new Cesium.Cartographic(111.2300178,39.5256063, 0),
        new Cesium.Cartographic(111.198801,39.5256635, 0),
        new Cesium.Cartographic(111.1988154,39.527964, 0),
      ]

       //生成矩形
      var bound = new Cesium.Rectangle.fromCartographicArray(tmpXYList)
      // 随机生成矩形范围内的点坐标
      let tPoints = turf.randomPoint(Number(this.xyList), {bbox: [bound.west, bound.south, bound.east, bound.north]}) 
      var searchWithin = turf.polygon([[
                            [111.2300232,39.5279085],
                            [111.2300178,39.5256063],
                            [111.198801,39.5256635],
                            [111.1988154,39.527964],
                            [111.2300232,39.5279085]
                        ]]);
      // 返回多边形内的所有点
      var ptsWithin = turf.pointsWithinPolygon(tPoints, searchWithin); 

      let tmpMarksList = []
      let heatMax = 0
      let heatPoints = []
      tmpXYList.forEach( xy => {
        this.sampleHeightsCoordinate([xy.longitude,xy.latitude],3,(posi) => {
          tmpMarksList.push(posi)
        })
      })

      // 对随机生成的点添加value值
      ptsWithin.features.forEach(dl => {
        var val = Math.floor(Math.random() * 100);
        heatMax = Math.max(heatMax, val);
        let coord = dl.geometry.coordinates
        var point = {
          x: coord[0],
          y: coord[1],
          value: val
        };
        heatPoints.push(point);
      })
      
      let temTime = setInterval(() => {
        if(ptsWithin.features.length === heatPoints.length && tmpXYList.length === tmpMarksList.length){
          heatMap1 ? '' : heatMap1 = window.CesiumHeatmap.create(cesiumHeatViewer,bound,tmpMarksList,{ // heatmap相应参数
            radius: 20,
            maxOpacity: .6,
            minOpacity: 0,
            blur: .75,
            gradient: {
                '0.95':'red',
                '0.85':'orange',
                '0.75':'yellow',
                '0.55':'blue',
                '0.3':'green',
            },
          })
          let valueMin = 0;
          heatMap1.setWGS84Data(valueMin, heatMax, heatPoints);

          clearInterval(temTime)
        }
      }, 120);
    },
  
    clearCesiumHeatMap(){
      this.isDrawCesiumHeatMap = false
      if(heatMap1) {
        heatMap1._layer ? heatMap1._cesium.entities.remove(heatMap1._layer) : ''
        heatMap1._layer = undefined
      }
      clearInterval(timeInterval)
    },
    
    sampleHeightsCoordinate(coordinate, height,callback) {
      const positions = [
        Cesium.Cartographic.fromDegrees(coordinate[0], coordinate[1]),
      ]
      cesiumHeatViewer.scene.sampleHeightMostDetailed(positions).then(function (clampedCartesians) {
        const posi = Cesium.Cartesian3.fromDegrees(coordinate[0], coordinate[1], clampedCartesians[0].height + height)
        callback(posi)
      })
    }
  }
};
</script>

<style lang="scss" scoped>
.closeCesiumHeatMap {
  text-decoration: none;
  position: absolute;
  top: 20px;
  right: 10px;
  z-index: 20;
}
.closeCesiumHeatMap:after {
  // content: "✖";
  content: "\e60b";
  font-family: "iconfont";
  font-size: 22px;
  color: rgba($color: gray, $alpha: 0.8);
}

#CesiumHeatMapDiv {
  color: rgba(29, 164, 220, 0.9);
  background: rgba(34, 69, 91, 0.7);
  border-radius: 6px;
  padding: 10px;

  .closeCesiumHeatMap {
    top: 1vh;
    right: 0.6vw;
    cursor: pointer;
  }
  
  /deep/ .inputNumWidth {
    width: 140px;
    .el-input__inner {
      height: 28px;
      line-height: 28px;
      padding: 0px 6px;
      background: #104c66bd;
      color: #cef2ff;
      font-size: 12px;
      border: 0px;
    }
    .el-input-number__decrease,
    .el-input-number__increase {
      background: #104c66;
      color: rgba(255, 255, 255, 0.8);
      border-right: 0px;
      border-left: 0px;
      font-size: 14px;
      top: 4px;
    }
  }

  /deep/ .el-button {
    background: rgba(18, 167, 204, 0.52);
    color: #cef2ff;
    border: 0px;
  }
}

#CesiumHeatMapDiv td {
  padding: 4px 2px;
}
</style>

四、CesiumHeatmap 修改后源码下载

CesiumHeatmap 资源链接

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向着太阳往前冲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值