基于北京SDK的方案预演功能
suerprisePlus
2024-06-13 28de79b44655118b1deffb5c9a8b06ec2904905b
src/components/map/layerManager.vue
@@ -1,351 +1,415 @@
<template>
  <div v-drag
       class="layerBox">
    <div class="layerTitle">
      <div class="tileLeft">
        <div @click="setCloseLayer"
             class="titleImg">
          <ArrowLeft />
        </div>
        <div class="titleLable">图层管理</div>
      </div>
      <div class="titleImg set"
           @click="store.state.layerFlag = null"
           title="关闭">
        <CloseBold />
      </div>
    </div>
    <div class="layerContent">
      <el-tree node-key="id"
               :props="props"
               :highlight-current="false"
               :data="treeData"
               show-checkbox
               :expand-on-click-node="false"
               @check-change="handleCheckChange"
               ref="treeRef">
        <template #default="{ node, data }">
          <span class="custom-tree-node">
            <span class="label">{{ node.label }}</span>
            <span class="button"
                  v-if="data.sourceType == 'demoAnimation'">
              <el-dropdown trigger="click">
                <span class="el-dropdown-link">
                  <el-icon style="color: wheat"
                           class="el-icon--right">
                    <MoreFilled />
                  </el-icon>
                </span>
                <template #dropdown>
                  <el-dropdown-menu>
                    <el-dropdown-item @click="playNode(data)">播放</el-dropdown-item>
                  </el-dropdown-menu>
                </template>
              </el-dropdown>
            </span>
          </span>
        </template>
      </el-tree>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { ref, onMounted, nextTick, watch } from "vue";
