|
@@ -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);
|
|
|
}
|
|
|
},
|
|
|
|