bill 1 gadu atpakaļ
vecāks
revīzija
38a52e9752
1 mainītis faili ar 317 papildinājumiem un 0 dzēšanām
  1. 317 0
      src/view/map/polygons.vue

+ 317 - 0
src/view/map/polygons.vue

@@ -0,0 +1,317 @@
+<template>
+  <div class="right-layout" @click.stop="selectChange(null)">
+    <div class="right-content">
+      <div class="tree-layout">
+        <p class="sub-title">全部数据</p>
+        <div class="poly-list">
+          <template v-if="boardData.polygons.length > 0">
+            <div
+              v-for="item in boardData.polygons"
+              class="poly-list-item"
+              :class="{
+                active: [
+                  boardStatus.lightPolygonId,
+                  boardStatus.editPolygonId,
+                  selectId,
+                ].includes(item.id),
+              }"
+              @mouseenter="!selectId && (boardStatus.lightPolygonId = item.id)"
+              @mouseleave="!selectId && (boardStatus.lightPolygonId = null)"
+              @click.stop="!currentItem && selectChange(item.id)"
+            >
+              <el-tooltip
+                class="box-item"
+                effect="dark"
+                :content="item.name ? item.name : '本体边界'"
+                placement="top"
+              >
+                <div class="left">
+                  <span>{{ item.name ? item.name : "本体边界" }}</span>
+                </div>
+              </el-tooltip>
+              <div
+                class="right"
+                @click.stop
+                v-if="!boardStatus.editPolygonId && !queryMode"
+              >
+                <el-icon class="icon">
+                  <Delete @click="del(item.id)" />
+                </el-icon>
+                <el-icon class="icon">
+                  <Edit @click="handleShowEditModel(item)" />
+                </el-icon>
+                <el-icon class="icon">
+                  <Download @click="handleDownload(item)" />
+                </el-icon>
+              </div>
+            </div>
+          </template>
+          <template v-else>
+            <div class="empty">暂没数据</div>
+          </template>
+        </div>
+      </div>
+    </div>
+  </div>
+
+  <Teleport to="body" v-if="!queryMode">
+    <div class="draw-global-icon" @click="cleanupEdit ? cleanupEdit() : enterEdit()">
+      <el-icon size="36">
+        <Check v-if="cleanupEdit" />
+        <picpenIcon v-else-if="!selectId" />
+        <piceditIcon v-else></piceditIcon>
+      </el-icon>
+    </div>
+    <SingleInput
+      v-if="selectItem"
+      :visible="isShowPolyEditName"
+      @update:visible="isShowPolyEditName = false"
+      :value="selectItem.name || ''"
+      :update-value="(name) => boardDataChange(() => (selectItem.name = name))"
+      placeholder="请输入"
+      title="矢量图名称"
+      name="矢量图"
+    />
+  </Teleport>
+</template>
+
+<script setup lang="ts">
+import { computed, onBeforeUnmount, ref, shallowRef, watch } from "vue";
+import type { PolyDataType } from "@/request/drawing.ts";
+import { Delete, Download, Edit, Check } from "@element-plus/icons-vue";
+import SingleInput from "@/components/single-input.vue";
+import { downloadPointsXLSL1 } from "@/util/pc4xlsl";
+import { boardData, scenePoints } from "@/store/scene";
+import { getWholeLinePolygonPoints } from "drawing-board";
+import { board, boardDataChange, mapManage, queryMode } from "./install";
+import { confirm } from "@/helper/message";
+import picpenIcon from "@/assets/pic_pen.svg";
+import piceditIcon from "@/assets/pic_edit.svg";
+import { ElMessage } from "element-plus";
+
+const boardStatus = board.polygon.status;
+const selectId = ref<string>();
+
+const selectChange = (id: string) => {
+  if (currentItem.value) return;
+  if (selectId.value === id) {
+    boardStatus.lightPolygonId = null;
+    selectId.value = null;
+  } else {
+    selectId.value = id;
+    if (!selectItem.value) {
+      selectChange(null);
+    } else {
+      boardStatus.lightPolygonId = selectItem.value.id;
+      const points = getWholeLinePolygonPoints(boardData.value, selectItem.value.id);
+      if (points.length) {
+        const total = points.reduce((t, p) => [t[0] + p.x, t[1] + p.y], [0, 0]);
+        const view = mapManage.map.getView();
+        // view.setZoom(20);
+        setTimeout(() => {
+          view.setCenter([total[0] / points.length, total[1] / points.length]);
+        }, 100);
+      }
+    }
+  }
+};
+
+board.polygon.bus.on("activePolygonId", selectChange);
+
+const selectItem = computed(() =>
+  boardData.value.polygons.find(({ id }) => id === selectId.value)
+);
+const currentItem = computed(() =>
+  boardData.value.polygons.find(({ id }) => id === boardStatus.editPolygonId)
+);
+
+const cleanupEdit = shallowRef<() => void>();
+const enterEdit = () => {
+  cleanupEdit.value && cleanupEdit.value();
+  const quitEdit = board.polygon.editPolygon(selectId.value);
+  const id = board.polygon.status.editPolygonId;
+  let needUpdate = false;
+  const stopWatch = watch(
+    () => currentItem.value,
+    () => (needUpdate = true),
+    { deep: true }
+  );
+  cleanupEdit.value = () => {
+    board.polygon.bus.off("penEndHandler", cleanupEdit.value);
+    quitEdit();
+    selectChange(null);
+    stopWatch();
+    const points = getWholeLinePolygonPoints(board.polygon.attrib, id);
+    if (points.length <= 2) {
+      board.polygon.removePolygon(id);
+      ElMessage.error("请至少绘制3个点");
+    }
+    needUpdate && boardDataChange();
+    cleanupEdit.value = null;
+  };
+  board.polygon.bus.on("penEndHandler", cleanupEdit.value);
+};
+
+onBeforeUnmount(() => {
+  cleanupEdit.value && cleanupEdit.value();
+  board.polygon.status.lightPointId = null;
+});
+
+const isShowPolyEditName = ref(false);
+const handleShowEditModel = (item: PolyDataType) => {
+  selectChange(item.id);
+  isShowPolyEditName.value = true;
+};
+
+const del = async (id: string) => {
+  if ((await confirm("确定要删除吗")) && !currentItem.value) {
+    if (selectId.value === id) {
+      selectChange(null);
+    }
+    boardDataChange(() => board.polygon.removePolygon(id));
+  }
+};
+
+const handleDownload = async (item: any) => {
+  const polygonPoints: any[] = getWholeLinePolygonPoints(boardData.value, item.id);
+
+  const points = polygonPoints.map((p) => {
+    const pos = [p.x, p.y, 0];
+    if (p.rtk) {
+      const sPoint = scenePoints.value.find(({ id }) => id.toString() === p.title);
+      if (sPoint) {
+        pos[2] = sPoint.pos[2];
+      }
+    }
+    return pos;
+  });
+  const dists = polygonPoints.map((p) => ({
+    title: p.title || p.id,
+    desc: p.title || p.id,
+  }));
+  await downloadPointsXLSL1(points, dists, `${item.name || "本体边界"}-绘制矢量数据`);
+};
+</script>
+
+<style lang="scss" scoped>
+.tree-item {
+  display: flex;
+  width: calc(100% - 50px);
+  align-items: center;
+  justify-content: space-between;
+
+  .title {
+    flex: 1;
+    overflow: hidden;
+    text-overflow: ellipsis; //文本溢出显示省略号
+    white-space: nowrap; //文本不会换行
+  }
+
+  .oper {
+    flex: none;
+  }
+}
+
+.disable {
+  pointer-events: all;
+}
+
+.tree-layout {
+  p {
+    color: #303133;
+    font-size: 14px;
+  }
+
+  .sub-title {
+    font-size: 14px;
+    font-weight: bolder;
+    margin-bottom: 30px;
+  }
+}
+
+.right-layout {
+  display: flex;
+  height: 100%;
+  flex-direction: column;
+  font-size: 16px;
+
+  .right-content {
+    flex: 1;
+    overflow-y: auto;
+  }
+}
+
+.tree-layout .tree-scene-name {
+  font-size: 10px;
+  margin: 0;
+  color: #999;
+}
+
+.poly-list {
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  font-size: 14px;
+  user-select: none;
+
+  .poly-list-item {
+    cursor: pointer;
+    width: 100%;
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 10px;
+
+    &.active {
+      color: #409eff;
+    }
+
+    .left {
+      flex: 0 0 220px;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      white-space: nowrap;
+    }
+
+    .icon {
+      margin-left: 8px;
+      font-size: 16px;
+      color: #409eff;
+      cursor: pointer;
+    }
+
+    .right {
+      flex: none;
+      width: 80px;
+    }
+  }
+
+  .empty {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 13px;
+    color: gray;
+    padding-top: 40px;
+  }
+}
+
+.draw-global-icon {
+  width: 64px;
+  height: 64px;
+  background: #ffffff;
+  border-radius: 50%;
+  position: fixed;
+  z-index: 1000;
+  transform: translateX(calc(-1 * calc(50% - 300px)));
+  left: calc(50% - 300px);
+  top: 90%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+  color: #409eff;
+}
+</style>