Koishi 3 週間 前
コミット
ca6a8ec3cd

+ 1 - 0
src/assets/wind/Windy_source.js

@@ -17,6 +17,7 @@ var Windy = function (json, cesiumViewer) {
     _primitives = cesiumViewer.scene.primitives;
     this._init();
 };
+
 Windy.prototype = {
     constructor: Windy,
     _init: function () {

+ 168 - 5
src/views/cesium.vue

@@ -92,6 +92,7 @@ import Windy from "../assets/wind/Windy_source.js";
 import basicGeoJson from "../assets/geoJson/basic.json";
 // import windLineJson from "../assets/geoJson/windLine_2017121300.json";
 import windLineJson from "./cesiumComponents/windspeed.json";
+import windData from "./cesiumComponents/windData.json";
 
 import axios from "axios";
 
@@ -162,6 +163,9 @@ export default {
       handlerAction: null,
       sidebarRightData: null,
       imageryProviderV: null,
+      isWindVisible: true,
+      minSpeed: 0,
+      maxSpeed: 0,
     };
   },
 
@@ -172,7 +176,7 @@ export default {
       this.initSystemInfo();
     }
     // this.getData();
-    // this.test();
+    this.test();
   },
 
   unmounted() {
@@ -207,6 +211,164 @@ export default {
         console.log("res===>>>", res);
       });
     },
+
+    // 创建粒子系统
+    createWindParticles(data) {
+      // 计算风速范围
+      const speeds = data.map((item) =>
+        Math.sqrt(item.u * item.u + item.v * item.v)
+      );
+      this.minSpeed = Math.min(...speeds);
+      this.maxSpeed = Math.max(...speeds);
+
+      const particleSystem = this.viewer.scene.primitives.add(
+        new Cesium.ParticleSystem({
+          image: this.createWindTexture(),
+          startColor: Cesium.Color.WHITE.withAlpha(0.7),
+          endColor: Cesium.Color.WHITE.withAlpha(0.0),
+          startScale: 1.0,
+          endScale: 1.5,
+          minimumParticleLife: 5.0,
+          maximumParticleLife: 15.0,
+          minimumSpeed: 1.0,
+          maximumSpeed: 4.0,
+          imageSize: new Cesium.Cartesian2(10.0, 10.0),
+          emissionRate: 500,
+          emitter: new Cesium.CircleEmitter(2000000.0), // 更大的发射器半径
+          bursts: [],
+          lifetime: 16.0,
+          updateCallback: (particle, dt) => {
+            // 获取粒子所在位置的风速
+            const position = particle.position;
+            const cartographic = Cesium.Cartographic.fromCartesian(position);
+            const lon = Cesium.Math.toDegrees(cartographic.longitude);
+            const lat = Cesium.Math.toDegrees(cartographic.latitude);
+
+            // 查找最近的风场数据点
+            const wind = this.findNearestWind(lon, lat, data);
+            if (wind) {
+              // 根据风速调整粒子移动
+              const speedFactor = 100000; // 调整风速对移动的影响
+              const uComponent = wind.u * speedFactor * dt;
+              const vComponent = wind.v * speedFactor * dt;
+
+              // 转换为笛卡尔坐标位移
+              const offset = new Cesium.Cartesian3(uComponent, vComponent, 0);
+
+              // 应用位移
+              particle.position = Cesium.Cartesian3.add(
+                particle.position,
+                offset,
+                new Cesium.Cartesian3()
+              );
+
+              // 根据风速调整粒子颜色
+              const speed = Math.sqrt(wind.u * wind.u + wind.v * wind.v);
+              const t =
+                (speed - this.minSpeed) / (this.maxSpeed - this.minSpeed);
+              particle.color = Cesium.Color.fromHsl(
+                0.6 - t * 0.6, // 从蓝色(0.6)到红色(0.0)
+                0.9,
+                0.5,
+                Cesium.Math.clamp(t + 0.2, 0.3, 0.8)
+              );
+
+              // 根据风速调整粒子大小
+              particle.size = Cesium.Math.lerp(5.0, 15.0, t);
+            }
+
+            // 如果粒子飞出边界,重置它
+            const height = Cesium.Cartographic.fromCartesian(
+              particle.position
+            ).height;
+            if (height > 10000 || height < 100) {
+              this.resetParticle(particle);
+            }
+          },
+        })
+      );
+
+      // 设置粒子的初始位置
+      const center = Cesium.Cartesian3.fromDegrees(116.0, 40.0, 1000);
+      const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(center);
+      particleSystem.modelMatrix = modelMatrix;
+
+      this.windLayer = particleSystem;
+    },
+
+    // 重置粒子位置
+    resetParticle(particle) {
+      const center = Cesium.Cartesian3.fromDegrees(
+        100 + Math.random() * 40,
+        20 + Math.random() * 40,
+        1000 + Math.random() * 500
+      );
+      particle.position = center;
+    },
+
+    // 创建风纹理
+    createWindTexture() {
+      const canvas = document.createElement("canvas");
+      canvas.width = 20;
+      canvas.height = 20;
+      const context = canvas.getContext("2d");
+
+      // 绘制一个简单的圆形粒子
+      context.beginPath();
+      context.arc(10, 10, 5, 0, 2 * Math.PI, false);
+      context.fillStyle = "white";
+      context.fill();
+
+      return canvas;
+    },
+
+    // 查找最近的风场数据点
+    findNearestWind(lon, lat, data) {
+      let minDistance = Infinity;
+      let nearestWind = null;
+
+      for (const item of data) {
+        const distance = Math.sqrt(
+          Math.pow(item.lon - lon, 2) + Math.pow(item.lat - lat, 2)
+        );
+
+        if (distance < minDistance) {
+          minDistance = distance;
+          nearestWind = item;
+        }
+
+        // 如果找到足够近的点,提前退出
+        if (distance < 0.5) {
+          break;
+        }
+      }
+
+      return minDistance < 5.0 ? nearestWind : null; // 5度以内的阈值
+    },
+
+    // 切换风场显示
+    toggleWind() {
+      if (this.windLayer) {
+        this.windLayerwindLayer.show = !this.windLayer.show;
+        this.isWindVisible = this.windLayer.show;
+      }
+    },
+
+    // 改变透明度
+    changeOpacity(delta) {
+      if (this.windLayer) {
+        const currentAlpha = this.windLayer.startColor.alpha;
+        const newAlpha = Cesium.Math.clamp(currentAlpha + delta, 0.1, 1.0);
+
+        this.windLayer.startColor = new Cesium.Color(
+          this.windLayer.startColor.red,
+          this.windLayer.startColor.green,
+          this.windLayer.startColor.blue,
+          newAlpha
+        );
+      }
+    },
+
     // 初始化一些监听事件
     initEventListener() {
       const mapBox = document.querySelector(".mapBox");
@@ -882,10 +1044,11 @@ export default {
     showWindLayer() {
       if (!this.windLayer) {
         this.resetViewport(20000000);
-        this.windLayer = new Windy(windLineJson, this.viewer);
-        this.windLayerTimmer = setInterval(() => {
-          this.windLayer.animate();
-        }, 200);
+        this.createWindParticles(windData);
+        // this.windLayer = new Windy(windLineJson, this.viewer);
+        // this.windLayerTimmer = setInterval(() => {
+        //   this.windLayer.animate();
+        // }, 200);
       }
     },
 

ファイルの差分が大きいため隠しています
+ 0 - 0
src/views/cesiumComponents/windData.json


この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません