1
wangjuncheng
2025-07-02 4b509ebb4ab4b83790a9cd8e9b806b2e84186d06
src/components/menu/TimeLine.vue
@@ -302,7 +302,17 @@
      // 如果需要触发某些更新函数,也可以保留
      updateWaterColorByTime();
      updateWeatherByProgress();
      // updateWeatherByProgress();
      // 修改为固定阶段,缓慢下雨的状态
      const rainParams = {
        rainSize: 0.5,
        rainSpeed: 20,
        rainDensity: 15,
        rainColor: "#ADD8E6",
      };
      console.log("实时模拟开始下雨");
      // 调用工具方法更新雨效
      mapUtils.toggleRain(rainParams, true);
    }, 5000); // 每 5 秒执行一次
  } else {
    // 这里面还是你的播放代码,上面的if中是五秒钟跳动一次的实时模拟
@@ -344,9 +354,10 @@
    console.warn("selectedScheme 或 data 不存在");
    return;
  }
  // 注意:有时 data 可能是一个字符串(例如 JSON 字符串)
  let data = selectedScheme.value.data;
  // 如果是字符串,则尝试解析成对象
  // 如果是字符串,则尝试解析为对象
  if (typeof data === "string") {
    try {
      data = JSON.parse(data);
@@ -356,28 +367,69 @@
      return;
    }
  }
  // 打印降雨强度的单位
  console.log("降雨强度的单位是:", data.intensityUnit);
  // 根据 intensityUnit 调整 rainfalls 中的 intensity 值
  if (data.intensityUnit === "mm/min") {
    data.rainfalls.forEach((r) => (r.intensity *= 60));
    console.log("将 mm/min 转换为 mm/h 后的 rainfalls:", data.rainfalls);
  } else if (data.intensityUnit === "mm/5min") {
    data.rainfalls.forEach((r) => (r.intensity *= 12));
    console.log("将 mm/5min 转换为 mm/h 后的 rainfalls:", data.rainfalls);
  } else if (data.intensityUnit !== "mm/h") {
    console.warn("未知的 intensity 单位,无法进行转换");
  // 判断 rainfalls 是否为对象,如果是则转成数组
  let rainfalls = data.rainfalls;
  if (typeof rainfalls === "object" && !Array.isArray(rainfalls)) {
    rainfalls = Object.values(rainfalls);
    console.warn("⚠️ rainfalls 是对象,已转换为数组");
  }
  const rainfallList = data.rainfalls;
  console.log("最终的 rainfallList:", rainfallList);
  rainTotalInfo.value = rainfallList;
  calculateTimeStep(rainTotalInfo.value);
  // 使用示例
  // 按小时聚合降雨数据
  const hourlyRainfallMap = {};
  rainfalls.forEach((record) => {
    const originalTime = new Date(record.time);
    if (isNaN(originalTime.getTime())) {
      console.warn("无效的时间格式:", record.time);
      return;
    }
    // 构造“小时”级别的时间键,比如:2024-08-25 20:00:00
    const hourKey = new Date(
      originalTime.getFullYear(),
      originalTime.getMonth(),
      originalTime.getDate(),
      originalTime.getHours()
    );
    const hourStr = hourKey.toISOString().slice(0, 16).replace("T", " ");
    if (!hourlyRainfallMap[hourStr]) {
      hourlyRainfallMap[hourStr] = {
        intensity: 0,
        time: hourStr,
        total: record.total, // 默认用第一个记录的 total
      };
    }
    hourlyRainfallMap[hourStr].intensity += record.intensity;
    // 取最大的 total(因为是累积值)
    if (record.total > hourlyRainfallMap[hourStr].total) {
      hourlyRainfallMap[hourStr].total = record.total;
    }
  });
  // 转换 map 成数组并排序
  const hourlyRainfallList = Object.values(hourlyRainfallMap).sort((a, b) =>
    a.time.localeCompare(b.time)
  );
  console.log("✅ 按小时聚合后的降雨数据:", hourlyRainfallList);
  // 设置全局变量
  rainTotalInfo.value = hourlyRainfallList;
  // 计算时间步长
  timeStepInfo = calculateTimeStep(rainTotalInfo.value);
  // 提取 intensity 值
  rainFallValues.value = rainfallList.map((r) => r.intensity);
  rainFallValues.value = hourlyRainfallList.map((r) => r.intensity);
  minRainValue.value = Math.min(...rainFallValues.value);
  maxRainValue.value = Math.max(...rainFallValues.value);
  console.log(
    "当前方案下最小雨量和最大雨量:",
    minRainValue.value,
@@ -497,7 +549,6 @@
// 预计算颜色阶段时间点
function precomputeColorStages() {
  if (!rainTotalInfo.value || rainTotalInfo.value.length === 0) return;
  // 颜色配置(亮度递减)
  const COLOR_STOPS = [
    { hex: "#F5F0E6", luminance: 240.4 }, // stage 0
@@ -517,10 +568,8 @@
    -0.7,   // stage 5
    -0.8    // stage 6
  ];
  // 累计降雨量阈值(mm)
  const R_THRESHOLDS = [0, 200, 240, 280, 310, 350]; // 共6个阶段对应6个阈值
  // 时间和降雨量信息
  const timeTotals = [];
  const initialTimestamp = new Date(rainTotalInfo.value[0].time).getTime();
@@ -536,7 +585,6 @@
  // 找出每个阶段首次达到的时间点
  const stages = [];
  for (let stage = 1; stage < R_THRESHOLDS.length + 1; stage++) {
    const threshold = R_THRESHOLDS[stage - 1];
    for (let i = 0; i < timeTotals.length; i++) {
@@ -616,20 +664,20 @@
  colorState.lastTime = currentTime.value;
  // ====== 新增:在 updateWaterColor 前打印当前信息 ======
  // // 获取当前累计降雨量
  // let currentTotal = null;
  // const baseTimestamp = new Date(rainTotalInfo.value[0].time).getTime();
  // const currentTimeMs = baseTimestamp + currentTime.value * 1000;
  let currentTotal = null;
  const baseTimestamp = new Date(rainTotalInfo.value[0].time).getTime();
  const currentTimeMs = baseTimestamp + currentTime.value * 1000;
  // // 找到最接近的降雨数据点
  // for (let i = rainTotalInfo.value.length - 1; i >= 0; i--) {
  //   const dataTimeMs = new Date(rainTotalInfo.value[i].time).getTime();
  //   if (dataTimeMs <= currentTimeMs) {
  //     currentTotal = rainTotalInfo.value[i].total;
  //     break;
  //   }
  // }
  // 找到最接近的降雨数据点
  for (let i = rainTotalInfo.value.length - 1; i >= 0; i--) {
    const dataTimeMs = new Date(rainTotalInfo.value[i].time).getTime();
    if (dataTimeMs <= currentTimeMs) {
      currentTotal = rainTotalInfo.value[i].total;
      break;
    }
  }
  // // 打印信息
  // 打印信息
  // console.log("========================================");
  // console.log(`【时间戳】: ${new Date(currentTimeMs).toLocaleString()}`);
  // console.log(`【累计降雨量 R】: ${currentTotal !== null ? currentTotal.toFixed(2) : '未知'} mm`);
@@ -879,7 +927,6 @@
    }
    // console.log('获取到的 serviceName:', serviceInfo);
    // 根据 layer.json 获取时间轴信息
    const {
      waterTimestamps: timestamps,
@@ -904,7 +951,6 @@
        "YYYY-MM-DD HH:mm:ss"
      );
    }
    minFlowRate = watersMinHeight;
    maxFlowRate = watersMaxHeight;
  } catch (error) {
@@ -921,9 +967,7 @@
  // 因为这个函数实时模拟监听也需要使用,所以封装了一个函数
  await initializeSimulationData();
});
const shouldAutoPlay = ref(false);
// 监听 layerDate 变化后标记准备播放
watch(
  () => layerDate.value,
@@ -934,7 +978,6 @@
  },
  { deep: true }
);
// 等待 finishPlay 成功后再播放
watchEffect(() => {
  if (shouldAutoPlay.value && finishPlay.value && !isPlaying.value) {
@@ -943,7 +986,6 @@
    shouldAutoPlay.value = false;
  }
});
// 根据返回数据的个数去渲染时间轴
function updateTimelineRange() {
  if (waterTimestamps.value.length > 0) {
@@ -954,7 +996,6 @@
    duration.value = (last - first) / 1000; // 毫秒转秒
  }
}
onBeforeUnmount(() => {
  stopPlayback();
  destoryWaterPrimitive();