guonan
2025-06-06 cf4ed06dea0076e518319de24c5120bb3fe0dae9
src/views/GisView.vue
@@ -1,59 +1,284 @@
<template>
  <div id="gis-view" ref="mapRef"></div>
  <!-- 切换底图影像 -->
  <div
    @click="handleShow"
    class="diqiu"
    :class="{ 'shift-right': simStore.isShowEarth }"
  >
    <img src="@/assets/img/screen/dq.png" alt="" />
  </div>
  <div
    v-show="picShow"
    class="earthBox"
    :class="{ 'shift-right': simStore.isShowEarth }"
  >
    <div
      v-for="(item, index) in views"
      :key="index"
      :class="['item-container', { active: currentIndex === index }]"
      @click="switchView(index)"
    >
      <div class="icon-wrapper">
        <img :src="getImageUrl(item.icon)" :alt="item.label" />
        <span class="label">{{ item.label }}</span>
      </div>
    </div>
  </div>
</template>
<script setup>
import { onMounted, onUnmounted, ref, watch } from "vue"
import { createPoint, initHandler, initView, addTileset, addTerrain } 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"
const route = useRoute()
let handler = null
function initMap () {
  window.Cesium = SmartEarth.Cesium
  window.earthCtrl = new SmartEarth.EarthCtrl("gis-view")
import { onMounted, onUnmounted, ref, watch } from "vue";
import {
  createPoint,
  initHandler,
  initView,
  addTileset,
  addTerrain,
} 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 simStore = useSimStore();
/////////////////////////地图影像选择/////////////////////////
const views = [
  { label: "地图", value: "map", icon: "地图.png" },
  { label: "影像", value: "image", icon: "影像.png" },
  { label: "地形", value: "terrain", icon: "地形.png" },
];
const getImageUrl = (iconName) => {
  return `/images/earth/${iconName}`;
};
const picShow = ref(false);
const handleShow = () => {
  picShow.value = !picShow.value;
};
const currentIndex = ref(-1);
let currentLayer = null;
const switchView = async (index) => {
  currentIndex.value = index;
  // 如果已经有图层存在,先从地图中移除
  if (currentLayer) {
    currentLayer.removeFromMap();
    currentLayer = null; // 清空引用
  }
  if (views[index].value === "map") {
    // 百度地图
    currentLayer = await earthCtrl.factory.createImageryLayer({
      sourceType: "baidu",
      url: "https://ss1.bdstatic.com/8bo_dTSlR1gBo1vgoIiO_jowehsv/tile/?qt=vtile&x={x}&y={y}&z={z}&styles=pl&udt=20180810&scaler=1&showtext=1",
    });
  } else if (views[index].value === "image") {
    currentLayer = await earthCtrl.factory.createImageryLayer({
      sourceType: "mapworld",
      url: "https://t0.tianditu.gov.cn/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=3ec79cf7a9dcc6bb18411a5414b148cb",
      layers: "tdtBasicLayer",
      style: "default",
      format: "image/jpeg",
      maximumLevel: 18,
      layer: "",
      tileMatrixSetID: "",
    });
    //标注层
    currentLayer = await earthCtrl.factory.createImageryLayer({
      sourceType: "mapworld",
      subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
      url: "https://{s}.tianditu.gov.cn/cia_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=cia&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&tk=c53eb074c3fcba5ac86103d4d711bbe8",
    });
  } else if (views[index].value === "terrain") {
    // 地形图层
    currentLayer = await earthCtrl.factory.createTerrainLayer({
      sourceType: "arcgis",
      url: "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer",
    });
  }
};
/////////////////////////地图影像选择/////////////////////////
const route = useRoute();
let handler = null;
/////////////////////////初始化地图/////////////////////////
function initMap() {
  window.Cesium = SmartEarth.Cesium;
  window.earthCtrl = new SmartEarth.EarthCtrl("gis-view");
  window.viewer = earthCtrl.viewer;
  // 1. 设置初始时间
  const date = new Date(2025, 3, 11, 12, 0, 0, 0);
  const julianDate = SmartEarth.Cesium.JulianDate.fromDate(date);
  // 2. 配置时钟选项
  earthCtrl.viewer.clockViewModel.shouldAnimate = false;
  earthCtrl.viewer.clockViewModel.clockRange =
    SmartEarth.Cesium.ClockRange.CLAMPED;
  earthCtrl.viewer.clockViewModel.multiplier = 0;
  earthCtrl.viewer.clock.currentTime = julianDate;
  //显示fps
  earthCtrl.showFPS = true
  // 显示fps
  earthCtrl.showFPS = true;
  // 先添加底图
  earthCtrl.factory.createImageryLayer({
    sourceType: "mapworld",
    url: "https://t0.tianditu.gov.cn/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=3ec79cf7a9dcc6bb18411a5414b148cb",
    url: "http://t0.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=7eb11c0c503429878691ac917238f87f",
    layers: "tdtBasicLayer",
    style: "default",
    format: "image/jpeg",
    maximumLevel: 18,
    layer: "",
    tileMatrixSetID: "",
  })
  // 关闭地形深度检测
  // viewer.scene.globe.depthTestAgainstTerrain = false;
  });
}
function addCityPolygon () {
  const url = `/json/110000.geo.json`
/////////////////////////新建方案区域选择/////////////////////////
const MULTIPOLYGON_COORDS = ref([]);
let previousEntities = []; // 用于存储之前创建的实体
const flyToHeight = ref(null);
const ShowFill = ref(true);
// 监听新建方案选择的区域范围
EventBus.on("select-geom", ({ geom, flyHeight, shouldShowFill }) => {
  flyToHeight.value = flyHeight;
  ShowFill.value = shouldShowFill;
  const coordsStr = geom
    .replace("MULTIPOLYGON(((", "") // 去掉开头
    .replace(")))", ""); // 去掉结尾
  // 分割成 ["lon lat", "lon lat", ...]
  const coordPairs = coordsStr.split(",");
  // 转换为 [[[lon, lat], [lon, lat], ...]] 格式
  MULTIPOLYGON_COORDS.value = [
    coordPairs.map((pair) => {
      const [lon, lat] = pair.trim().split(" ").map(Number);
      return [lon, lat];
    }),
  ];
  // 检查是否是空多边形,如果是空,则去掉面片颜色,并飞回初始位置
  if (geom === "MULTIPOLYGON EMPTY") {
    clearPreviousEntities();
    flyToHomeView();
    return; // 不执行后续操作
  }
  // 清除之前的所有实体
  clearPreviousEntities();
  // 选中区域标色
  addCustomPolygon(ShowFill.value);
});
// 清除之前的所有实体
function clearPreviousEntities() {
  previousEntities.forEach((entity) => {
    viewer.entities.remove(entity);
  });
  previousEntities = [];
}
// 计算选中区域中心点
function calculateCenter(coordinates) {
  const lons = coordinates.flat().map((coord) => coord[0]);
  const lats = coordinates.flat().map((coord) => coord[1]);
  return {
    lon: (Math.min(...lons) + Math.max(...lons)) / 2,
    lat: (Math.min(...lats) + Math.max(...lats)) / 2,
  };
}
function convertToGeoJson(coords) {
  return {
    type: "Feature",
    id: 0,
    bbox: calculateCenter(MULTIPOLYGON_COORDS.value), // 可选
    properties: {
      center: calculateCenter(MULTIPOLYGON_COORDS.value), // 第一个点作为 center
      centroid: MULTIPOLYGON_COORDS.value[0][0], // 可选
      level: "district",
      code: 123456,
      districtCount: 0,
    },
    geometry: {
      type: "MultiPolygon",
      coordinates: [coords], // 包装成 MultiPolygon
    },
  };
}
function addCustomPolygon(ShowFill = true) {
  // 将 MULTIPOLYGON_COORDS.value 转换为 GeoJSON 格式
  const geoJson = convertToGeoJson(MULTIPOLYGON_COORDS.value);
  const center = geoJson.properties.center;
  // 创建多边形实体,并根据 ShowFill 参数决定是否显示填充颜色
  const polygonEntity = viewer.entities.add({
    polygon: {
      hierarchy: Cesium.Cartesian3.fromDegreesArray(
        geoJson.geometry.coordinates[0][0].flat()
      ),
      material: ShowFill
        ? Cesium.Color.RED.withAlpha(0.3) // 半透明红色填充
        : new Cesium.ColorMaterialProperty(Cesium.Color.TRANSPARENT), // 如果不需要填充,则使用透明材质
      outline: true,
      outlineColor: Cesium.Color.RED, // 红色边框
      outlineWidth: 5,
      clampToGround: true, // 贴地显示
    },
  });
  previousEntities.push(polygonEntity);
  // 飞向中心点
  viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(
      center.lon,
      center.lat,
      flyToHeight.value
    ), // 提高到指定高度
    orientation: {
      heading: Cesium.Math.toRadians(0), // 正北方向
      pitch: Cesium.Math.toRadians(-90), // 向下倾斜90度(垂直俯视)
      roll: 0.0,
    },
  });
}
EventBus.on("close-selectArea", () => {
  clearPreviousEntities();
  flyToHomeView();
});
/////////////////////////新建方案区域选择/////////////////////////
function addCityPolygon() {
  const url = `/json/110000.geo.json`;
  let wallLayer = earthCtrl.factory.createTrailWallLayer({
    url: "/json/110000.geojson",
    color: "LIGHTSTEELBLUE", //颜色
    height: 2000, //高度
    speed: 3,
  })
  });
  const dataSourcePromise = Cesium.GeoJsonDataSource.load(url, {
    clampToGround: true,
  })
  });
  return dataSourcePromise.then(function (dataSource) {
    viewer.dataSources.add(dataSource)
    const polygonEntity = dataSource.entities.values
    console.log("polygonEntity", polygonEntity)
    const distanceDisplayCondition = new Cesium.DistanceDisplayCondition(1000, 50000000)
    polygonEntity.forEach(entity => {
      // console.log("entity", entity)
    viewer.dataSources.add(dataSource);
    // 所有的数据
    const polygonEntity = dataSource.entities.values;
    const distanceDisplayCondition = new Cesium.DistanceDisplayCondition(
      1000,
      50000000
    );
    polygonEntity.forEach((entity) => {
      entity.polygon.material = new Cesium.ColorMaterialProperty(
        Cesium.Color.LIGHTSTEELBLUE.withAlpha(0)
        // new Cesium.Color.fromCssColorString("#0f2636b3")
@@ -62,24 +287,24 @@
        //    minimumAlpha: 0.2,
        //    maximumAlpha: 0.9,
        // })
      )
      );
      entity.polygon.distanceDisplayCondition = distanceDisplayCondition
      entity.polygon.distanceDisplayCondition = distanceDisplayCondition;
      const properties = entity.properties
      const center = properties.centroid.getValue()
      const fullname = properties.fullname.getValue()
      const districtCount = properties.districtCount.getValue() || 0
      const properties = entity.properties;
      const center = properties.centroid.getValue();
      const fullname = properties.fullname.getValue();
      const districtCount = properties.districtCount.getValue() || 0;
      const position = Cesium.Cartesian3.fromDegrees(center[0], center[1])
      const positions = entity.polygon.hierarchy._value.positions
      const position = Cesium.Cartesian3.fromDegrees(center[0], center[1]);
      const positions = entity.polygon.hierarchy._value.positions;
      entity.position = position
      entity.position = position;
      // 判断是否为东城区或西城区
      let labelText = fullname || "默认标签"
      let labelText = fullname || "默认标签";
      if (fullname === "东城区" || fullname === "西城区") {
        // 将文本拆分为竖列
        labelText = fullname.split("").join("\n")
        labelText = fullname.split("").join("\n");
      }
      entity.label = {
        // 文本。支持显式换行符“ \ n”
@@ -118,7 +343,7 @@
        disableDepthTestDistance: Number.POSITIVE_INFINITY,
        // 是否显示
        show: true,
      }
      };
      entity.polyline = {
        positions: positions,
        width: 5,
@@ -132,16 +357,16 @@
        ),
        clampToGround: true,
        distanceDisplayCondition: distanceDisplayCondition,
      }
      };
      viewer.entities.add(entity)
    })
      viewer.entities.add(entity);
    });
    // 获取 GeoJSON 中的第一个 Polygon feature
  })
  });
}
function flyToHomeView () {
function flyToHomeView() {
  const view = {
    destination: {
      x: -2355432.569004413,
@@ -153,158 +378,388 @@
      roll: 0.00031421159527500464,
      heading: 6.140424766644804,
    },
  };
  viewer.scene.camera.flyTo(view);
}
///////////////////////// 区域标记点管理系统 /////////////////////////
// 存储所有创建的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 = {
  label: {
    backgroundColor: SmartEarth.Cesium.Color.SKYBLUE.withAlpha(0.8),
    font: "14pt Source Han Sans CN",
    fillColor: SmartEarth.Cesium.Color.WHITE,
    showBackground: true,
  },
  showBillboard: false,
  showLabel: true,
};
// 区域级别配置
const LEVEL_CONFIG = {
  // 二级区域
  secondary: {
    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,
    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];
  getPoint()
    .then((res) => {
      res.data.forEach((item) => {
        processDistrictItem(item, config, level); // 添加level参数
      });
    })
    .catch((error) => {
      console.error(`初始化${level}级区域统计失败:`, error);
    });
}
// 处理单个区域项
function processDistrictItem(item, config, level = "secondary") {
  // 添加默认值
  normalizeItemData(item);
  const html = createDistrictHtmlMarker(item, config);
  if (level === "secondary") {
    secondaryHandler(html, item, config);
  } else {
    primaryHandler(html, item, config);
  }
  viewer.scene.camera.flyTo(view)
  htmlEntityList.push(html);
}
let htmlEntityList = []
function initDistrictCount () {
  getDistrictCount().then(res => {
    res.data.forEach(item => {
      const { districtName, count, lat, lon } = item
      item.name = `${item.districtName}\n${item.count}`
      item.longitude = item.lon
      item.latitude = item.lat
      item.showBillboard = false
      item.showLabel = true
      item.label = {
        text: item.name,
        backgroundColor: SmartEarth.Cesium.Color.SKYBLUE.withAlpha(0.8),
        font: "14pt Source Han Sans CN",
        fillColor: SmartEarth.Cesium.Color.WHITE,
        showBackground: true,
      }
      // createPoint(item)
      const html = earthCtrl.view.createScreenDialog({
        html: `
                  <div class="district-count">
                     <div class="name">${districtName}</div>
                     <div class="value">${count}</div>
               </div>
               `,
        lon: item.lon,
        lat: item.lat,
        height: 0,
      })
      html.maxVisibleDistance = 69000
      html.minVisibleDistance = 20000
      html.element.addEventListener("click", () => {
        viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, 12000),
          orientation: {
            pitch: Cesium.Math.toRadians(-90),
            heading: Cesium.Math.toRadians(0),
            roll: 0,
          },
          duration: 2,
        })
      })
// 设置二级区域点击处理(包含WMS图层)
function secondaryHandler(html, item, config) {
  html.element.addEventListener("click", async () => {
    try {
      // 先飞向目标位置
      await flyToDistrict(item.longitude, item.latitude, config.flyToHeight);
      htmlEntityList.push(html)
    })
  })
}
function initDistrictCountByCity () {
  getDistrictCountByCity().then(res => {
    res.data.forEach(item => {
      const { districtName, count, lat, lon } = item
      item.name = `${item.districtName}\n${item.count}`
      item.longitude = item.lon
      item.latitude = item.lat
      item.showBillboard = false
      item.showLabel = true
      item.label = {
        text: item.name,
        backgroundColor: SmartEarth.Cesium.Color.SKYBLUE.withAlpha(0.8),
        font: "14pt Source Han Sans CN",
        fillColor: SmartEarth.Cesium.Color.WHITE,
        showBackground: true,
      }
      // createPoint(item)
      const html = earthCtrl.view.createScreenDialog({
        html: `
                  <div class="district-count">
                     <div class="name">${districtName}</div>
                     <div class="value">${count}</div>
               </div>
               `,
        lon: item.lon,
        lat: item.lat,
        height: 0,
      })
      html.maxVisibleDistance = 50000000
      html.minVisibleDistance = 70000
      html.element.addEventListener("click", () => {
        viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude, 45000),
          orientation: {
            pitch: Cesium.Math.toRadians(-90),
            heading: Cesium.Math.toRadians(0),
            roll: 0,
          },
          duration: 2,
        })
      })
      // 移除旧图层
      removeAllWmsLayers();
      // 延时1秒后添加新图层
      setTimeout(() => {
        // 如果满足可视范围,尝试重新加载 WMS 图层
        const cameraHeight = viewer.camera.positionCartographic.height;
        // loadWmsImg(cameraHeight);
      }, 1000); // 1000毫秒 = 1秒
      htmlEntityList.push(html)
    })
  })
      // 设置WMS要素查询
      setupWmsFeatureQuery();
      // 添加新的点击事件
    } catch (error) {
      console.error("区域点击处理失败:", error);
    }
  });
}
// 设置一级区域点击处理
function primaryHandler(html, item, config) {
  html.element.addEventListener("click", () => {
    flyToDistrict(item.longitude, item.latitude, config.flyToHeight);
    console.log(item.districtCode, "itemitemitemitem");
  });
}
// 统一数据格式和添加默认配置
function normalizeItemData(item) {
  item.name = `${item.districtName}\n${item.count}`;
  item.longitude = item.lon;
  item.latitude = item.lat;
  Object.assign(item, ENTITY_CONFIG);
}
// 创建HTML标记
function createDistrictHtmlMarker(item, config) {
  const html = earthCtrl.view.createScreenDialog({
    html: `
      <div class="district-count">
        <div class="name">${item.districtName}</div>
        <div class="value">${item.count}</div>
      </div>
    `,
    lon: item.lon,
    lat: item.lat,
    height: 0,
  });
  html.maxVisibleDistance = config.maxVisibleDistance;
  html.minVisibleDistance = config.minVisibleDistance;
  return html;
}
// 飞向指定区域
function flyToDistrict(longitude, latitude, height) {
  viewer.camera.flyTo({
    destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height),
    orientation: {
      pitch: Cesium.Math.toRadians(-90),
      heading: Cesium.Math.toRadians(0),
      roll: 0,
    },
    duration: 2,
  });
}
// 路由监听
const validPaths = ["/", "/yhgl", "/zhjc"];
watch(
  () => route.fullPath,
  val => {
    if (val != "/") {
      // clusterLayer.dataSource.show = false
      htmlEntityList.forEach(item => {
        item.show = false
      })
      removeCameraChange()
  (val) => {
    const isValidPath = validPaths.includes(val);
    // 更新 WMS 图层配置
    updateWmsLayerByRoute(val);
    // 控制HTML实体显示
    htmlEntityList.forEach((item) => {
      item.show = isValidPath
        ? isVisibleDistance(item.minVisibleDistance, item.maxVisibleDistance)
        : false;
    });
    // 控制相机变化监听
    if (isValidPath) {
      handleCameraChange();
      // 如果满足可视范围,尝试重新加载 WMS 图层
      const cameraHeight = viewer.camera.positionCartographic.height;
      // loadWmsImg(cameraHeight);
    } else {
      handleCameraChange()
      // clusterLayer.dataSource.show = true
      htmlEntityList.forEach(item => {
        item.show = true
      })
      removeCameraChange();
      removeAllWmsLayers();
    }
  }
)
function handleCameraChange () {
  viewer.camera.changed.addEventListener(toggleHtmlLayerByVisibleDistance)
}
function removeCameraChange () {
  viewer.camera.changed.removeEventListener(toggleHtmlLayerByVisibleDistance)
}
let cameraChangeTimer = null
);
function toggleHtmlLayerByVisibleDistance () {
  if (cameraChangeTimer) {
    clearTimeout(cameraChangeTimer)
    cameraChangeTimer = null
    return
// 自动加载 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;
    }
  }
  cameraChangeTimer = setTimeout(() => {
    htmlEntityList.forEach(item => {
      item.show = isVisibleDistance(item.minVisibleDistance, item.maxVisibleDistance)
    })
  }, 100)
}
let clickHandler = null;
// 移除所有WMS图层
function removeAllWmsLayers() {
  wmsLayers.forEach((layer) => {
    layer.removeFromMap();
  });
  wmsLayers.length = 0; // 清空数组
}
let cameraChangeTimer = null;
function toggleHtmlLayerByVisibleDistance() {
  if (cameraChangeTimer) {
    clearTimeout(cameraChangeTimer);
    cameraChangeTimer = null;
    return;
  }
  cameraChangeTimer = setTimeout(() => {
    const cameraHeight = viewer.camera.positionCartographic.height;
    // 更新HTML实体显示状态
    htmlEntityList.forEach((item) => {
      item.show = isVisibleDistance(
        item.minVisibleDistance,
        item.maxVisibleDistance
      );
    });
    // 检查是否需要自动加载或清除WMS图层
    // loadWmsImg(cameraHeight);
  }, 100);
}
function handleCameraChange() {
  viewer.camera.changed.addEventListener(toggleHtmlLayerByVisibleDistance);
}
function removeCameraChange() {
  viewer.camera.changed.removeEventListener(toggleHtmlLayerByVisibleDistance);
}
// 初始化函数
function initAllDistrictCounts() {
  initDistrictCount("secondary"); // 二级区域
  initDistrictCount("primary"); // 一级区域
}
// 设置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()
  initMap();
  addCityPolygon();
  initHandler();
  // initView()
  loadAreaPolygon("/json/nsl_area.geojson")
  loadAreaPolygonAll("/json/geometry.json", true)
  flyToHomeView()
  initDistrictCount()
  initDistrictCountByCity()
  handleCameraChange()
  loadAreaPolygon("/json/nsl_area.geojson");
  loadAreaPolygonAll("/json/geometry.json", true);
  flyToHomeView();
  // 页面加载时初始化
  initAllDistrictCounts();
  handleCameraChange();
  // 设置 billboard 点击事件
})
});
onUnmounted(() => {
  removeCameraChange()
})
  removeCameraChange();
  EventBus.off("select-geom");
  EventBus.off("close-selectArea");
});
</script>
<style lang="less" scoped>
@@ -313,4 +768,77 @@
  height: 100vh;
  position: absolute;
}
// // 修改指南针位置
/deep/ .compass {
  right: 128px !important;
  top: 112px;
}
.diqiu {
  position: absolute;
  bottom: 8%;
  right: 4%;
  z-index: 9999;
}
.earthBox {
  z-index: 9999;
  width: 12%;
  height: 7%;
  background-color: rgba(0, 9, 9, 0.3);
  position: absolute;
  right: 8%;
  bottom: 6%;
  display: flex;
  justify-content: space-evenly;
  padding: 10px 6px;
}
.icon-wrapper {
  position: relative;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  border: 1px solid transparent; /* 默认透明边框占位 */
  img {
    height: 100%;
    width: auto; /* 确保图片按比例缩放 */
    margin: 0;
    padding: 0;
    display: block; /* 移除图片下方可能存在的空白间隙 */
  }
  .label {
    position: absolute;
    bottom: 0;
    right: 0;
    left: 0;
    background-color: rgba(0, 0, 0, 0.5);
    text-align: center;
    color: white;
  }
}
.item-container {
  position: relative;
  display: inline-block;
  cursor: pointer;
}
.item-container.active .icon-wrapper {
  border: 1px solid #218967; /* 蓝色边框 */
}
.item-container.active .label {
  background-color: rgba(33, 137, 103, 0.8);
}
.diqiu.shift-right {
  right: 10%;
}
.earthBox.shift-right {
  right: 13%;
}
</style>