mirror of
				https://github.com/jiawanlong/Cesium-Examples.git
				synced 2025-11-03 08:44:17 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			357 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			357 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!--********************************************************************
 | 
						|
* by jiawanlong
 | 
						|
*********************************************************************-->
 | 
						|
<!DOCTYPE html>
 | 
						|
<html>
 | 
						|
 | 
						|
<head>
 | 
						|
  <meta charset="UTF-8" />
 | 
						|
  <title>2024格美</title>
 | 
						|
  <link rel="stylesheet" href="./../../libs/cesium/Cesium1.98/Widgets/widgets.css">
 | 
						|
  <script type="text/javascript" src="./../../libs/cesium/Cesium1.98/Cesium.js"></script>
 | 
						|
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
 | 
						|
  <script src="./libgif.js"></script>
 | 
						|
</head>
 | 
						|
 | 
						|
<body style="margin: 0; overflow: hidden; background: #fff; width: 100%; height: 100%; position: absolute; top: 0">
 | 
						|
  <div id="map" style="margin: 0 auto; width: 100%; height: 100%"></div>
 | 
						|
  <ul
 | 
						|
    style="position: absolute;z-index: 100;bottom: 30px;right: 10px;    color: #fff;background: #000000cc; list-style: none;;">
 | 
						|
    <li>
 | 
						|
      <span style=" border-radius: 10px;   width: 10px;height: 10px; display: inline-block; background: GREEN;"></span>
 | 
						|
      <span>热带低压</span>
 | 
						|
    </li>
 | 
						|
    <li>
 | 
						|
      <span style="  border-radius: 10px; width: 10px;height: 10px; display: inline-block; background: BLUE;"></span>
 | 
						|
      <span>热带风暴</span>
 | 
						|
    </li>
 | 
						|
    <li>
 | 
						|
      <span
 | 
						|
        style="    border-radius: 10px; width: 10px;height: 10px; display: inline-block; background: YELLOW;"></span>
 | 
						|
      <span>强热带风暴</span>
 | 
						|
    </li>
 | 
						|
    <li>
 | 
						|
      <span
 | 
						|
        style="  border-radius: 10px;  width: 10px;height: 10px; display: inline-block; background: #FBC712;"></span>
 | 
						|
      <span>台风</span>
 | 
						|
    </li>
 | 
						|
    <li>
 | 
						|
      <span style="   border-radius: 10px;  width: 10px;height: 10px; display: inline-block; background: RED;"></span>
 | 
						|
      <span>超强台风</span>
 | 
						|
    </li>
 | 
						|
  </ul>
 | 
						|
  <script type="text/javascript">
 | 
						|
 | 
						|
    Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3ZjQ5ZGUzNC1jNWYwLTQ1ZTMtYmNjYS05YTY4ZTVmN2I2MDkiLCJpZCI6MTE3MTM4LCJpYXQiOjE2NzY0NDUyODB9.ZaNSBIfc1sGLhQd_xqhiSsc0yr8oS0wt1hAo9gbke6M'
 | 
						|
    const viewer = new Cesium.Viewer('map', {});
 | 
						|
    viewer.camera.setView({
 | 
						|
      destination: Cesium.Cartesian3.fromDegrees(120, 20, 4025692.0)
 | 
						|
    });
 | 
						|
    let fengquanLayers = [];
 | 
						|
 | 
						|
    initJJ();
 | 
						|
    initPoints();
 | 
						|
    let myEntityCollection = new Cesium.CustomDataSource("initPointsCollection");
 | 
						|
    viewer.dataSources.add(myEntityCollection);
 | 
						|
 | 
						|
    // 历史点和线
 | 
						|
    function initPoints() {
 | 
						|
 | 
						|
      axios.get('./202403.json')
 | 
						|
        .then((response) => {
 | 
						|
          let points = response.data.points;
 | 
						|
          let lineArr = [];
 | 
						|
 | 
						|
          points.forEach(element => {
 | 
						|
            let color = Cesium.Color.RED
 | 
						|
            lineArr.push(element.lng)
 | 
						|
            lineArr.push(element.lat)
 | 
						|
            if (element.strong == "热带低压") {
 | 
						|
              color = Cesium.Color.GREEN
 | 
						|
            } else if (element.strong == "热带风暴") {
 | 
						|
              color = Cesium.Color.BLUE
 | 
						|
            } else if (element.strong == "强热带风暴") {
 | 
						|
              color = Cesium.Color.YELLOW
 | 
						|
            } else if (element.strong == "台风") {
 | 
						|
              color = Cesium.Color.fromCssColorString("#FBC712")
 | 
						|
            } else if (element.strong == "强台风") {
 | 
						|
              color = Cesium.Color.PLUM
 | 
						|
            } else if (element.strong == "超强台风") {
 | 
						|
              color = Cesium.Color.RED
 | 
						|
            }
 | 
						|
            var entity1 = new Cesium.Entity({
 | 
						|
              position: Cesium.Cartesian3.fromDegrees(element.lng, element.lat),
 | 
						|
              point: {
 | 
						|
                pixelSize: 5,
 | 
						|
                color: color
 | 
						|
              },
 | 
						|
            });
 | 
						|
            myEntityCollection.entities.add(entity1);
 | 
						|
          });
 | 
						|
          viewer.entities.add({
 | 
						|
            polyline: {
 | 
						|
              positions: Cesium.Cartesian3.fromDegreesArray(lineArr),
 | 
						|
              width: 3,
 | 
						|
              clampToGround: true,
 | 
						|
              material: Cesium.Color.RED,
 | 
						|
            }
 | 
						|
          });
 | 
						|
          initForeast(points[points.length - 1])
 | 
						|
          adds(points)
 | 
						|
        })
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    // 预测
 | 
						|
    function initForeast(data) {
 | 
						|
      let forecast = data.forecast;
 | 
						|
 | 
						|
      let colorArr = [
 | 
						|
        Cesium.Color.fromCssColorString("#2D12FB"),
 | 
						|
        Cesium.Color.fromCssColorString("#15E5E7"),
 | 
						|
        Cesium.Color.fromCssColorString("#15E74A"),
 | 
						|
        Cesium.Color.fromCssColorString("#E76F15"),
 | 
						|
        Cesium.Color.fromCssColorString("#15D9E7"),
 | 
						|
      ];
 | 
						|
      forecast.forEach((ele, ii) => {
 | 
						|
 | 
						|
        let lineArr = [];
 | 
						|
        ele.forecastpoints.forEach((e) => {
 | 
						|
          lineArr.push(e.lng)
 | 
						|
          lineArr.push(e.lat)
 | 
						|
          var entity1 = new Cesium.Entity({
 | 
						|
            position: Cesium.Cartesian3.fromDegrees(e.lng, e.lat),
 | 
						|
            point: {
 | 
						|
              pixelSize: 7,
 | 
						|
              color: colorArr[ii]
 | 
						|
            },
 | 
						|
          });
 | 
						|
          myEntityCollection.entities.add(entity1);
 | 
						|
        })
 | 
						|
        viewer.entities.add({
 | 
						|
          polyline: {
 | 
						|
            positions: Cesium.Cartesian3.fromDegreesArray(lineArr),
 | 
						|
            width: 2,
 | 
						|
            clampToGround: true,
 | 
						|
            material: new Cesium.PolylineDashMaterialProperty({
 | 
						|
              color: colorArr[ii]
 | 
						|
            }),
 | 
						|
          }
 | 
						|
        });
 | 
						|
      })
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    // 警戒线
 | 
						|
    function initJJ() {
 | 
						|
      // 24 线
 | 
						|
      viewer.entities.add({
 | 
						|
        name: '24',
 | 
						|
        polyline: {
 | 
						|
          positions: Cesium.Cartesian3.fromDegreesArray([
 | 
						|
            [127, 34],
 | 
						|
            [127, 22],
 | 
						|
            [119, 18],
 | 
						|
            [119, 11],
 | 
						|
            [113, 4.5],
 | 
						|
            [105, 0]
 | 
						|
          ].flat()),
 | 
						|
          width: 2,
 | 
						|
          material: Cesium.Color.RED,
 | 
						|
          clampToGround: true,
 | 
						|
        }
 | 
						|
      });
 | 
						|
 | 
						|
      // 48 线
 | 
						|
      viewer.entities.add({
 | 
						|
        name: '48',
 | 
						|
        polyline: {
 | 
						|
          positions: Cesium.Cartesian3.fromDegreesArray([
 | 
						|
            [132, 34],
 | 
						|
            [132, 22],
 | 
						|
            [119, 0],
 | 
						|
            [105, 0]
 | 
						|
          ].flat()),
 | 
						|
          width: 2,
 | 
						|
          material: Cesium.Color.YELLOW,
 | 
						|
          clampToGround: true,
 | 
						|
        }
 | 
						|
      });
 | 
						|
      viewer.entities.add({
 | 
						|
        position: Cesium.Cartesian3.fromDegrees(126.129019, 29.104287),
 | 
						|
        label: {
 | 
						|
          fillColor: Cesium.Color.RED,
 | 
						|
          text: '24小时警戒线',
 | 
						|
          font: '14pt monospace',
 | 
						|
        }
 | 
						|
      });
 | 
						|
      viewer.entities.add({
 | 
						|
        position: Cesium.Cartesian3.fromDegrees(132, 20),
 | 
						|
        label: {
 | 
						|
          fillColor: Cesium.Color.YELLOW,
 | 
						|
          text: '48小时警戒线',
 | 
						|
          font: '14pt monospace',
 | 
						|
        }
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    let iii = 0;
 | 
						|
    let currentPointObj;
 | 
						|
    let tbentity;
 | 
						|
    function adds(data) {
 | 
						|
      addTB()
 | 
						|
 | 
						|
      setInterval(function () {
 | 
						|
        let kkk = iii * 2
 | 
						|
        currentPointObj = {
 | 
						|
          lon: data[iii].lng,
 | 
						|
          lat: data[iii].lat,
 | 
						|
          circle7: {
 | 
						|
            radius1: 350 - kkk,
 | 
						|
            radius2: 450 - kkk,
 | 
						|
            radius3: 400 - kkk,
 | 
						|
            radius4: 350 - kkk,
 | 
						|
          },
 | 
						|
          circle10: {
 | 
						|
            radius1: 250 - kkk,
 | 
						|
            radius2: 270 - kkk,
 | 
						|
            radius3: 250 - kkk,
 | 
						|
            radius4: 220 - kkk,
 | 
						|
          },
 | 
						|
          circle12: {
 | 
						|
            radius1: 170 - kkk,
 | 
						|
            radius2: 150 - kkk,
 | 
						|
            radius3: 150 - kkk,
 | 
						|
            radius4: 170 - kkk,
 | 
						|
          }
 | 
						|
        };
 | 
						|
        tbentity.position = Cesium.Cartesian3.fromDegrees(data[iii].lng, data[iii].lat)
 | 
						|
 | 
						|
        if (iii > 99) {
 | 
						|
          iii = 0
 | 
						|
        } else {
 | 
						|
          iii = iii + 1
 | 
						|
        }
 | 
						|
 | 
						|
        removeTFLayer();
 | 
						|
        addTyphoonCircle();
 | 
						|
      }, 200);
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
    function addTB() {
 | 
						|
      let div = document.createElement("div");
 | 
						|
      let img = document.createElement("img");
 | 
						|
      div.appendChild(img);
 | 
						|
      img.src = './tf.gif'
 | 
						|
 | 
						|
      img.onload = () => {
 | 
						|
        let rub = new SuperGif({
 | 
						|
          gif: img
 | 
						|
        })
 | 
						|
        rub.load(() => {
 | 
						|
          tbentity = viewer.entities.add({
 | 
						|
            position: Cesium.Cartesian3.fromDegrees(75.166493, 39.9060534),
 | 
						|
            billboard: {
 | 
						|
              image: new Cesium.CallbackProperty(() => {
 | 
						|
                return rub.get_canvas().toDataURL("image/png");
 | 
						|
              }, false),
 | 
						|
              scale: 0.1,
 | 
						|
            },
 | 
						|
          });
 | 
						|
          resolve(entity);
 | 
						|
        });
 | 
						|
      };
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    function removeTFLayer() {
 | 
						|
      let arr = fengquanLayers;
 | 
						|
      for (let i = 0; i < arr.length; i++) {
 | 
						|
        viewer.entities.remove(arr[i])
 | 
						|
      }
 | 
						|
      fengquanLayers = [];
 | 
						|
    }
 | 
						|
    function addTyphoonCircle() {
 | 
						|
      const circles = ["circle7", "circle10", "circle12"];
 | 
						|
      circles.forEach(item => {
 | 
						|
        let en = viewer.entities.add({
 | 
						|
          id: `tf_polygon_${item}`,
 | 
						|
          name: `tf_polygon_${item}`,
 | 
						|
          polygon: {
 | 
						|
            hierarchy:
 | 
						|
              new Cesium.CallbackProperty(() => {
 | 
						|
                let points = [];
 | 
						|
                if (currentPointObj[item]) {
 | 
						|
                  points = getTyphoonPolygonPoints(currentPointObj, item)
 | 
						|
                } else {
 | 
						|
                  points = []
 | 
						|
                }
 | 
						|
                return new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(points));
 | 
						|
              }, false),
 | 
						|
            material: Cesium.Color.ORANGE.withAlpha(0.05),
 | 
						|
            extrudedHeight: 1000,
 | 
						|
            outline: true,
 | 
						|
            outlineColor: Cesium.Color.ORANGE,
 | 
						|
            outlineWidth: 2,
 | 
						|
          },
 | 
						|
          polyline: {
 | 
						|
            positions:
 | 
						|
              new Cesium.CallbackProperty(() => {
 | 
						|
                let points = [];
 | 
						|
                if (currentPointObj[item]) {
 | 
						|
                  points = getTyphoonPolygonPoints(currentPointObj, item)
 | 
						|
                } else {
 | 
						|
                  points = []
 | 
						|
                }
 | 
						|
                return new Cesium.Cartesian3.fromDegreesArray(points);
 | 
						|
              }, false),
 | 
						|
            material: Cesium.Color.ORANGE,
 | 
						|
            width: 2,
 | 
						|
            height: 1000,
 | 
						|
          }
 | 
						|
        })
 | 
						|
        fengquanLayers.push(en)
 | 
						|
      })
 | 
						|
    }
 | 
						|
    // 获取台风圈面的坐标
 | 
						|
    function getTyphoonPolygonPoints(pointObj, cNum) {
 | 
						|
      let points = []
 | 
						|
      let center = [pointObj.lon * 1, pointObj.lat * 1]
 | 
						|
      let radiusList = [
 | 
						|
        pointObj[cNum]['radius1'],
 | 
						|
        pointObj[cNum]['radius2'],
 | 
						|
        pointObj[cNum]['radius3'],
 | 
						|
        pointObj[cNum]['radius4'],
 | 
						|
      ]
 | 
						|
      let startAngleList = [0, 90, 180, 270]
 | 
						|
      let fx, fy
 | 
						|
      startAngleList.forEach((startAngle, index) => {
 | 
						|
        let radius = radiusList[index] / 100
 | 
						|
        let pointNum = 90
 | 
						|
        let endAngle = startAngle + 90
 | 
						|
        let sin, cos, x, y, angle
 | 
						|
        for (let i = 0; i <= pointNum; i++) {
 | 
						|
          angle = startAngle + ((endAngle - startAngle) * i) / pointNum
 | 
						|
          sin = Math.sin((angle * Math.PI) / 180)
 | 
						|
          cos = Math.cos((angle * Math.PI) / 180)
 | 
						|
          // console.log(center)
 | 
						|
          x = center[0] + radius * sin
 | 
						|
          y = center[1] + radius * cos
 | 
						|
          points.push(x, y);
 | 
						|
          if (startAngle == 0 && i == 0) {
 | 
						|
            fx = x;
 | 
						|
            fy = y;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      })
 | 
						|
      points.push(fx, fy);
 | 
						|
      return points
 | 
						|
    }
 | 
						|
  </script>
 | 
						|
</body>
 | 
						|
 | 
						|
</html> |