Cesium 模拟病毒扩散效果

1.随机生成一个经纬度,半径,范围

2.根据半径计算bounds,并生成rectangle

3.使用CesiumHeatmap.js生成热力图

4.热力图输出图片到rectangle上

5.实时修改半径,实现动态效果

6.删除

//图片
    var image = new Image();
    var randomRect = [];//存储随机生成的热力图,矩形,延迟方法
    var randomid = 0;//id
    //点,随机数,生成热力图
    function PointRandomHeatMap() {

      var point = { longitude: 108.45, latitude: 33.9, height: 11.409122369106317 }
      var primitiveid="test";
      var radius = 100;//半径
      var randiusPoint = 100;//点周围范围半径内
      var rvalue = 150;//范围半径
      //最小值
      var valueMin = 0;
      //最大值
      var valueMax = 100;

      // 计算边界
      var west = point.longitude - Cesium.Math.toDegrees(rvalue / Cesium.Ellipsoid.WGS84.maximumRadius);
      var south = point.latitude - Cesium.Math.toDegrees(rvalue / Cesium.Ellipsoid.WGS84.maximumRadius);
      var east = point.longitude + Cesium.Math.toDegrees(rvalue / Cesium.Ellipsoid.WGS84.maximumRadius);
      var north = point.latitude + Cesium.Math.toDegrees(rvalue / Cesium.Ellipsoid.WGS84.maximumRadius);

      var bounds = new Cesium.Rectangle(west, south, east, north);

      console.log(bounds); // 输出计算得到的边界

      viewer.camera.setView({
        destination: Cesium.Rectangle.fromDegrees(bounds.west, bounds.south, bounds.east, bounds.north)
      });


      var data = getDatapoint(point, bounds, randiusPoint, 100);//数据
      var heatMap;

      var heatPrimitive = viewer.scene.primitives.add(
        new Cesium.GroundPrimitive({
          geometryInstances: new Cesium.GeometryInstance({
            geometry: new Cesium.RectangleGeometry({
              rectangle: Cesium.Rectangle.fromDegrees(bounds.west, bounds.south, bounds.east, bounds.north),
              vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
            }),
          }),
          appearance: new Cesium.EllipsoidSurfaceAppearance({
            aboveGround: true,
            material: new Cesium.Material({
              fabric: {
                type: "Image",
                uniforms: {
                  image: image.src,
                },
              },
            }),
          }),
        })
      );
      heatPrimitive.id=primitiveid;
      console.log("矩形id:", heatPrimitive.id);
      heatPrimitive.show = false;

      SyncCreate(valueMin, valueMax, radius, data, heatPrimitive);

      // viewer.clock.onTick.addEventListener(syncRadius);

      var synctimer1 = setInterval(function () {
        syncRadius();
      }, 100);

      randomRect.push({
        id:heatPrimitive.id,
        obj:{
          heatmap:heatMap,
          primitive:heatPrimitive,
          synctimer:synctimer1
        }
      });



      // //方法内部删除
      // $("#clear1").click(function () {
      //   console.log("清除按钮点击,清除随机");
      //   ClearHeatMapSync();
      // });

      // //清除结果
      // function ClearHeatMapSync() {
      //   clearInterval(synctimer1);
      //   radius = 100.0;
      //   heatMap.clearLayer();
      //   viewer.scene.primitives.remove(heatPrimitive);

      // }





      function syncRadius(params) {
        //clearInterval(synctimer1);
        radius++;
        if (radius >= 100) {
          radius = 0;
        }

        //console.log("动态半径:", radius);
        SyncCreate(valueMin, valueMax, radius, data, heatPrimitive);

      }

      //生成
      function SyncCreate(valueMin, valueMax, radius, data, heatPrimitive) {
        console.log("动态半径:", valueMin, valueMax, radius, data);
        heatMap = CesiumHeatmap.create(
          viewer, // 视图层
          bounds, // 矩形坐标
          { // heatmap相应参数
            backgroundColor: "rgba(0,0,0,0)",
            radius: radius,
            maxOpacity: .5,
            minOpacity: 0,
            blur: .75
          }
        );

        heatMap.setWGS84Data(valueMin, valueMax, data);
        heatMap.show(false);
        console.log("生成的热力图1:", heatMap);
        CreateImageCanvasSync(heatMap, heatPrimitive);
      }

    }


    //计算范围内的随机点
    function getDatapoint(point, bounds, rp, length) {
      data = [];
      data.push({ x: point.longitude, y: point.latitude, value: valueMax });

      for (var i = 0; i < length; i++) {

        // 生成随机方位角(bearing)
        var bearing = Cesium.Math.randomBetween(0, 2 * Math.PI);
        // 生成随机距离(在半径范围内)
        var distance = Cesium.Math.randomBetween(0, rp);

        // 根据中心点、方位角和距离计算生成点的经纬度坐标
        //var centerCartographic = Cesium.Cartographic.fromDegrees(point.longitude, point.latitude);
        //var centerPosition = Cesium.Ellipsoid.WGS84.cartographicToCartesian(centerCartographic);
        // 根据中心点、方位角和距离计算生成点的经纬度坐标
        //var randomLongitude = point.longitude + (Cesium.Math.toDegrees(distance) / rp) * Math.cos(bearing);
        //var randomLatitude = point.latitude + (Cesium.Math.toDegrees(distance) / rp) * Math.sin(bearing);
        //var x = randomLongitude;//point.longitude + Math.random() * (bounds.west - bounds.east);
        //var y = randomLatitude;//point.latitude + Math.random() * (bounds.north - bounds.south);
        var randompoint = calculatingTargetPoints(point, bearing, distance);

        var x = randompoint.longitude;//point.longitude + Math.random() * (bounds.west - bounds.east);
        var y = randompoint.latitude;//point.latitude + Math.random() * (bounds.north - bounds.south);
        var value = Math.random() * 100;
        data.push({ x: x, y: y, value: value });
      }
      return data;
    }

    //计算范围内的随机点
    function getData(length) {
      data = [];
      for (var i = 0; i < length; i++) {
        var x = Math.random() * (west - east) + east;
        var y = Math.random() * (north - south) + south;
        var value = Math.random() * 100;
        data.push({ x: x, y: y, value: value });
      }
      return data;
    }

    //计算一个点周围某一方向,某一距离上的点
    function calculatingTargetPoints(pos, direction, radius) {
      // 观察点
      var viewPoint = Cesium.Cartesian3.fromDegrees(pos.longitude, pos.latitude, pos.height);
      // 世界坐标转换为投影坐标
      var webMercatorProjection = new Cesium.WebMercatorProjection(viewer.scene.globe.ellipsoid);
      var viewPointWebMercator = webMercatorProjection.project(Cesium.Cartographic.fromCartesian(viewPoint));
      // 计算目标点
      var toPoint = new Cesium.Cartesian3(viewPointWebMercator.x + radius * Math.cos(direction), viewPointWebMercator.y +
        radius * Math.sin(direction), 0);
      // 投影坐标转世界坐标
      toPoint = webMercatorProjection.unproject(toPoint);
      toPoint = Cesium.Cartographic.toCartesian(toPoint.clone());
      // 世界坐标转地理坐标
      var cartographic = Cesium.Cartographic.fromCartesian(toPoint);

      var point = {
        longitude: Cesium.Math.toDegrees(cartographic.longitude),
        latitude: Cesium.Math.toDegrees(cartographic.latitude),
        height: cartographic.height
      }
      return point;
    }


    //热力图数据渲染成图片,贴在地图上
    function CreateImageCanvasSync(heatMap, heatPrimitive) {

      //console.log("生成的矩形:", heatPrimitive);
      //指定格式PNG,更新材质
      image.src = heatMap._heatmap._renderer.canvas.toDataURL("image/jpg");
      heatPrimitive.appearance.material.uniforms.image = image.src;
      heatPrimitive.show = true;
      console.log("更新矩形材质:");

      if (heatMap.getLayer()) {
        heatMap.clearLayer();
        console.log("清除:");
      }

    }


    $("#clear1").click(function () {
        console.log("清除按钮点击,清除随机");
        ClearHeatMapSync('test');
      });

      //清除结果
      function ClearHeatMapSync(id) {
        var ob=GetObj(id);
        console.log("找到:",ob);
        clearInterval(ob.b.obj.synctimer);
        ob.b.obj.heatmap.clearLayer();
        viewer.scene.primitives.remove(ob.b.obj.primitive);
        randomRect.splice(ob.a,1);
      }

      //根据id查找
      function GetObj(id) {
        for(var i=0;i<randomRect.length;i++){
          if(randomRect[i].id==id){
          
            return {a:i,b:randomRect[i]};
          }
        }
      }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值