1
wangjuncheng
8 天以前 5a93ff9c70a25e09d77aff8e9175022b63b3060f
src/views/GisView.vue
@@ -35,15 +35,25 @@
  initView,
  addTileset,
  addTerrain,
  removeEntities,
  clearAllPoints,
} from "@/utils/map.js";
import { loadAreaPolygon } from "@/utils/area.js";
import { loadAreaPolygonAll } from "@/utils/area_all.js";
import { isVisibleDistance } from "@/utils/customEntity";
import { getDistrictCount, getDistrictCountByCity } from "@/api/index";
import { useRoute } from "vue-router";
import { EventBus } from "@/eventBus"; // 引入事件总线
import { useSimStore } from "@/store/simulation";
const route = useRoute();
const simStore = useSimStore();
import {
  getDangerPoint,
  getDeviceInfo,
  getAeraCode,
  getAeraTownCode,
  getDeviceCount,
} from "@/api/hpApi";
/////////////////////////地图影像选择/////////////////////////
const views = [
  { label: "地图", value: "map", icon: "地图.png" },
@@ -107,7 +117,6 @@
};
/////////////////////////地图影像选择/////////////////////////
const route = useRoute();
let handler = null;
/////////////////////////初始化地图/////////////////////////
function initMap() {
@@ -385,17 +394,6 @@
///////////////////////// 区域标记点管理系统 /////////////////////////
// 存储所有创建的HTML实体(地图上的标记点)
const htmlEntityList = [];
const wmsLayers = []; // 存储创建的WMS图层
// 路由对应的 WMS 图层配置
const WMS_LAYER_MAP = {
  "/zhjc": {
    url: "http://192.168.56.106:8191/iserver/services/map-ywsj_view_jc_zkr_device_all_kb/wms130/ywsj_device_kb",
  },
  "/yhgl": {
    url: "http://192.168.56.106:8191/iserver/services/map-ywsj_view_dz_zkr_point_kb/wms130/ywsj_yhd_kb",
  },
};
// 统一管理所有区域标记的样式配置
const ENTITY_CONFIG = {
@@ -416,53 +414,81 @@
    maxVisibleDistance: 69000,
    minVisibleDistance: 20000,
    flyToHeight: 12000,
    wmsOptions: {
      sourceType: "wms",
      url: "", // 动态设置
      layers: "0.1",
      parameters: {
        format: "image/png",
        transparent: true,
        version: "1.1.1",
        srs: "EPSG:4326",
        query_layers: "0.2",
        info_format: "application/json",
      },
    },
  },
  // 一级区域
  primary: {
    maxVisibleDistance: 50000000,
    maxVisibleDistance: 60000000,
    minVisibleDistance: 70000,
    flyToHeight: 45000,
  },
};
// 更新 WMS 配置函数(根据当前路由)
function updateWmsLayerByRoute(currentPath) {
  const config = WMS_LAYER_MAP[currentPath];
  if (!config) return;
  LEVEL_CONFIG.secondary.wmsOptions.url = config.url;
}
// 初始化区域统计
function initDistrictCount(level = "secondary") {
  const getPoint =
    level === "secondary" ? getDistrictCount : getDistrictCountByCity;
  const config = LEVEL_CONFIG[level];
async function initDistrictCount(level = "secondary") {
  try {
    const deviceAreaTotal = ref([]);
    const deviceTownTotal = ref([]);
  getPoint()
    .then((res) => {
    if (level === "primary") {
      // 一级区域处理
      if (route.path === "/zhjc") {
        deviceAreaTotal.value = await getDeviceCount(); // 获取区级设备统计
      }
      const res = await getAeraCode();
      res.data.forEach((item) => {
        processDistrictItem(item, config, level); // 添加level参数
        if (route.path === "/zhjc") {
          const matchedDistrict = deviceAreaTotal.value.data?.find(
            (d) => d.districtName === item.districtName
          );
          if (matchedDistrict) {
            item.count = matchedDistrict.count; // 更新 count
          }
        }
        processDistrictItem(item, LEVEL_CONFIG[level], level);
      });
    })
    .catch((error) => {
      console.error(`初始化${level}级区域统计失败:`, error);
    });
}
    } else if (level === "secondary") {
      // 二级区域处理
      const primaryRes = await getAeraCode();
      if (route.path === "/zhjc") {
        // 并发获取每个区的设备统计
        deviceTownTotal.value = await Promise.all(
          primaryRes.data.map((item) =>
            getDeviceCount({ districtCode: Number(item.districtCode) })
          )
        );
      }
      // 并发获取每个区下的镇数据
      const townResults = await Promise.all(
        primaryRes.data.map((item) => getAeraTownCode(item.districtCode))
      );
      // 处理每个区的镇数据
      for (let i = 0; i < townResults.length; i++) {
        const townRes = townResults[i];
        const deviceCountData = deviceTownTotal.value[i]?.data || []; // 对应区的设备统计数据
        townRes.data.forEach((townItem) => {
          if (route.path === "/zhjc") {
            const matchedTown = deviceCountData.find(
              (d) => d.districtName === townItem.districtName
            );
            if (matchedTown) {
              townItem.count = matchedTown.count;
            }
          }
          processDistrictItem(townItem, LEVEL_CONFIG[level], level);
        });
      }
    } else {
      console.error("未知的 level 类型:", level);
    }
  } catch (error) {
    console.error(`初始化 ${level} 级区域统计失败:`, error);
  }
}
// 处理单个区域项
function processDistrictItem(item, config, level = "secondary") {
  // 添加默认值
@@ -475,40 +501,98 @@
    primaryHandler(html, item, config);
  }
  // 此处必须加,不然二次调用初始化函数的时候会将一二级区域所有的点都显示在页面上
  html.show = isVisibleDistance(
    config.minVisibleDistance,
    config.maxVisibleDistance
  );
  htmlEntityList.push(html);
}
import { ElMessage } from "element-plus";
// 设置二级区域点击处理(包含WMS图层)
const districtList = ref([]);
// 设置二级区域点击处理(请求隐患点,监测设备等)
function secondaryHandler(html, item, config) {
  html.element.addEventListener("click", async () => {
    try {
      // 先飞向目标位置
      // 清理已有点
      handleCleanup();
      // 显示 loading 提示(无遮罩,仅文字+转圈)
      const loadingInstance = ElMessage({
        type: "info",
        message: "数据正在加载中...",
        duration: 0, // 持续显示,直到手动关闭
        icon: "loading", // 显示为 loading 图标(Element Plus 支持)
        grouping: true, // 相同内容的消息合并,避免重复提示
      });
      let res;
      if (route.path === "/yhgl") {
        // 请求隐患点数据
        res = await getDangerPoint(item.districtCode);
      } else if (route.path === "/zhjc") {
        // 请求监测设备数据
        res = await getDeviceInfo(null, item.districtCode);
      } else {
        loadingInstance.close();
        return;
      }
      districtList.value = [];
      // 更新数据
      districtList.value = res.data.pageData;
      if (districtList.value.length === 0) {
        ElMessage.warning("该区域暂无相关数据");
        loadingInstance.close();
        return;
      }
      // 创建地图点
      for (const [index, point] of districtList.value.entries()) {
        point.id = point.hdId || point.deviceId; // 根据实际情况调整
        point.latitude = point.lat || point.latitude; // 根据实际情况调整
        point.longitude = point.lon || point.longitude; // 根据实际情况调整
        point.showBillboard = true;
        point.type = point.disasterType || point.deviceTypeName; // 根据实际情况调整
        point.className = "district";
        // ✅ 根据路由决定名称字段
        if (route.path === "/yhgl") {
          point.name = point.hdName; // 隐患点名称
          point.className = "district";
        } else if (route.path === "/zhjc") {
          point.name = point.deviceName; // 设备简称
          point.className = "device";
        }
        await createPoint(point);
      }
      // 飞向指定位置
      await flyToDistrict(item.longitude, item.latitude, config.flyToHeight);
      // 移除旧图层
      removeAllWmsLayers();
      // 延时1秒后添加新图层
      setTimeout(() => {
        // 如果满足可视范围,尝试重新加载 WMS 图层
        const cameraHeight = viewer.camera.positionCartographic.height;
        // loadWmsImg(cameraHeight);
      }, 1000); // 1000毫秒 = 1秒
      // 设置WMS要素查询
      setupWmsFeatureQuery();
      // 添加新的点击事件
      // 加载完成后关闭 loading 提示
      loadingInstance.close();
    } catch (error) {
      console.error("区域点击处理失败:", error);
      ElMessage.error("数据加载失败,请稍后再试");
      // loadingInstance.close(); // 确保在发生错误时也关闭 loading 提示
    }
  });
}
const handleCleanup = async () => {
  districtList.value = [];
  clearAllPoints();
};
// 设置一级区域点击处理
function primaryHandler(html, item, config) {
  html.element.addEventListener("click", () => {
    flyToDistrict(item.longitude, item.latitude, config.flyToHeight);
    console.log(item.districtCode, "itemitemitemitem");
  });
}
@@ -553,85 +637,32 @@
  });
}
// 路由监听
// 在路由监听器中
const validPaths = ["/", "/yhgl", "/zhjc"];
watch(
  () => route.fullPath,
  (val) => {
    const isValidPath = validPaths.includes(val);
    // 更新 WMS 图层配置
    updateWmsLayerByRoute(val);
    // 控制HTML实体显示
    htmlEntityList.forEach((item) => {
      item.show = isValidPath
        ? isVisibleDistance(item.minVisibleDistance, item.maxVisibleDistance)
        : false;
    });
    // 控制相机变化监听
    if (isValidPath) {
      initAllDistrictCounts();
      handleCameraChange();
      // 如果满足可视范围,尝试重新加载 WMS 图层
      const cameraHeight = viewer.camera.positionCartographic.height;
      // loadWmsImg(cameraHeight);
      // 控制HTML实体显示
      htmlEntityList.forEach((item) => {
        item.show = isValidPath
          ? isVisibleDistance(item.minVisibleDistance, item.maxVisibleDistance)
          : false;
      });
    } else {
      htmlEntityList.forEach((item) => {
        item.show = false;
      });
      removeCameraChange();
      removeAllWmsLayers();
    }
  }
);
// 自动加载 WMS 图层
async function loadWmsImg(cameraHeight) {
  const config = LEVEL_CONFIG.secondary;
  // 判断是否处于二级可视范围内
  if (cameraHeight <= config.minVisibleDistance) {
    // 如果当前没有WMS图层,则自动加载第一个二级点的WMS图层
    if (wmsLayers.length === 0 && htmlEntityList.length > 0) {
      const firstItem = htmlEntityList[0]; // 可以选任意一个二级点
      removeAllWmsLayers(); // 清除可能存在的残留图层
      earthCtrl.factory
        .createImageryLayer(config.wmsOptions)
        .then((wmsLayer) => {
          wmsLayers.push(wmsLayer);
        });
    } else {
      // 已有图层但URL变了,需要更新
      const currentUrl = wmsLayers[0]?.imageryProvider?.url;
      if (currentUrl !== config.wmsOptions.url) {
        removeAllWmsLayers();
        earthCtrl.factory
          .createImageryLayer(config.wmsOptions)
          .then((wmsLayer) => {
            wmsLayers.push(wmsLayer);
          });
      }
    }
  } else if (cameraHeight > config.maxVisibleDistance && wmsLayers.length > 0) {
    // 如果超出可视范围且已有WMS图层,则清除
    removeAllWmsLayers();
    // 可以在这里移除事件监听器
    if (clickHandler) {
      clickHandler.destroy();
      clickHandler = null;
    }
  }
}
let clickHandler = null;
// 移除所有WMS图层
function removeAllWmsLayers() {
  wmsLayers.forEach((layer) => {
    layer.removeFromMap();
  });
  wmsLayers.length = 0; // 清空数组
}
let cameraChangeTimer = null;
@@ -643,8 +674,6 @@
  }
  cameraChangeTimer = setTimeout(() => {
    const cameraHeight = viewer.camera.positionCartographic.height;
    // 更新HTML实体显示状态
    htmlEntityList.forEach((item) => {
      item.show = isVisibleDistance(
@@ -652,9 +681,6 @@
        item.maxVisibleDistance
      );
    });
    // 检查是否需要自动加载或清除WMS图层
    // loadWmsImg(cameraHeight);
  }, 100);
}
@@ -668,87 +694,17 @@
// 初始化函数
function initAllDistrictCounts() {
  initDistrictCount("secondary"); // 二级区域
  initDistrictCount("primary"); // 一级区域
  initDistrictCount("secondary"); // 二级区域
}
// 设置WMS要素查询
function setupWmsFeatureQuery() {
  // // 先移除已有的事件监听(不能要,要了之后隐患点就不会请求了)
  // earthCtrl.viewer.screenSpaceEventHandler.removeInputAction(
  //   Cesium.ScreenSpaceEventType.LEFT_CLICK
  // );
  // 添加新的点击事件
  earthCtrl.viewer.screenSpaceEventHandler.setInputAction(
    handleMapClick,
    Cesium.ScreenSpaceEventType.LEFT_CLICK
  );
}
// 处理地图点击查询
function handleMapClick(click) {
  console.log("点击屏幕位置:", click.position);
  // 1. 获取点击位置的地理坐标
  const ray = viewer.camera.getPickRay(click.position);
  if (!ray) {
    console.log("无法获取拾取射线");
    return;
  }
  const cartesian = viewer.scene.globe.pick(ray, viewer.scene);
  if (!cartesian) {
    console.log("无法获取地理坐标");
    return;
  }
  // console.log("cartesian:", cartesian);
  const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
  const longitude = Cesium.Math.toDegrees(cartographic.longitude);
  const latitude = Cesium.Math.toDegrees(cartographic.latitude);
  console.log("点击位置坐标:", longitude, latitude);
  queryWmsFeatures(longitude, latitude, click.position);
}
// 查询WMS要素
function queryWmsFeatures(longitude, latitude, clickPosition) {
  const wmsUrl = LEVEL_CONFIG.secondary.wmsOptions.url;
  const params = new URLSearchParams({
    SERVICE: "WMS",
    VERSION: "1.1.1",
    REQUEST: "GetFeatureInfo",
    LAYERS: "0.1", // 查询信息所在的图层
    QUERY_LAYERS: "0.2",
    INFO_FORMAT: "text/xml",
    FEATURE_COUNT: "10", // 返回最多10个要素
    X: Math.floor(clickPosition.x),
    Y: Math.floor(clickPosition.y),
    SRS: "EPSG:4326",
    WIDTH: viewer.canvas.width,
    HEIGHT: viewer.canvas.height,
    BBOX: [longitude - 1, latitude - 1, longitude + 1, latitude + 1].join(","),
  });
  const featureInfoUrl = wmsUrl + "?" + params.toString();
  // console.log("请求URL:", featureInfoUrl);
  // 3. 发送GetFeatureInfo请求
  fetch(featureInfoUrl)
    .then((res) => res.text()) // 先获取文本
    .then((text) => {
      // console.log(text);
    });
}
onMounted(() => {
  initMap();
  addCityPolygon();
  initHandler();
  // initView()
  loadAreaPolygon("/json/nsl_area.geojson");
  loadAreaPolygonAll("/json/geometry.json", true);
  // loadAreaPolygon("/json/nsl_area.geojson");
  // loadAreaPolygonAll("/json/geometry.json", true);
  flyToHomeView();
  // 页面加载时初始化
  initAllDistrictCounts();