wangjuncheng
5 天以前 f60f7c614e60221ed7c0ddb93c52608e86f4b57e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
import { useSimStore } from "@/store/simulation";
import { storeToRefs } from "pinia";
const simStore = useSimStore();
const { waterLegendData } = storeToRefs(simStore);
let water = null;
 
/**
 * 销毁水体模拟层
 */
export function destoryWaterPrimitive() {
  if (water) {
    enableWaterArrowFlow(false);
    water.destroy();
    water = null;
    // console.log("Water simulation destroyed.");
  }
}
 
/**
 * 创建水体模拟层
 * @param {Object} options - 可选参数
 * @param {number} options.interval - 水体模拟的时间间隔(单位:毫秒)
 * @param {string} options.baseUrl - 仿真服务地址
 * @param {boolean} options.colorRender - 是否启用颜色渲染
 */
export async function createWaterPrimitive(options = {}) {
  const {
    baseUrl = "/simu/c2h1dc",
    interval = 1000,
    colorRender = true,
    minFlowRate = 0.1, // 新增参数
    maxFlowRate = 12, // 新增参数
  } = options;
 
  // 定义水深颜色映射的色标
  const colorStops = [
    "#09a2dc",
    "#58c196",
    "#bedf74",
    "#d7f06e",
    "#ffe930",
    "#fdd10a",
    "#feb652",
    "#fd7f06",
    "#fe2b07",
    "#4d0a08",
  ];
 
  const levelCount = colorStops.length;
  const minAllowed = 0.05; // 最小允许值
  const threshold = 1; // 小值与大值分界点
 
  let effectiveMin = Math.max(minFlowRate, minAllowed); // 最小不能小于 0.01
 
  const waterHeightLevels = [];
 
  // 分两段构造高度数组
  for (let i = 0; i < levelCount; i++) {
    let ratio = i / (levelCount - 1); // 0 ~ 1
 
    let height;
    if (ratio <= 0.5) {
      // 前半段:低值区域,使用强指数增长,从 effectiveMin 到 threshold
      const localRatio = ratio * 2; // 映射到 0~1
      const expRatio = Math.pow(localRatio, 2); // 更强调低值区域密度
      height = effectiveMin + (threshold - effectiveMin) * expRatio;
    } else {
      // 后半段:高值区域,从 threshold 到 maxFlowRate,使用指数增长
      const localRatio = (ratio - 0.5) * 2; // 映射到 0~1
      const expBase = Math.exp(Math.log(maxFlowRate / threshold) / 1);
      height = threshold * Math.pow(expBase, localRatio);
    }
 
    waterHeightLevels.push({
      height: parseFloat(height.toFixed(2)), // 保留两位小数
      color: colorStops[i],
    });
  }
 
  waterLegendData.value = waterHeightLevels;
  // console.log(waterLegendData.value, "图例数据");
  water = await earthCtrl.simulate.createWaterSimulateLayer({
    baseUrl,
    interval,
    color: SmartEarth.Cesium.Color.fromCssColorString("#D4F2E7"),
    loop: false,
    callback: timeCallback,
    alphaByDepth: -0.3,
    waterHeightLevels,
    colorRender,
    sizeIndex: 0,
  });
  //防止缩放导致地形变动压盖水面,水面增加设置
  water.clampMinHeight = 0; //相机相对于水面最小高度
  water.clampMaxHeight = 1000; //相机相对于水面最大高度
  water.offsetMinHeight = 0; //水偏移最小高度
  water.offsetMaxHeight = 100; //水偏移最大高度
  // 是否开启箭头
  enableWaterArrowFlow(false);  
  // 是否开启水面阴影
  toggleWaterShadow(false);
 
  // console.log(
  //   `仿真模拟参数:请求路径 ${baseUrl}, 帧间间隔 ${interval}ms, 是否开启专题渲染 ${colorRender}`
  // );
}
/**
 * 初始化水体模拟视图
 */
export function initeWaterPrimitiveView() {
  let view = {
    destination: {
      x: -2173603.2294639186,
      y: 4338938.333124211,
      z: 4128027.401463165,
    },
    orientation: {
      pitch: -0.6208443477400212,
      roll: 0.000049799989940702005,
      heading: 3.6294612473618644,
    },
  };
  viewer.scene.camera.flyTo(view);
  // console.log("Camera view initialized for water simulation.");
}
/**
 * 更换水透明度
 */
export function updateWaterColor(color, alpha) {
  if (water) {
    water.color = Cesium.Color.fromCssColorString(color);
    water.alphaByDepth = alpha;
  } else {
    console.warn("No water simulation to pause.");
  }
}
/**
 * 暂停水体模拟
 */
export function pauseWaterSimulation() {
  if (water) {
    water.pause();
    // console.log("暂停仿真");
  } else {
    console.warn("No water simulation to pause.");
  }
}
 
/**
 * 恢复水体模拟
 */
export function resumeWaterSimulation() {
  if (water) {
    water.resume();
    // console.log("继续仿真");
  } else {
    console.warn("No water simulation to resume.");
  }
}
 
/**
 * 跳转到某个时间点的水面状态
 * @param {number} closestIndex - 目标时间戳索引
 */
export function setTimeForWaterSimulation(closestIndex) {
  if (water) {
    const imageList = water.getTimeList();
 
    if (!imageList.length) {
      console.warn("No timestamps available for water simulation.");
      return;
    }
    // const idx = Math.floor(Math.random() * imageList.length); //随机索引跳转,实际中用不到,只用作演示
    // console.log(
    //   `Jumping to timestamp: count:[${imageList.length}], index:[${closestIndex}]`
    // );
    water.setTime(imageList[closestIndex]);
  } else {
    console.warn("No water simulation to set time for.");
  }
}
 
/**
 * 设置或关闭颜色渲染
 * @param {boolean} enabled
 */
export function toggleWaterColorRender(enabled) {
  if (water) {
    water.colorRender = enabled;
    // console.log(`是否开启专题渲染 ${enabled}`);
  } else {
    console.warn("No water simulation to toggle color rendering.");
  }
}
// ==================【SDK 新增功能 - 箭头流向 & 阴影控制】==================
 
/**
 * 开启/关闭箭头流向动画
 * @param {boolean} enabled - 是否启用箭头动画
 */
export function enableWaterArrowFlow(enabled) {
  if (water) {
    // 默认关闭状态
    water.flowEnabled = enabled; // 假设 SDK 支持此属性
    // console.log(`箭头流向动画已${enabled ? "开启" : "关闭"}`);
  } else {
    console.warn("未找到水体模拟图层,请先启动洪水模拟");
  }
}
 
/**
 * 开启/关闭全局阴影效果
 * @param {boolean} enabled - 是否启用阴影
 */
export function toggleWaterShadow(enabled) {
  if (!viewer) {
    console.warn("Cesium Viewer 未初始化,无法设置阴影");
    return;
  }
 
  try {
    earthCtrl.shadows = enabled;
    if (enabled) {
      earthCtrl.shadowMap.maximumDistance = 10000.0; //最大距离
      earthCtrl.shadowMap.pointLightRadius = 50.0; //点光源半径
    }
    // console.log(`阴影效果已${enabled ? "开启" : "关闭"}`);
  } catch (error) {
    console.error("设置阴影失败:", error);
  }
}
 
// ==================================================
/**
 * 时间戳回调函数
 * @param {number} timeStamp - 当前时间戳
 */
function timeCallback(timeStamp) {
  // console.log(`Current timestamp: ${timeStamp}`);
}