import { ElTree } from "element-plus";
interface Tree {
  id: number;
  label: string;
  children?: Tree[];
}
const treeRef = ref<InstanceType<typeof ElTree>>();
import { MoreFilled, Setting, CloseBold } from "@element-plus/icons-vue";
import palyTools from "@/assets/js/tool/palyTools";
import configTool from "@/assets/js/tool/configTool";
import layerManager from "@/assets/js/map/layerManage";
import axios from "axios";
import store from "@/store";
const treeData = ref([]);
const props = {
  label: "name",
  children: "children",
};
const handleCheckChange = (data, check, indeterminate) => {
  if (data.children) return;
  if (data._children) {
    for (var i in data._children) {
      var layer = data._children[i];
      if (check) {
        layerManager.setAddLayer(layer);
      } else {
        layerManager.setRemoveLayer(layer);
      }
    }
  } else {
    if (check) {
      layerManager.setAddLayer(data);
    } else {
      layerManager.setRemoveLayer(data);
    }
  }
};
const playNode = (res) => {
  palyTools.Init(res);
};
const setTreeDataStart = (res) => {
  treeData.value = res.children;
  var obj = configTool.getTreeDataCheck(res.children, []);
  nextTick(() => {
    treeRef.value!.setCheckedKeys(obj, false);
    setLayerStart();
  });
};
const setLayerStart = () => {
  var obj = treeRef.value!.getCheckedNodes(false, false);
  setAddLayer(obj);
};
const setAddLayer = (res) => {
  for (var i in res) {
    if (res[i]._children) {
      setAddLayer(res[i]._children);
    } else {
      layerManager.setAddLayer(res[i]);
    }
  }
};
const setTreeStart = () => {
  var url = config.jsonUrl + "SmartEarth.json";
  axios.get(url).then((res) => {
    setTreeDataStart(res.data);
  });
};
const setAnimation = (res) => {
  var info = res.info;
  for (var i in info) {
    var obj = treeRef.value!.getNode(info[i]);
    if (res.show) {
      layerManager.setAddLayer(obj.data);
    } else {
      layerManager.setRemoveLayer(obj.data);
    }
  }
  var valCheck = treeRef.value!.getCheckedKeys();
  for (var i in info) {
    if (res.show) {
      valCheck.push(info[i]);
    } else {
      if (valCheck.indexOf(info[i]) > -1) {
        valCheck.splice(valCheck.indexOf(info[i]), 1);
      }
    }
  }
  nextTick(() => {
    treeRef.value!.setCheckedKeys(valCheck, false);
    store.state.setAnimation = false;
  });
};
onMounted(() => {
  setTreeStart();
});
watch(
  () => store.state.setAnimation,
  (newVal, oldVal) => {
    if (newVal) {
      setAnimation(newVal);
    }
  },
  { immediate: true, deep: true }
);
</script>
<style lang="less" scoped>
.layerBox {
  width: 300px;
  height: 600px;
  background: rgba(7, 8, 14, 0.8);
  box-shadow: inset 0px 10px 40px 10px rgba(38, 47, 71, 1);
  position: absolute;
  z-index: 41;
  top: 150px;
  right: 1%;
  .layerTitle {
    width: calc(100% - 27px);
    height: 42px;
    background: #30bcff;
    box-shadow: 0 2px 3px rgba(16, 133, 80, 0.5);
    border-bottom: 1px solid #20bc74;
    display: flex;
    justify-content: space-between;
    padding-left: 7px;
    padding-right: 20px;
    color: white;
    .tileLeft {
      height: 100%;
      display: flex;
      align-items: center;
      .titleLable {
        font-size: 18px;
        font-family: Source Han Sans CN;
        font-weight: 400;
        color: #ffffff;
      }
    }
    .titleImg {
      width: 20px;
      height: 100%;
      display: flex;
      align-items: center;
      color: #fff;
    }
    .set {
      cursor: pointer;
    }
  }
  .layerContent {
    height: 525px;
    padding: 0 8px;
    overflow: auto;
    overflow-y: auto;
  }
  .layerContent::-webkit-scrollbar {
    width: 8px;
  }
  .layerContent::-webkit-scrollbar-thumb {
    border-radius: 10px;
    background: rgba(35, 47, 42, 0.8);
  }
  .layerContent::-webkit-scrollbar-track {
    border-radius: 0;
    background: rgba(35, 47, 42, 0.8);
  }
  .el-tree {
    width: 100%;
    overflow-y: auto;
  }
  .layerContent .el-tree-node__content {
    overflow: hidden;
  }
  .layerContent .custom-tree-node {
    overflow: hidden;
    flex-shrink: 1;
    flex-grow: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 16px;
    padding-right: 8px;
  }
  .layerContent .custom-tree-node .label {
    flex-shrink: 1;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .layerContent .custom-tree-node .button {
    flex-grow: 0;
    flex-shrink: 0;
  }
}
.dropdown_box {
  position: relative;
}
/deep/.el-select-dropdown__item {
  font-size: 12px !important;
}
.el-tree {
  background: transparent;
}
/deep/ .el-tree-node {
  background: #0d131d;
  color: #ffffff;
  font-size: 20px;
  font-weight: 300;
  margin-top: 3px;
  padding: 8px;
}
/deep/ .el-tree-node:focus > .el-tree-node__content {
  background: transparent;
}
/deep/ .el-tree-node__content:hover {
  background: #0d131d;
}
/deep/ .el-tree-node__children {
  background: #1e2a3d;
  .el-tree-node {
    background: #1e2a3d;
    margin-top: 0;
    padding: 4px;
  }
}
/deep/
  .el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content {
  background: rgba(104, 156, 255, 0.5) !important;
}
.highlight {
  background: rgba(104, 156, 255, 0.5) !important;
}
// .custom-tree-node {
//   flex: 1;
//   display: flex;
//   align-items: center;
//   justify-content: space-between;
//   font-size: 16px;
//   padding-right: 8px;
// }
.el-dropdown-menu {
  background: rgba(7, 8, 14, 0.8);
  box-shadow: inset 0px 10px 40px 10px rgba(38, 47, 71, 1);
  color: #fff;
  border: 0;
  /deep/ .el-dropdown-menu__item {
    color: #fff;
  }
}
/deep/ .el-dropdown-menu__item:not(.is-disabled):focus {
  background-color: rgba(104, 156, 255, 0.5);
  color: #fff;
}
</style>
<style>
.el-popper.is-light {
  border: 1px solid rgba(7, 8, 14, 0.8) !important;
}
.el-scrollbar {
  border: 0 !important;
}
</style>
<template>
  <div v-drag class="layerBox">
    <div class="layerTitle">
      <div class="tileLeft">
        <div @click="setCloseLayer" class="titleImg">
          <ArrowLeft />
        </div>
        <div class="titleLable">图层管理</div>
      </div>
      <div class="set">
        <div
          @click="setAddManagerFile()"
          class="titleImg"
          style="margin-right: 10px"
          title="导入"
        >
          <el-icon :size="20">
            <FolderOpened />
          </el-icon>
        </div>
        <div
          @click="setoutManagerFile()"
          class="titleImg"
          style="margin-right: 10px"
          title="导出"
        >
          <el-icon :size="20">
            <Download />
          </el-icon>
        </div>
        <div
          @click="setAddManagerLayer"
          class="titleImg"
          style="margin-right: 10px"
          title="添加"
        >
          <el-icon :size="20">
            <Plus />
          </el-icon>
        </div>
        <div
          class="titleImg"
          @click="store.state.layerFlag = null"
          title="关闭"
        >
          <el-icon :size="20">
            <Close />
          </el-icon>
        </div>
      </div>
    </div>
    <div class="layerContent">
      <el-tree
        node-key="id"
        :props="props"
        :highlight-current="false"
        :data="treeData"
        show-checkbox
        :expand-on-click-node="false"
        @check-change="handleCheckChange"
        ref="treeRef"
        class="stafftree"
      >
      </el-tree>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { ref, onMounted, nextTick, watch } from "vue";
import { ElTree } from "element-plus";
interface Tree {
  id: number;
  label: string;
  children?: Tree[];
}
const treeRef = ref<InstanceType<typeof ElTree>>();
import {
  MoreFilled,
  Setting,
  Close,
  Plus,
  defineProps,
  FolderOpened,
  Download
} from "@element-plus/icons-vue";
import palyTools from "@/assets/js/tool/palyTools";
import configTool from "@/assets/js/tool/configTool";
import layerManager from "@/assets/js/map/layerManage";
import axios from "axios";
import store from "@/store";
const treeData = ref([]);
const props = {
  label: "name",
  children: "children"
};
const setAddManagerLayer = () => {
  store.state.setAddEntityList = {
    flag: true,
    title: "图层添加",
    type: 1
  };
};
const setAddManagerFile = () => {
  store.state.setAddEntityList = {
    flag: true,
    title: "图层导入",
    type: 3
  };
};
const setoutManagerFile = () => {
  configTool.saveToJson(treeData.value, "图层导出");
};
const handleCheckChange = (data, check, indeterminate) => {
  if (data.children) return;
  if (data._children) {
    for (var i in data._children) {
      var layer = data._children[i];
      if (check) {
        layerManager.setAddLayer(layer);
      } else {
        layerManager.setRemoveLayer(layer);
      }
    }
  } else {
    if (check) {
      layerManager.setAddLayer(data);
    } else {
      layerManager.setRemoveLayer(data);
    }
  }
};
const playNode = (res) => {
  palyTools.Init(res);
};
const setTreeDataStart = (res) => {
  treeData.value = res.children;
  var obj = configTool.getTreeDataCheck(res.children, []);
  nextTick(() => {
    treeRef.value!.setCheckedKeys(obj, false);
    setLayerStart();
  });
};
const setLayerStart = () => {
  var obj = treeRef.value!.getCheckedNodes(false, false);
  setAddLayer(obj);
};
const setAddLayer = (res) => {
  for (var i in res) {
    if (res[i]._children) {
      setAddLayer(res[i]._children);
    } else {
      layerManager.setAddLayer(res[i]);
    }
  }
};
const setTreeStart = () => {
  var url = config.jsonUrl + "SmartEarth.json";
  axios.get(url).then((res) => {
    setTreeDataStart(res.data);
  });
};
const setAnimation = (res) => {
  var info = res.info;
  for (var i in info) {
    var obj = treeRef.value!.getNode(info[i]);
    if (res.show) {
      layerManager.setAddLayer(obj.data);
    } else {
      layerManager.setRemoveLayer(obj.data);
    }
  }
  var valCheck = treeRef.value!.getCheckedKeys();
  for (var i in info) {
    if (res.show) {
      valCheck.push(info[i]);
    } else {
      if (valCheck.indexOf(info[i]) > -1) {
        valCheck.splice(valCheck.indexOf(info[i]), 1);
      }
    }
  }
  nextTick(() => {
    treeRef.value!.setCheckedKeys(valCheck, false);
    store.state.setAnimation = false;
  });
};
const addGeometry = (val) => {
  if (val.flag) {
    for (var i in val.value) {
      treeData.value.push(val.value[i]);
    }
  } else {
    val.id = configTool.getEndDateTime();
    if (val.sourceType === "3DTiles") {
      treeData.value[0].children.push(val);
    } else if (val.sourceType === "WMS") {
      treeData.value[1].children.push(val);
    } else if (val.sourceType === "TMS") {
      treeData.value[2].children.push(val);
    }
  }
};
onMounted(() => {
  setTreeStart();
});
defineExpose({
  addGeometry
});
watch(
  () => store.state.setAnimation,
  (newVal, oldVal) => {
    if (newVal) {
      setAnimation(newVal);
    }
  },
  { immediate: true, deep: true }
);
</script>
<style lang="less" scoped>
.layerBox {
  width: 300px;
  height: 600px;
  background: rgba(7, 8, 14, 0.8);
  box-shadow: inset 0px 10px 40px 10px rgba(38, 47, 71, 1);
  position: absolute;
  z-index: 41;
  top: 150px;
  right: 1%;
  .layerTitle {
    width: calc(100% - 27px);
    height: 42px;
    background: #30bcff;
    box-shadow: 0 2px 3px rgba(16, 133, 80, 0.5);
    border-bottom: 1px solid #20bc74;
    display: flex;
    justify-content: space-between;
    padding-left: 7px;
    padding-right: 20px;
    color: white;
    .tileLeft {
      height: 100%;
      display: flex;
      align-items: center;
      .titleLable {
        font-size: 18px;
        font-family: Source Han Sans CN;
        font-weight: 400;
        color: #ffffff;
      }
    }
    .titleImg {
      width: 20px;
      height: 100%;
      color: #fff;
      display: flex;
      align-items: center;
    }
    .set {
      cursor: pointer;
      display: flex;
    }
  }
  .layerContent {
    height: 525px;
    padding: 0 8px;
    overflow: auto;
    overflow-y: auto;
  }
  .layerContent::-webkit-scrollbar {
    width: 8px;
  }
  .layerContent::-webkit-scrollbar-thumb {
    border-radius: 10px;
    background: rgba(35, 47, 42, 0.8);
  }
  .layerContent::-webkit-scrollbar-track {
    border-radius: 0;
    background: rgba(35, 47, 42, 0.8);
  }
  .el-tree {
    width: 100%;
    overflow-y: auto;
  }
  .layerContent .el-tree-node__content {
    overflow: hidden;
  }
  .layerContent .custom-tree-node {
    overflow: hidden;
    flex-shrink: 1;
    flex-grow: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 16px;
    padding-right: 8px;
  }
  .layerContent .custom-tree-node .label {
    flex-shrink: 1;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .layerContent .custom-tree-node .button {
    flex-grow: 0;
    flex-shrink: 0;
  }
}
.dropdown_box {
  position: relative;
}
/deep/.el-select-dropdown__item {
  font-size: 12px !important;
}
.el-tree {
  background: transparent;
}
/deep/ .el-tree-node {
  background: #0d131d;
  color: #ffffff;
  font-size: 14px;
  font-weight: 300;
  margin-top: 3px;
  padding: 8px;
}
/deep/ .el-tree-node:focus > .el-tree-node__content {
  background: transparent;
}
/deep/ .el-tree-node__content:hover {
  background: #0d131d;
}
/deep/ .el-tree-node__children {
  background: #1e2a3d;
  .el-tree-node {
    background: #1e2a3d;
    margin-top: 0;
    padding: 4px;
    font-size: 12px;
  }
}
/deep/ .stafftree > .el-tree-node > .el-tree-node__content .el-checkbox {
  display: none;
}
/deep/
  .el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content {
  background: rgba(104, 156, 255, 0.5) !important;
}
.highlight {
  background: rgba(104, 156, 255, 0.5) !important;
}
// .custom-tree-node {
//   flex: 1;
//   display: flex;
//   align-items: center;
//   justify-content: space-between;
//   font-size: 16px;
//   padding-right: 8px;
// }
.el-dropdown-menu {
  background: rgba(7, 8, 14, 0.8);
  box-shadow: inset 0px 10px 40px 10px rgba(38, 47, 71, 1);
  color: #fff;
  border: 0;
  /deep/ .el-dropdown-menu__item {
    color: #fff;
  }
}
/deep/ .el-dropdown-menu__item:not(.is-disabled):focus {
  background-color: rgba(104, 156, 255, 0.5);
  color: #fff;
}
</style>
<style>
.el-popper.is-light {
  border: 1px solid rgba(7, 8, 14, 0.8) !important;
}
.el-scrollbar {
  border: 0 !important;
}
</style>