guonan
2025-06-04 1dd9751171f27170d7b96e51b7074b336a545f7a
src/views/GisView.vue
@@ -1,5 +1,22 @@
<template>
  <div id="gis-view" ref="mapRef"></div>
  <!-- 切换底图影像 -->
  <div @click="handleShow" class="diqiu">
    <img src="@/assets/img/screen/dq.png" alt="" />
  </div>
  <div v-show="picShow" class="earthBox">
    <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>
@@ -18,6 +35,66 @@
import { useRoute } from "vue-router";
import { EventBus } from "@/eventBus"; // 引入事件总线
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() {
@@ -41,6 +118,8 @@
  //显示fps
  earthCtrl.showFPS = true;
  // 系统目前默认使用的
  earthCtrl.factory.createImageryLayer({
    sourceType: "mapworld",
    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",
@@ -58,10 +137,12 @@
const MULTIPOLYGON_COORDS = ref([]);
let previousEntities = []; // 用于存储之前创建的实体
const flyToHeight = ref(null);
const ShowFill = ref(true);
// 监听新建方案选择的区域范围
EventBus.on("select-geom", ({ geom, flyHeight }) => {
EventBus.on("select-geom", ({ geom, flyHeight, shouldShowFill }) => {
  flyToHeight.value = flyHeight;
  ShowFill.value = shouldShowFill;
  const coordsStr = geom
    .replace("MULTIPOLYGON(((", "") // 去掉开头
    .replace(")))", ""); // 去掉结尾
@@ -87,7 +168,7 @@
  // 清除之前的所有实体
  clearPreviousEntities();
  // 选中区域标色
  addCustomPolygon();
  addCustomPolygon(ShowFill.value);
});
// 清除之前的所有实体
@@ -127,25 +208,27 @@
  };
}
function addCustomPolygon() {
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({
    // name: "自定义区域",
    polygon: {
      hierarchy: Cesium.Cartesian3.fromDegreesArray(
        geoJson.geometry.coordinates[0][0].flat()
      ),
      material: Cesium.Color.RED.withAlpha(0.3), // 半透明红色填充
      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);
  // 飞向中心点
@@ -154,14 +237,13 @@
      center.lon,
      center.lat,
      flyToHeight.value
    ), // 提高到 100000米高度
    ), // 提高到指定高度
    orientation: {
      heading: Cesium.Math.toRadians(0), // 正北方向
      pitch: Cesium.Math.toRadians(-90), // 向下倾斜90度(垂直俯视)
      roll: 0.0,
    },
  });
}
EventBus.on("close-selectArea", () => {
@@ -395,10 +477,12 @@
    });
  });
}
const validPaths = ["/", "/yhgl"];
watch(
  () => route.fullPath,
  (val) => {
    if (val != "/") {
    if (!validPaths.includes(val)) {
      // clusterLayer.dataSource.show = false
      htmlEntityList.forEach((item) => {
        item.show = false;
@@ -467,9 +551,70 @@
  height: 100vh;
  position: absolute;
}
// // 修改指南针位置
// /deep/ .compass {
//     right: 128px !important;
//     top: 112px;
// }
/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);
}
</style>