Pārlūkot izejas kodu

需求变动,查看页面制作

bill 1 gadu atpakaļ
vecāks
revīzija
3e72c68ccc

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 7 - 0
src/assets/location_n.svg


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 7 - 0
src/assets/location_o.svg


+ 3 - 1
src/lib/board/4dmap.d.ts

@@ -36,6 +36,7 @@ type ShapeStyles = {
     common: (ev?: KonvaEventObject<any>) => void;
     bus?: Emitter<{
         statusChange: Partial<ShapeStylesStatus> | null;
+        shapeStatusChange: "common" | "hover" | "active" | "draging";
     }>;
     getStatus?: (status: ShapeStylesStatus, ev: KonvaEventObject<any>) => "common" | "hover" | "active" | "draging" | null;
     hover?: (ev?: KonvaEventObject<any>) => void;
@@ -469,6 +470,7 @@ type EntityEvent = {
     mounted: void;
     destroyed: void;
     statusChange: Partial<ShapeStylesStatus> | null;
+    shapeStatusChange: "common" | "hover" | "active" | "draging";
     "*": void;
 };
 type EntityType<T extends Attrib, S extends ShapeType, P extends EntityProps<T> = EntityProps<T>, K extends Entity<T, S> = Entity<T, S, any>, EK extends string = string, ER = any> = (new (props: P) => K) & {
@@ -1148,7 +1150,7 @@ type PolygonsAttrib = {
 type PolygonsStatus = {
     newModel: boolean;
     lightPolygonId?: string;
-    activePointId?: string;
+    lightPointId?: string;
     editPolygonId?: string;
     selectPoiIds: string[];
 };

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 575 - 568
src/lib/board/4dmap.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 4 - 4
src/lib/board/4dmap.umd.cjs


+ 19 - 2
src/router.ts

@@ -4,6 +4,8 @@ import { watch, watchEffect } from "vue";
 
 export const COORD_NAME = "map-coord";
 export const POYS_NAME = "map-poy";
+export const QUERY_COORD_NAME = "query-map-coord";
+export const QUERY_POYS_NAME = "query-map-poy";
 
 const history = createWebHashHistory();
 const routes: RouteRecordRaw[] = [
@@ -110,7 +112,21 @@ const routes: RouteRecordRaw[] = [
             path: "",
             name: "query-map",
             meta: { title: "文物", navClass: "map" },
-            component: () => import("@/view/map/map.vue"),
+            component: () => import("@/view/map/layout.vue"),
+            children: [
+              {
+                path: "query-coord",
+                name: QUERY_COORD_NAME,
+                meta: { title: "文物", navClass: "map" },
+                component: () => import("@/view/map/coord.vue"),
+              },
+              {
+                path: "query-polygons",
+                name: QUERY_POYS_NAME,
+                meta: { title: "文物", navClass: "map" },
+                component: () => import("@/view/map/polygons.vue"),
+              },
+            ],
           },
           {
             path: "pano/:pid",
@@ -185,9 +201,10 @@ router.beforeEach((to, _, next) => {
     }
     return;
   }
-  console.log(to.name);
   if (to.name === "map") {
     router.replace({ name: COORD_NAME, params: to.params });
+  } else if (to.name === "query-map") {
+    router.replace({ name: QUERY_COORD_NAME, params: to.params });
   }
 
   if (to.meta?.title) {

+ 20 - 26
src/view/map/coord.vue

@@ -1,16 +1,5 @@
 <template>
-  <div class="right-layout">
-    <div class="tile-select">
-      <el-select
-        v-model="tileType"
-        placeholder="选择底图"
-        style="width: 120px"
-        class="tile-type-select"
-      >
-        <el-option v-for="item in tileOptions" :key="item" :label="item" :value="item" />
-      </el-select>
-    </div>
-
+  <div class="right-layout" @click="board.polygon.status.lightPointId = null">
     <div class="right-content">
       <el-form :inline="false" v-if="!queryMode">
         <el-form-item>
@@ -24,7 +13,6 @@
         <el-tree
           style="max-width: 600px"
           :data="treeNode"
-          :props="{ disabled: 'run' }"
           node-key="id"
           ref="treeRef"
           :show-checkbox="!queryMode"
@@ -34,7 +22,10 @@
           <template #default="{ node, data }">
             <div
               class="tree-item"
-              @click="
+              :class="{
+                active: board.polygon.status.lightPointId === data.raw.id.toString(),
+              }"
+              @click.stop="
                 !data.disable &&
                   (data.type === 'scene' ? flyScene(data) : flyPos(data.raw))
               "
@@ -59,7 +50,7 @@
                 v-else
                 class="box-item"
                 effect="dark"
-                :content="node.label"
+                :content="data.raw.name || node.label"
                 placement="top"
               >
                 <div class="title-box">
@@ -69,14 +60,13 @@
                       <DeleteLocation v-else />
                     </el-icon>
                     {{ node.label }}
-                    <!-- uu -->
                   </span>
                   <span :class="{ disable: data.disable }" class="name">
                     {{ data.raw.name }}
                   </span>
                 </div>
               </el-tooltip>
-              <span class="oper">
+              <span class="oper" @click.stop>
                 <template v-if="!queryMode">
                   <template v-if="data.type === 'scene'">
                     <el-icon color="#409efc" v-if="data.raw.creationMethod !== 2">
@@ -185,7 +175,7 @@ import {
   getWholeLineLinesByPointId,
   getWholeLinePoint,
 } from "drawing-board";
-import { flyScene, gotoPointPage, tileType, mapManage, tileOptions } from "./install";
+import { flyScene, gotoPointPage, mapManage } from "./install";
 import { board } from "./install";
 
 const inputPoint = ref<ScenePoint | null>(null);
@@ -202,7 +192,7 @@ const updatePointName = async (title: string) => {
 
 const flyPos = (point: ScenePoint) => {
   mapManage.map.getView().setCenter(point.pos);
-  board.polygon.status.activePointId = point.id.toString();
+  board.polygon.status.lightPointId = point.id.toString();
 };
 
 const relicsName = ref("");
@@ -310,9 +300,16 @@ const pointClickHandler = ({ id }: { id: any }) => {
   point && gotoPointPage(point);
 };
 
+board.polygon.container.stage.on("click.checkPointSelect", (ev) => {
+  if (ev.target === board.polygon.container.stage) {
+    board.polygon.status.lightPointId = null;
+  }
+});
 board.polygon.bus.on("clickPoint", pointClickHandler);
 onBeforeUnmount(() => {
   board.polygon.bus.off("clickPoint", pointClickHandler);
+  board.polygon.container.stage.off("click.checkPointSelect");
+  board.polygon.status.lightPointId = null;
 });
 </script>
 
@@ -340,6 +337,10 @@ onBeforeUnmount(() => {
   justify-content: space-between;
   font-size: var(--font14);
 
+  &.active {
+    color: rgba(64, 158, 255, 1);
+  }
+
   .title {
     flex: 1;
     overflow: hidden;
@@ -401,11 +402,4 @@ onBeforeUnmount(() => {
   margin: 0;
   color: #999;
 }
-
-.tile-select {
-  position: absolute;
-  right: 100%;
-  top: 10px;
-  margin-right: 10px;
-}
 </style>

+ 7 - 26
src/view/map/install.ts

@@ -1,9 +1,9 @@
 import { TileType, createMap, Manage } from "./openlayer";
 import { computed, ref, watch, watchEffect } from "vue";
 import ScaleLine from "ol/control/ScaleLine";
-import { createBoard, PoPoint, changeEnv } from "drawing-board";
+import { createBoard } from "drawing-board";
 import { Scene, ScenePoint, boardData, relicsId, scenes } from "@/store/scene";
-import { router, COORD_NAME } from "@/router";
+import { router } from "@/router";
 import { addOrUpdateDrawingFetch } from "@/request/drawing";
 
 // ---------map---------
@@ -86,30 +86,11 @@ export const gotoPointPage = (point: ScenePoint) => {
 
 // -------board------
 export const board = createBoard({ map: mapManage.map });
-watch(
-  boardData,
-  (data) => {
-    data && board.setData(data);
-    console.log("set board data", data);
-  },
-  {
-    immediate: true,
-    flush: "pre",
-  }
-);
-watch(
-  () => [router.currentRoute.value.name, boardData.value],
-  ([name]) => {
-    const showOther = name !== COORD_NAME;
-    board.polygon &&
-      board.polygon.children.filter((entity) => {
-        if (!(entity instanceof PoPoint && entity.attrib.rtk)) {
-          entity.visible(showOther);
-        }
-      });
-  },
-  { immediate: true, flush: "post" }
-);
+watch(boardData, (data) => data && board.setData(data), {
+  immediate: true,
+  flush: "pre",
+});
+
 export const boardDataChange = (dataChange?: () => void) => {
   dataChange && dataChange();
   return addOrUpdateDrawingFetch({

+ 113 - 9
src/view/map/layout.vue

@@ -1,16 +1,18 @@
 <template>
   <div class="map-layout">
     <div class="custom_bar">
-      <div class="back_container">
+      <div class="back_container" v-if="!queryMode">
         <el-button :icon="Back" circle type="primary" @click="router.back()" />
       </div>
       <div class="nav_container">
         <div
           v-for="menu in menus"
-          :key="menu.router"
+          :key="menu.name"
           class="nav_item"
-          :class="{ active: router.currentRoute.value.name === menu.router }"
-          @click="router.push({ name: menu.router })"
+          :class="{
+            active: menu.router.includes(router.currentRoute.value.name.toString()),
+          }"
+          @click="router.replace({ name: menu.router[Number(queryMode)] })"
         >
           <el-icon size="20">
             <component :is="menu.icon" />
@@ -23,6 +25,42 @@
     <div class="map-oper-layout">
       <div class="map-container" :ref="setMapContainer">
         <div class="board" :ref="setBoardContainer"></div>
+        <div class="map-top-out-pano">
+          <el-button @click="showPoints = !showPoints">
+            <el-checkbox :modelValue="showPoints" label="点位" size="large" />
+          </el-button>
+          <div class="tile-select">
+            <el-select
+              v-model="tileType"
+              placeholder="选择底图"
+              style="width: 120px"
+              class="tile-type-select"
+            >
+              <el-option
+                v-for="item in tileOptions"
+                :key="item"
+                :label="item"
+                :value="item"
+              />
+            </el-select>
+          </div>
+        </div>
+        <div class="map-bottom-out-pano">
+          <div class="point-info">
+            <div>
+              <el-icon size="20" color="rgb(230, 162, 60)">
+                <locationIcon />
+              </el-icon>
+              <p>RTK点位</p>
+            </div>
+            <div>
+              <el-icon size="20" color="rgba(64, 158, 255)">
+                <locationIcon />
+              </el-icon>
+              <p>地图选点</p>
+            </div>
+          </div>
+        </div>
       </div>
 
       <div class="data-panel">
@@ -39,24 +77,33 @@ import { router } from "@/router";
 import { Back } from "@element-plus/icons-vue";
 import vectorIcon from "@/assets/vector.svg";
 import locationIcon from "@/assets/location.svg";
-import { COORD_NAME, POYS_NAME } from "@/router";
-import { mapManage, board, autoInitPos, defaultCenter } from "./install";
+import { COORD_NAME, POYS_NAME, QUERY_COORD_NAME, QUERY_POYS_NAME } from "@/router";
+import {
+  mapManage,
+  board,
+  autoInitPos,
+  tileOptions,
+  defaultCenter,
+  tileType,
+} from "./install";
 import { ref, watch } from "vue";
 import { initRelics, relics } from "@/store/relics";
+import { queryMode } from "./install";
+import { PoPoint } from "drawing-board";
+import { boardData } from "@/store/scene";
 
 const menus = [
   {
     icon: locationIcon,
     name: "坐标",
-    router: COORD_NAME,
+    router: [COORD_NAME, QUERY_COORD_NAME],
   },
   {
     icon: vectorIcon,
     name: "矢量图",
-    router: POYS_NAME,
+    router: [POYS_NAME, QUERY_POYS_NAME],
   },
 ];
-
 const setMapContainer = (dom: HTMLDivElement) => setTimeout(() => mapManage.mount(dom));
 const setBoardContainer = (dom: HTMLDivElement) =>
   setTimeout(() => board.setProps({ dom }));
@@ -79,6 +126,27 @@ watch(
   },
   { immediate: true }
 );
+
+const showPoints = ref(true);
+watch(
+  () => [router.currentRoute.value.name, boardData.value, showPoints.value] as const,
+  ([name, _, showPoints]) => {
+    if (!board.polygon) return;
+    const rtksOnly = name && ![COORD_NAME, QUERY_COORD_NAME].includes(name.toString());
+    board.polygon.children.forEach((entity) => {
+      if (entity instanceof PoPoint) {
+        if (entity.attrib.rtk) {
+          entity.visible(showPoints);
+        } else {
+          entity.visible(showPoints && rtksOnly);
+        }
+      } else {
+        entity.visible(rtksOnly);
+      }
+    });
+  },
+  { immediate: true, flush: "post" }
+);
 </script>
 
 <style lang="scss" scoped>
@@ -183,6 +251,42 @@ watch(
   position: relative;
   z-index: 3;
 }
+.map-top-out-pano {
+  display: flex;
+  position: absolute;
+  right: 10px;
+  top: 10px;
+  z-index: 3;
+  > * {
+    margin-left: 10px;
+  }
+}
+.map-bottom-out-pano {
+  position: absolute;
+  right: 10px;
+  bottom: 10px;
+  z-index: 3;
+}
+.point-info {
+  background: #ffffff;
+  border-radius: 4px 4px 4px 4px;
+  padding: 10px;
+
+  > div {
+    display: flex;
+    align-items: center;
+    &:not(:last-child) {
+      margin-bottom: 10px;
+    }
+
+    p {
+      font-size: 16px;
+      color: #606266;
+      margin: 0;
+      margin-left: 6px;
+    }
+  }
+}
 </style>
 
 <style lang="scss">

+ 0 - 605
src/view/map/map-board.vue

@@ -1,605 +0,0 @@
-<template>
-  <div class="map-layout">
-    <Teleport to=".header" v-if="isMounted">
-      <div class="custom_bar">
-        <div class="back_container">
-          <el-button :icon="Back" circle type="primary" @click="router.back()" />
-        </div>
-        <div class="nav_container">
-          <div
-            class="nav_item"
-            :class="{ active: isCurrentTab(0) }"
-            @click="handleTabs(0)"
-          >
-            <el-icon size="20">
-              <locationIcon />
-            </el-icon>
-            <span>坐标</span>
-          </div>
-          <div
-            class="nav_item"
-            :class="{ active: isCurrentTab(1) }"
-            @click="handleTabs(1)"
-          >
-            <el-icon size="20">
-              <vectorIcon />
-            </el-icon>
-            <span>矢量图</span>
-          </div>
-        </div>
-      </div>
-    </Teleport>
-
-    <div id="map" class="map-container" ref="mapContainer" @click.stop="unActiveId">
-      <div class="map-component">
-        <el-select
-          v-model="tileType"
-          placeholder="选择底图"
-          style="width: 120px"
-          class="tile-type-select"
-        >
-          <el-option
-            v-for="item in tileOptions"
-            :key="item"
-            :label="item"
-            :value="item"
-          />
-        </el-select>
-      </div>
-
-      <div class="board" ref="boardContainer"></div>
-    </div>
-    <div class="right-control">
-      <MapRight
-        :data="boardData"
-        v-if="isCurrentTab(0)"
-        @fly-point="flyScenePoint"
-        @fly-scene="flyScene"
-        :boardPolygons="board.polygon"
-        @goto-point="gotoPointPage"
-      />
-      <MapRightPoly
-        @del="handlePolysDel"
-        @edit="handlePolysEdit"
-        :data="boardData"
-        @sync="handleSyncDataToServer"
-        ref="rightPoly"
-        :boardPolygons="board.polygon"
-        v-if="boardData && isCurrentTab(1)"
-      >
-      </MapRightPoly>
-    </div>
-
-    <Teleport to="body" v-if="isMounted">
-      <!-- <el-button class="temp_btn" @click="clearPolys">后端全清</el-button> -->
-      <div
-        class="draw-global-icon"
-        v-if="isCurrentTab(1) && !board.polygon.status.editPolygonId"
-        @click="rightPoly.enterEdit()"
-      >
-        <el-icon size="36">
-          <picpenIcon />
-        </el-icon>
-      </div>
-    </Teleport>
-  </div>
-</template>
-
-<script setup lang="ts">
-import MapRight from "./map-right.vue";
-import { router, setDocTitle } from "@/router";
-import { Manage } from "./openlayer";
-import {
-  ScenePoint,
-  Scene,
-  scenePoints,
-  scenes,
-  SceneStatus,
-  boardData,
-} from "@/store/scene";
-import { initRelics, initSelfRelics, relics } from "@/store/relics";
-import { onMounted, ref, watchEffect, watch, onUnmounted, computed } from "vue";
-import {
-  createBoard,
-  getWholeLineLinesByPointId,
-  PolygonsPointAttrib,
-  PoPoint,
-} from "drawing-board";
-import MapRightPoly from "./map-right-poly.vue";
-import { Back } from "@element-plus/icons-vue";
-import vectorIcon from "@/assets/vector.svg";
-import picpenIcon from "@/assets/pic_pen.svg";
-import locationIcon from "@/assets/location.svg";
-import {
-  addOrUpdateDrawingFetch,
-  getDrawingDetailFetch,
-  DrawingParamsType,
-  DrawingDataType,
-  PolyDataType,
-} from "@/request/drawing.ts";
-// import { relicsPolyginsFetch } from "@/request";
-// import { Grid, LocationInformation } from "@element-plus/icons-vue";
-
-import { mapManageInit, flyUserCenter, tileOptions, tileType } from "./map-flow";
-
-console.log(router.currentRoute.value);
-const scenePosTransform = (scenes: Scene[]) => {
-  const points: PolygonsPointAttrib[] = [];
-
-  scenes.forEach((scene) => {
-    if (scene.calcStatus !== SceneStatus.SUCCESS) {
-      return;
-    }
-    scene.scenePos.forEach((pos) => {
-      if (!pos.pos || pos.pos.length === 0) {
-        return;
-      }
-      points.push({
-        x: pos.pos[0],
-        y: pos.pos[1],
-        title: pos.name,
-        id: pos.id.toString(),
-        rtk: true,
-      });
-    });
-  });
-  return points;
-};
-
-const relicsId = computed(() => router.currentRoute.value.params.relicsId || "");
-
-const gotoPointPage = (point: ScenePoint) => {
-  router.push({
-    name: router.currentRoute.value.name === "map" ? "pano" : "query-pano",
-    params: { pid: point.id },
-  });
-};
-
-const isMounted = ref(false);
-const currentTab = ref(0);
-const isCurrentTab = ref((index: number) => currentTab.value === index);
-const rightPoly = ref<any>();
-
-const autoInitPos = () => {
-  const scene = scenes.value.find(
-    (scene) => !scene.scenePos.every((pos) => !pos.pos || pos.pos.length === 0)
-  );
-  if (scene) {
-    flyScene(scene);
-    return true;
-  } else {
-    return false;
-  }
-};
-const flyPos = (pos: number[]) => mapManage.map.getView().setCenter(pos);
-
-const flyScene = (scene: Scene) => {
-  const totalPos = [0, 0];
-  let numCalc = 0;
-  for (let i = 0; i < scene.scenePos.length; i++) {
-    const coord = scene.scenePos[i].pos as number[];
-    if (coord && coord.length > 0) {
-      totalPos[0] += coord[0];
-      totalPos[1] += coord[1];
-      numCalc++;
-    }
-  }
-
-  totalPos[0] /= numCalc;
-  totalPos[1] /= numCalc;
-  flyPos(totalPos);
-};
-const unActiveId = () => {
-  board.polygon.status.activePointId = null;
-};
-const flyScenePoint = (point: ScenePoint) => {
-  flyPos(point.pos);
-  board.polygon.status.activePointId = point.id.toString();
-};
-
-watch(
-  () => [router.currentRoute.value.name, router.currentRoute.value.params?.relicsId],
-  ([name, rid], old) => {
-    if (["map", "query-map"].includes(name as string) && (!old || old[1] !== rid)) {
-      relics.value = undefined;
-      const fn = name === "map" ? initSelfRelics : initRelics;
-      fn(Number(rid)).finally(() => {
-        if (!relics.value) {
-          return router.replace({ name: "relics" });
-        }
-        if (mapManage && !autoInitPos()) {
-          flyUserCenter(mapManage);
-        }
-
-        board.polygon.bus.on("clickPoint", (bpoint) => {
-          if (isCurrentTab.value(0)) {
-            const point =
-              bpoint.id &&
-              scenePoints.value.find((point) => point.id.toString() === bpoint.id);
-            point && gotoPointPage(point);
-          }
-        });
-      });
-    }
-  },
-  { immediate: true }
-);
-
-watch(
-  () => {
-    const scene = scenes.value.find(
-      (scene) => !scene.scenePos.every((pos) => !pos.pos || pos.pos.length === 0)
-    );
-    return scene?.sceneCode;
-  },
-  (firstCode) => {
-    if (firstCode && mapManage) {
-      autoInitPos();
-    }
-  }
-);
-
-watchEffect(() => {
-  if (
-    ["map", "query-map"].includes(router.currentRoute.value.name as string) &&
-    relics.value
-  ) {
-    setDocTitle(relics.value.name);
-  }
-});
-
-// ----------流程--------
-const mapContainer = ref<HTMLDivElement>();
-const boardContainer = ref<HTMLDivElement>();
-let mapManage: Manage;
-
-const board = createBoard();
-watch(boardData, (data) => data && board.setData(data), {
-  immediate: true,
-  flush: "sync",
-});
-
-watch(
-  [currentTab, boardData],
-  ([tab]) => {
-    const showOther = tab !== 0;
-    board.polygon.children.filter((entity) => {
-      if (!(entity instanceof PoPoint && entity.attrib.rtk)) {
-        entity.visible(showOther);
-      }
-    });
-  },
-  { immediate: true, flush: "post" }
-);
-
-let endEdithandler;
-
-onMounted(async () => {
-  mapManage = mapManageInit(mapContainer.value!);
-  board.setProps({
-    dom: boardContainer.value!,
-    map: mapManage.map,
-  });
-  isMounted.value = true;
-});
-
-onUnmounted(() => {
-  mapManage.map.dispose();
-  board.destory();
-});
-
-const handleTabs = (index: number) => {
-  currentTab.value = index;
-};
-
-const handleSyncDataToServer = () => {
-  setTimeout(async () => {
-    console.log("handleSyncDataToServer");
-    const data = (board.getData() as any) as DrawingDataType;
-    boardData.value = data;
-    const param: DrawingParamsType = {
-      data: data,
-      relicsId: String(relicsId.value),
-    };
-    patchPolyName(data);
-
-    await addOrUpdateDrawingFetch(param);
-
-    if (endEdithandler) {
-      console.log("end edit");
-    }
-  }, 1000);
-};
-
-const patchPolyName = (data: DrawingDataType) => {
-  const poly = data.polygons;
-  poly?.forEach((item) => {
-    if (!item.name) {
-      item.name = "本体边界" + item.id;
-    }
-  });
-};
-
-const initCroodTabdata = async () => {
-  const points = scenePosTransform(scenes.value);
-  board.setData({
-    id: String(relicsId.value),
-    points: points,
-    lines: [],
-    polygons: [],
-  });
-};
-
-watch(
-  currentTab,
-  (tab, _, onCleanup) => {
-    if (tab === 1) {
-      initPolyTabData();
-      onCleanup(() => {});
-    } else {
-      // // 防止被vue组件收集,自己控制
-      // let stop: () => void;
-      // let timeout = setTimeout(() => {
-      //   stop = watch(() => scenes.value, initCroodTabdata, {
-      //     immediate: true,
-      //     deep: true,
-      //   });
-      // });
-      // onCleanup(() => {
-      //   stop && stop();
-      //   clearTimeout(timeout);
-      // });
-    }
-  },
-  { immediate: true }
-);
-
-const initPolyTabData = async () => {
-  try {
-    setTimeout(async () => {
-      const points = scenePosTransform(scenes.value);
-      const res = await getDrawingDetailFetch(String(relicsId.value));
-      // console.log("res", points, res.data);
-      if (res.data) {
-        const canDelPoint = (id: string) =>
-          getWholeLineLinesByPointId(res.data as any, id).length === 0 &&
-          !points.some(({ id: rtkId }) => id === rtkId);
-
-        // 查看是否有多余的点,有则删除,出现原因是删除了场景
-        for (let i = 0; i < res.data.points.length; i++) {
-          if (canDelPoint(res.data.points[i].id)) {
-            res.data.points.splice(i--, 1);
-          }
-        }
-
-        // 将rtk点加入
-        for (let i = 0; i < points.length; i++) {
-          const ndx = res.data.points.findIndex(({ id }) => id === points[i].id);
-          if (!~ndx) {
-            res.data.points.push(points[i]);
-          } else {
-            res.data.points[ndx] = { ...points[i] };
-          }
-        }
-        console.log(res.data.points);
-
-        boardData.value = res.data;
-        board.setData({ ...boardData.value, id: String(relicsId.value) });
-      }
-    }, 500);
-  } catch (error) {}
-};
-
-const handlePolysDel = (id: string) => {
-  try {
-    board.polygon.removePolygon(id);
-    handleSyncDataToServer();
-  } catch (error) {
-    console.error("handlePolysDel", error);
-  }
-};
-
-const handlePolysEdit = (item: PolyDataType) => {
-  console.log("handlePolysEdit", item);
-  const data = (board.getData() as any) as DrawingDataType;
-  const index = data.polygons.findIndex((i) => item.id === i.id);
-  data.polygons[index] = item;
-  handleSyncDataToServer();
-};
-
-// const clearPolys = async () => {
-//   await addOrUpdateDrawingFetch({
-//     relicsId: String(relicsId.value),
-//     data: {
-//       points: [],
-//       polygons: [],
-//       lines: [],
-//     },
-//   });
-// };
-</script>
-
-<style lang="scss">
-.tooltip {
-  pointer-events: none;
-}
-
-.map-layout {
-  display: flex;
-  flex-direction: row;
-  height: 100%;
-}
-
-.map-container {
-  margin-left: 60px;
-  flex: 1;
-  position: relative;
-}
-
-.right-control {
-  flex: none;
-  width: 320px;
-  padding: 15px;
-
-  border-left: 1px solid var(--border-color);
-}
-
-.active {
-  cursor: pointer;
-}
-
-.active-point {
-  position: absolute;
-  pointer-events: none;
-}
-
-.map-component {
-  pointer-events: none;
-  position: absolute;
-  width: 100%;
-  height: 100%;
-  left: 0;
-  top: 0;
-  z-index: 9;
-}
-
-.env {
-  width: 100%;
-  height: 100%;
-}
-
-.tile-type-select {
-  pointer-events: all;
-  position: absolute;
-  right: 10px;
-  top: 10px;
-}
-
-.scale-view {
-  --color: #fff;
-  position: absolute;
-  left: 20px;
-  bottom: 20px;
-  height: 8px;
-  color: var(--color);
-  text-align: center;
-  border: 1px solid var(--color);
-  border-top: none;
-  z-index: 1;
-  font-size: 14px;
-  display: flex;
-  align-items: end;
-
-  &.light {
-    --color: #fff;
-
-    > div {
-      text-shadow: 0 0 2px #000;
-    }
-  }
-
-  &.dark {
-    --color: #000;
-
-    > div {
-      text-shadow: 0 0 2px #fff;
-    }
-  }
-}
-
-.board {
-  position: absolute;
-  left: 0;
-  top: 0;
-  bottom: 0;
-  right: 0;
-  z-index: 1;
-}
-
-.custom_bar {
-  width: 60px;
-  position: fixed;
-  top: 0;
-  left: 0;
-  height: 100vh;
-  background-color: white;
-
-  // padding-top: 76px;
-  .back_container {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    color: #606266;
-    height: 76px;
-  }
-
-  .nav_container {
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    color: #606266;
-
-    .nav_item {
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-      justify-content: center;
-      padding: 10px 0;
-      cursor: pointer;
-      user-select: none;
-      width: 100%;
-      span {
-        line-height: 26px;
-        font-size: var(--font14);
-      }
-
-      &.active {
-        .icon {
-          color: #409eff;
-        }
-
-        color: #409eff;
-        background-color: #ecf5ff;
-        position: relative;
-
-        &::before {
-          content: "";
-          height: 100%;
-          width: 4px;
-          position: absolute;
-          top: 0;
-          left: 0;
-          background-color: #409eff;
-        }
-      }
-    }
-  }
-}
-
-.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;
-}
-
-.temp_btn {
-  top: 40px;
-  position: fixed;
-  z-index: 1000;
-  top: 10px;
-  transform: translateX(calc(-1 * calc(50% - 300px)));
-  left: calc(50% - 300px);
-}
-</style>

+ 0 - 62
src/view/map/map-flow.ts

@@ -1,62 +0,0 @@
-import { TileType, createMap, Manage } from "./openlayer";
-import { ref, watch, watchEffect } from "vue";
-import ScaleLine from "ol/control/ScaleLine";
-
-export const tileOptions: TileType[] = ["影像底图", "矢量底图"];
-export const tileType = ref<TileType>(tileOptions[0]);
-const defaultCenter = [116.412611, 39.908866];
-
-const refreshTileType = (mapManage: Manage) => {
-  mapManage.setTileType(tileType.value);
-};
-
-export const flyUserCenter = (mapManage: Manage) => {
-  mapManage.setCenter(defaultCenter);
-  navigator.geolocation.getCurrentPosition(
-    (pos) => {
-      console.log("获取中心位置成功", pos);
-      mapManage.setCenter([pos.coords.longitude, pos.coords.latitude]);
-    },
-    (e) => {
-      console.error(e);
-      console.error("获取中心位置失败");
-    },
-    {
-      enableHighAccuracy: false,
-      timeout: 50000,
-      maximumAge: 0,
-    }
-  );
-};
-
-const addScale = (mapManage: Manage) => {
-  const scaleLine = new ScaleLine({
-    className: "scale-view",
-    maxWidth: 150,
-    minWidth: 100,
-    units: "metric",
-  });
-  // 加载比例尺
-  mapManage.map.addControl(scaleLine);
-
-  watch(
-    tileType,
-    (type) => {
-      const el = (scaleLine as any).element as HTMLDivElement;
-      el.classList.add(type === "影像底图" ? "light" : "dark");
-      el.classList.remove(type === "影像底图" ? "dark" : "light");
-      console.log(el, type);
-    },
-    { flush: "post", immediate: true }
-  );
-};
-
-export const mapManageInit = (container: HTMLDivElement) => {
-  const mapManage = createMap(container!);
-  mapManage.setCenter(defaultCenter);
-
-  watchEffect(() => refreshTileType(mapManage));
-  addScale(mapManage);
-
-  return mapManage;
-};

+ 0 - 257
src/view/map/map-right-poly.vue

@@ -1,257 +0,0 @@
-<template>
-  <div class="right-layout">
-    <div class="right-content">
-      <div class="tree-layout">
-        <p class="sub-title">全部数据</p>
-        <div class="poly-list">
-          <template v-if="data.polygons.length > 0" v-for="item in data.polygons">
-            <div
-              class="poly-list-item"
-              :class="{
-                active: [boardStatus.lightPolygonId, boardStatus.editPolygonId].includes(
-                  item.id
-                ),
-              }"
-              @mouseenter="boardStatus.lightPolygonId = item.id"
-              @mouseleave="boardStatus.lightPolygonId = null"
-              @click="enterEdit(item)"
-            >
-              <div class="left">
-                <span>{{ item.name ? item.name : "本体边界" + item.id }}</span>
-              </div>
-              <div class="right" @click.stop v-if="!boardStatus.editPolygonId">
-                <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>
-    <SingleInput
-      v-if="currentItem"
-      :visible="isShowPolyEditName"
-      @update:visible="isShowPolyEditName = false"
-      :value="currentItem.name || ''"
-      :update-value="
-        (name) =>
-          emit('edit', {
-            ...currentItem,
-            name,
-          })
-      "
-      placeholder="请输入"
-      title="修改边界名称"
-    />
-  </div>
-</template>
-
-<script setup lang="ts">
-import { computed, onUnmounted, ref, watch, watchEffect } from "vue";
-import type { PolyDataType, DrawingDataType } from "@/request/drawing.ts";
-import { Delete, Download, Edit } from "@element-plus/icons-vue";
-import SingleInput from "@/components/single-input.vue";
-import { downloadPointsXLSL2 } from "@/util/pc4xlsl";
-import { scenePoints } from "@/store/scene";
-import { ElMessageBox } from "element-plus";
-import { Polygons, getWholeLinePolygonPoints } from "drawing-board";
-
-const props = defineProps<{
-  data: DrawingDataType | null;
-  boardPolygons: Polygons;
-}>();
-
-const emit = defineEmits<{
-  (e: "del", id: string): void;
-  (e: "edit", data: PolyDataType): void;
-  (e: "editPolygon", data: PolyDataType): void;
-  (e: "sync"): void;
-  // (e: "edit", id: string): void;
-}>();
-
-const boardStatus = computed(() => props.boardPolygons.status);
-const currentItem = computed(() => {
-  if (!boardStatus.value.editPolygonId || !props.data) {
-    return null;
-  } else {
-    return props.data.polygons.find(({ id }) => id === boardStatus.value.editPolygonId);
-  }
-});
-
-let cleanupEdit: () => void;
-const enterEdit = (item?: PolyDataType) => {
-  console.error("enterEdit");
-  cleanupEdit && cleanupEdit();
-  const quitEdit = props.boardPolygons.editPolygon(item?.id);
-  let needUpdate = false;
-  const stopWatch = watch(
-    () => props.boardPolygons.attrib,
-    () => (needUpdate = true),
-    { deep: true }
-  );
-  cleanupEdit = () => {
-    props.boardPolygons.bus.off("penEndHandler", cleanupEdit);
-    quitEdit();
-    stopWatch();
-    needUpdate && emit("sync");
-    cleanupEdit = null;
-  };
-  props.boardPolygons.bus.on("penEndHandler", cleanupEdit);
-};
-
-props.boardPolygons.bus.on("clickPolygon", enterEdit);
-onUnmounted(() => {
-  cleanupEdit && cleanupEdit();
-  props.boardPolygons.bus.off("clickPolygon", enterEdit);
-});
-
-const isShowPolyEditName = ref(false);
-const handleShowEditModel = (item: PolyDataType) => {
-  enterEdit(item);
-  isShowPolyEditName.value = true;
-  const stopWatch = watchEffect(() => {
-    if (!isShowPolyEditName.value) {
-      cleanupEdit();
-      stopWatch();
-    }
-  });
-};
-
-const del = async (id: string) => {
-  const ok = await ElMessageBox.confirm("确定要删除吗", {
-    type: "warning",
-  });
-  if (ok) {
-    emit("del", id);
-  }
-};
-const handleDownload = async (item: any) => {
-  const polygonPoints: any[] = getWholeLinePolygonPoints(props.data as any, 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.id,
-    desc: p.title || p.id,
-  }));
-  await downloadPointsXLSL2(
-    points,
-    dists,
-    `${item.name ? item.name : "本体边界" + item.id}`
-  );
-};
-
-defineExpose({
-  enterEdit,
-});
-</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 {
-    width: 100%;
-    display: flex;
-    flex-direction: row;
-    justify-content: space-between;
-    align-items: center;
-    margin-bottom: 10px;
-
-    &.active {
-      color: #409eff;
-    }
-
-    .icon {
-      margin-left: 8px;
-      font-size: 16px;
-      color: #409eff;
-      cursor: pointer;
-    }
-  }
-
-  .empty {
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    font-size: 13px;
-    color: gray;
-    padding-top: 40px;
-  }
-}
-</style>

+ 0 - 371
src/view/map/map-right.vue

@@ -1,371 +0,0 @@
-<template>
-  <div class="right-layout">
-    <div class="right-content">
-      <el-form :inline="false" v-if="router.currentRoute.value.name === 'map'">
-        <el-form-item>
-          <el-button type="primary" :icon="Plus" style="width: 100%" @click="addHandler">
-            添加场景
-          </el-button>
-        </el-form-item>
-      </el-form>
-      <div class="tree-layout">
-        <p class="sub-title">全部数据</p>
-        <el-tree
-          style="max-width: 600px"
-          :data="treeNode"
-          :props="{ disabled: 'run' }"
-          node-key="id"
-          ref="treeRef"
-          :show-checkbox="router.currentRoute.value.name === 'map'"
-          default-expand-all
-          :expand-on-click-node="false"
-        >
-          <template #default="{ node, data }">
-            <div
-              class="tree-item"
-              @click="!data.disable && emit((data.type === 'scene' ? 'flyScene' : 'flyPoint') as any, data.raw)"
-            >
-              <el-tooltip
-                v-if="data.type === 'scene'"
-                class="box-item"
-                effect="dark"
-                :content="data.raw.sceneName + ' ' + node.label"
-                placement="top"
-              >
-                <span :class="{ disable: data.disable }" class="title">
-                  <el-icon>
-                    <Grid />
-                  </el-icon>
-                  {{ data.raw.sceneName }}
-
-                  <span class="tree-scene-name">{{ node.label }}</span>
-                </span>
-              </el-tooltip>
-              <el-tooltip
-                v-else
-                class="box-item"
-                effect="dark"
-                :content="node.label"
-                placement="top"
-              >
-                <div class="title-box">
-                  <span :class="{ disable: data.disable }" class="title">
-                    <el-icon>
-                      <StateGpsIcon v-if="!data.disable" />
-                      <DeleteLocation v-else />
-                    </el-icon>
-                    {{ node.label }}
-                    <!-- uu -->
-                  </span>
-                  <span :class="{ disable: data.disable }" class="name">
-                    {{ data.raw.name }}
-                  </span>
-                </div>
-              </el-tooltip>
-              <span class="oper">
-                <template v-if="router.currentRoute.value.name === 'map'">
-                  <template v-if="data.type === 'scene'">
-                    <el-icon color="#409efc" v-if="data.raw.creationMethod !== 2">
-                      <Delete @click.stop="delSceneHandler([data.raw])" />
-                    </el-icon>
-                  </template>
-                  <el-icon v-else color="#409efc">
-                    <Edit @click.stop="inputPoint = data.raw" />
-                  </el-icon>
-                </template>
-                <el-icon color="#409efc" style="margin-left: 8px">
-                  <!-- root -->
-                  <template v-if="data.raw.scenePos">
-                    <FrameIcon
-                      v-if="!data.run"
-                      @click.stop="
-                        data.type === 'scene'
-                          ? gotoScene(data.raw)
-                          : emit('gotoPoint', data.raw)
-                      "
-                    />
-                  </template>
-                  <template v-else>
-                    <PanoramaIcon
-                      v-if="!data.run"
-                      @click.stop="
-                        data.type === 'scene'
-                          ? gotoScene(data.raw)
-                          : emit('gotoPoint', data.raw)
-                      "
-                    />
-                  </template>
-                </el-icon>
-              </span>
-            </div>
-          </template>
-        </el-tree>
-      </div>
-    </div>
-
-    <template v-if="router.currentRoute.value.name === 'map'">
-      <el-button
-        type="primary"
-        :icon="Download"
-        style="width: 100%"
-        @click="handlerExport(2, relics?.name)"
-      >
-        导出本体边界坐标
-      </el-button>
-      <!-- <el-button type="primary" :icon="Download" style="width: 100%; margin-top: 20px; margin-left: 0"
-        @click="exportFile(getSelectPoints(), 1, relics?.name)">
-        导出绘制矢量数据
-      </el-button> -->
-
-      <el-button
-        type="primary"
-        :icon="Download"
-        style="width: 100%; margin-top: 20px; margin-left: 0"
-        @click="exportImage(getSelectPoints(), relics?.name)"
-      >
-        下载全景图
-      </el-button>
-    </template>
-  </div>
-
-  <SingleInput
-    :visible="!!inputPoint"
-    @update:visible="inputPoint = null"
-    :value="inputPoint?.name || ''"
-    :update-value="updatePointName"
-    title="测点说明"
-    placeholder="请填写测点说明"
-  />
-</template>
-
-<script setup lang="ts">
-import {
-  Plus,
-  Delete,
-  Grid,
-  Download,
-  DeleteLocation,
-  Edit,
-} from "@element-plus/icons-vue";
-import { computed, ref, watchEffect } from "vue";
-import {
-  Scene,
-  scenes,
-  ScenePoint,
-  updateScenePointName,
-  gotoScene,
-  relicsId,
-  refreshScenes,
-} from "@/store/scene";
-import { relics } from "@/store/relics";
-import SingleInput from "@/components/single-input.vue";
-import { router } from "@/router";
-import { selectScenes } from "../quisk";
-import { addRelicsScenesFetch, delRelicsScenesFetch } from "@/request";
-import { exportFile, exportImage } from "./pc4Helper";
-import { SceneStatus } from "@/store/scene";
-import StateGpsIcon from "@/assets/state_gps.svg";
-import PanoramaIcon from "@/assets/panorama.svg";
-import FrameIcon from "@/assets/frame.svg";
-import { DrawingDataType, getDrawingDetailFetch } from "@/request/drawing";
-import { alert } from "@/helper/message";
-import { Polygons, getWholeLineLinesByPointId } from "drawing-board";
-
-const props = defineProps<{
-  data: DrawingDataType | null;
-  boardPolygons: Polygons;
-}>();
-
-const emit = defineEmits<{
-  (e: "flyScene", data: Scene): void;
-  (e: "flyPoint", data: ScenePoint): void;
-  (e: "gotoPoint", data: ScenePoint): void;
-}>();
-
-const inputPoint = ref<ScenePoint | null>(null);
-const updatePointName = async (title: string) => {
-  await updateScenePointName(inputPoint.value!, title);
-};
-
-const relicsName = ref("");
-watchEffect(() => (relicsName.value = relics.value?.name || ""));
-
-const treeRef = ref<any>();
-const treeNode = computed(() =>
-  scenes.value.map((scene) => ({
-    label: scene.sceneCode,
-    id: scene.id,
-    type: "scene",
-    run: scene.calcStatus !== SceneStatus.SUCCESS,
-    disable: scene.scenePos.every((pos) => !pos.pos || pos.pos.length === 0),
-    raw: scene,
-    children: scene.scenePos.map((pos) => ({
-      label: pos.uuid,
-      run: scene.calcStatus !== SceneStatus.SUCCESS,
-      disable: !pos.pos || pos.pos.length === 0,
-      id: pos.id,
-      type: "point",
-      raw: { ...pos, name: pos.name, cameraType: scene.cameraType },
-    })),
-  }))
-);
-
-const getSelectPoints = () =>
-  treeRef
-    .value!.getCheckedNodes(false, false)
-    .filter((option: any) => option.type === "point")
-    .map((option: any) => option.raw) as ScenePoint[];
-
-watchEffect(() => {
-  if (treeRef.value) {
-    props.boardPolygons.status.selectPoiIds = getSelectPoints().map((point) =>
-      point.id.toString()
-    );
-  }
-});
-const addHandler = async () => {
-  const sceneCodes = scenes.value.map((scene) => scene.sceneCode);
-  await selectScenes({
-    scenes: scenes.value,
-    selfScenes: scenes.value.filter((scene) => scene.creationMethod === 2),
-    submit: async (nScene) => {
-      const requests: Promise<any>[] = [];
-      const delScenes = sceneCodes
-        .filter((sceneCode) => !nScene.some((scene) => scene.sceneCode === sceneCode))
-        .map((sceneCode) => scenes.value.find((scene) => scene.sceneCode === sceneCode)!);
-
-      delScenes.length && requests.push(delRelicsScenes(delScenes));
-      const addScenes = nScene.filter(({ sceneCode }) => !sceneCodes.includes(sceneCode));
-      addScenes.length && requests.push(addSceneHandler(addScenes));
-
-      await Promise.all(requests);
-      requests.length && (await refreshScenes());
-    },
-  });
-};
-
-const delRelicsScenes = (scenes: Pick<Scene, "sceneId" | "sceneCode">[]) =>
-  delRelicsScenesFetch(
-    relicsId.value,
-    scenes.map((item) => ({ sceneCode: item.sceneCode, id: item.sceneId }))
-  );
-
-const delSceneHandler = async (scenes: Scene[]) => {
-  const res = await getDrawingDetailFetch(String(relicsId.value));
-  for (const scene of scenes) {
-    const que = scene.scenePos.some((pos) => {
-      const id = pos.id.toString();
-      console.log(getWholeLineLinesByPointId(res.data as any, id), id);
-      return getWholeLineLinesByPointId(res.data as any, id).length !== 0;
-    });
-    if (que) {
-      await alert("已存在矢量图数据,不可删除。");
-      return;
-    }
-  }
-  await delRelicsScenes(scenes);
-  await refreshScenes();
-};
-
-const addSceneHandler = async (scenes: Pick<Scene, "sceneId" | "sceneCode">[]) =>
-  await addRelicsScenesFetch(
-    relicsId.value!,
-    scenes.map((item) => ({ sceneCode: item.sceneCode, id: item.sceneId }))
-  );
-
-const handlerExport = (type: number, name: string) => {
-  console.log("type", type, name);
-  console.log("getSelectPoints", getSelectPoints());
-  exportFile(getSelectPoints(), type, name);
-};
-</script>
-
-<style lang="scss" scoped>
-:deep(.el-tree-node__content) {
-  --el-tree-node-content-height: 26px;
-  line-height: 26px;
-  user-select: none;
-  margin-bottom: 8px;
-}
-
-:deep(.el-tree-node__children .el-tree-node__content) {
-  --el-tree-node-content-height: 52px;
-
-  & > label.el-checkbox {
-    padding-top: 6px;
-    align-items: flex-start;
-  }
-}
-
-:deep(.el-tree .tree-item) {
-}
-
-.tree-item {
-  display: flex;
-  width: calc(100% - 50px);
-  align-items: flex-start;
-  justify-content: space-between;
-  font-size: var(--font14);
-
-  .title {
-    flex: 1;
-    overflow: hidden;
-    display: inline-flex;
-    align-items: center;
-    text-overflow: ellipsis; //文本溢出显示省略号
-    white-space: nowrap; //文本不会换行
-    line-height: 26px;
-  }
-
-  .title-box {
-    display: flex;
-    flex-direction: column;
-    justify-content: center;
-    width: 100%;
-    flex-wrap: nowrap;
-
-    .name {
-      padding-left: 15px;
-      color: #999;
-    }
-  }
-
-  .oper {
-    flex: none;
-    line-height: 26px;
-    vertical-align: middle;
-  }
-}
-
-.disable {
-  pointer-events: all;
-}
-
-.tree-layout {
-  p {
-    color: #303133;
-  }
-
-  .sub-title {
-    font-size: 14px;
-    font-weight: bolder;
-  }
-}
-
-.right-layout {
-  display: flex;
-  height: 100%;
-  flex-direction: column;
-
-  .right-content {
-    flex: 1;
-    overflow-y: auto;
-  }
-}
-
-.tree-layout .tree-scene-name {
-  font-size: 10px;
-  margin: 0;
-  color: #999;
-}
-</style>

+ 0 - 342
src/view/map/map.vue

@@ -1,342 +0,0 @@
-<template>
-  <div class="map-layout" @click="activeId = null">
-    <div
-      id="map"
-      class="map-container"
-      ref="container"
-      :class="{ active: !!activeId }"
-      @click.stop
-      @mousedown="activeId = null"
-      @wheel="activeId = null"
-    >
-      <div class="map-component">
-        <el-tooltip
-          class="tooltip"
-          :visible="!!activeId"
-          :content="active?.name"
-          effect="light"
-          placement="top"
-          virtual-triggering
-          :virtual-ref="triggerRef"
-        />
-        <el-select
-          v-model="tileType"
-          placeholder="选择底图"
-          style="width: 120px"
-          class="tile-type-select"
-        >
-          <el-option
-            v-for="item in tileOptions"
-            :key="item"
-            :label="item"
-            :value="item"
-          />
-        </el-select>
-      </div>
-    </div>
-    <div class="right-control">
-      <MapRight
-        :data="2 as any"
-        :board-polygons="1 as any"
-        @fly-point="flyScenePoint"
-        @fly-scene="flyScene"
-        @goto-point="gotoPoint"
-      />
-    </div>
-  </div>
-</template>
-
-<script setup lang="ts">
-import MapRight from "./map-right.vue";
-import { router, setDocTitle } from "@/router";
-import { TileType, createMap, Manage } from "./openlayer";
-import { ScenePoint, Scene, scenePoints, scenes } from "@/store/scene";
-import { initRelics, initSelfRelics, relics } from "@/store/relics";
-import { computed, onMounted, ref, watchEffect, watch, onUnmounted } from "vue";
-import ScaleLine from "ol/control/ScaleLine";
-
-const activeId = ref<ScenePoint["id"] | null>();
-const active = computed(() =>
-  scenePoints.value.find((point) => point.id === activeId.value)
-);
-
-const activePixel = ref<number[] | null>();
-const triggerRef = ref({
-  getBoundingClientRect() {
-    return DOMRect.fromRect({
-      x: activePixel.value![0],
-      y: activePixel.value![1],
-      width: 0,
-      height: 0,
-    });
-  },
-});
-
-const tileOptions: TileType[] = ["影像底图", "矢量底图"];
-const tileType = ref<TileType>(tileOptions[0]);
-
-const points = computed(() =>
-  scenePoints.value
-    .filter((point) => point.pos)
-    .map((point) => ({
-      data: point.pos,
-      id: point.id,
-      label: point.name,
-    }))
-);
-
-const gotoPoint = (point: ScenePoint) => {
-  router.push({
-    name: router.currentRoute.value.name === "map" ? "pano" : "query-pano",
-    params: { pid: point.id },
-  });
-};
-
-const flyUserCenter = () => {
-  mapManage.setCenter([116.412611, 39.908866]);
-  navigator.geolocation.getCurrentPosition(
-    (pos) => {
-      console.log("获取中心位置成功", pos);
-      mapManage.setCenter([pos.coords.longitude, pos.coords.latitude]);
-    },
-    (e) => {
-      console.error(e);
-      console.error("获取中心位置失败");
-    },
-    {
-      enableHighAccuracy: false,
-      timeout: 50000,
-      maximumAge: 0,
-    }
-  );
-};
-const center = [109.47293862712675, 30.26530938156551];
-const container = ref<HTMLDivElement>();
-let mapManage: Manage;
-onMounted(async () => {
-  mapManage = createMap(container.value!);
-  mapManage.setCenter(center);
-  mapManage.hotsBus.on("active", (id) => {
-    if (id) {
-      activeId.value = id;
-      active.value && activeScenePoint(active.value!);
-    } else {
-      activeId.value = null;
-      activePixel.value = null;
-    }
-  });
-  mapManage.hotsBus.on("click", (id) => {
-    const point = id && scenePoints.value.find((point) => point.id === id);
-    point && gotoPoint(point);
-  });
-  refreshHots();
-  refreshTileType();
-  const scaleLine = new ScaleLine({
-    className: "scale-view",
-    maxWidth: 150,
-    minWidth: 100,
-    units: "metric",
-  });
-  // 加载比例尺
-  mapManage.map.addControl(scaleLine);
-  watch(
-    tileType,
-    (type) => {
-      const el = (scaleLine as any).element as HTMLDivElement;
-      el.classList.add(type === "影像底图" ? "light" : "dark");
-      el.classList.remove(type === "影像底图" ? "dark" : "light");
-      console.log(el, type);
-    },
-    { flush: "post", immediate: true }
-  );
-});
-
-const activeScenePoint = (point: ScenePoint) => {
-  activePixel.value = mapManage.map.getPixelFromCoordinate(point.pos);
-  activeId.value = point.id;
-};
-
-const flyPos = (pos: number[]) => mapManage.map.getView().setCenter(pos);
-
-const flyScenePoint = (point: ScenePoint) => {
-  flyPos(point.pos);
-  setTimeout(() => {
-    activeScenePoint(point);
-  }, 16);
-};
-
-const flyScene = (scene: Scene) => {
-  const totalPos = [0, 0];
-  let numCalc = 0;
-  for (let i = 0; i < scene.scenePos.length; i++) {
-    const coord = scene.scenePos[i].pos as number[];
-    if (coord && coord.length > 0) {
-      totalPos[0] += coord[0];
-      totalPos[1] += coord[1];
-      numCalc++;
-    }
-  }
-
-  totalPos[0] /= numCalc;
-  totalPos[1] /= numCalc;
-  flyPos(totalPos);
-};
-
-const refreshHots = () => {
-  if (!mapManage) return;
-  mapManage.clearHots();
-  mapManage.addHots(points.value);
-};
-
-const refreshTileType = () => {
-  if (!mapManage) return;
-  mapManage.setTileType(tileType.value);
-};
-
-watch(points, refreshHots, { immediate: true });
-watch(tileType, refreshTileType, { immediate: true });
-watch(
-  () => [router.currentRoute.value.name, router.currentRoute.value.params?.relicsId],
-  ([name, rid], old) => {
-    if (["map", "query-map"].includes(name as string) && (!old || old[1] !== rid)) {
-      relics.value = undefined;
-      const fn = name === "map" ? initSelfRelics : initRelics;
-      fn(Number(rid)).finally(() => {
-        if (!relics.value) {
-          router.replace({ name: "relics" });
-        }
-        if (!autoInitPos()) {
-          flyUserCenter();
-        }
-      });
-    }
-  },
-  { immediate: true }
-);
-
-const autoInitPos = () => {
-  const scene = scenes.value.find(
-    (scene) => !scene.scenePos.every((pos) => !pos.pos || pos.pos.length === 0)
-  );
-  if (scene) {
-    flyScene(scene);
-    return true;
-  } else {
-    return false;
-  }
-};
-
-watch(
-  () => {
-    const scene = scenes.value.find(
-      (scene) => !scene.scenePos.every((pos) => !pos.pos || pos.pos.length === 0)
-    );
-    return scene?.sceneCode;
-  },
-  (firstCode) => {
-    if (firstCode) {
-      autoInitPos();
-    }
-  }
-);
-
-watchEffect(() => {
-  if (
-    ["map", "query-map"].includes(router.currentRoute.value.name as string) &&
-    relics.value
-  ) {
-    setDocTitle(relics.value.name);
-  }
-});
-
-onUnmounted(() => mapManage.map.dispose());
-</script>
-
-<style lang="scss">
-.tooltip {
-  pointer-events: none;
-}
-.map-layout {
-  display: flex;
-  flex-direction: row;
-  height: 100%;
-}
-
-.map-container {
-  flex: 1;
-  position: relative;
-}
-
-.right-control {
-  flex: none;
-  width: 320px;
-  padding: 15px;
-
-  border-left: 1px solid var(--border-color);
-}
-
-.map-component {
-  width: 100%;
-  height: 100%;
-  position: relative;
-}
-
-.active {
-  cursor: pointer;
-}
-
-.active-point {
-  position: absolute;
-  pointer-events: none;
-}
-
-.map-component {
-  pointer-events: none;
-  position: absolute;
-  width: 100%;
-  height: 100%;
-  left: 0;
-  top: 0;
-  z-index: 9;
-}
-.env {
-  width: 100%;
-  height: 100%;
-}
-
-.tile-type-select {
-  pointer-events: all;
-  position: absolute;
-  right: 10px;
-  top: 10px;
-}
-
-.scale-view {
-  --color: #fff;
-  position: absolute;
-  left: 20px;
-  bottom: 20px;
-  height: 8px;
-  color: var(--color);
-  text-align: center;
-  border: 1px solid var(--color);
-  border-top: none;
-  z-index: 1;
-  font-size: 14px;
-  display: flex;
-  align-items: end;
-  &.light {
-    --color: #fff;
-    > div {
-      text-shadow: 0 0 2px #000;
-    }
-  }
-  &.dark {
-    --color: #000;
-    > div {
-      text-shadow: 0 0 2px #fff;
-    }
-  }
-}
-</style>
-./openlayer./openlayer/manage

+ 10 - 6
src/view/map/polygons.vue

@@ -22,7 +22,11 @@
               <div class="left">
                 <span>{{ item.name ? item.name : "本体边界" + item.id }}</span>
               </div>
-              <div class="right" @click.stop v-if="!boardStatus.editPolygonId">
+              <div
+                class="right"
+                @click.stop
+                v-if="!boardStatus.editPolygonId && !queryMode"
+              >
                 <el-icon class="icon">
                   <Delete @click="del(item.id)" />
                 </el-icon>
@@ -43,10 +47,10 @@
     </div>
   </div>
 
-  <Teleport to="body">
+  <Teleport to="body" v-if="!queryMode">
     <div class="draw-global-icon" @click="cleanupEdit ? cleanupEdit() : enterEdit()">
       <el-icon size="36">
-        <successIco v-if="cleanupEdit" />
+        <Check v-if="cleanupEdit" />
         <picpenIcon v-else />
       </el-icon>
     </div>
@@ -65,15 +69,14 @@
 <script setup lang="ts">
 import { computed, onBeforeUnmount, ref, shallowRef, watch } from "vue";
 import type { PolyDataType } from "@/request/drawing.ts";
-import { Delete, Download, Edit } from "@element-plus/icons-vue";
+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 } from "./install";
+import { board, boardDataChange, mapManage, queryMode } from "./install";
 import { confirm } from "@/helper/message";
 import picpenIcon from "@/assets/pic_pen.svg";
-import successIco from "@/assets/panorama.svg";
 
 const boardStatus = board.polygon.status;
 const selectId = ref<string>();
@@ -135,6 +138,7 @@ const enterEdit = () => {
 
 onBeforeUnmount(() => {
   cleanupEdit.value && cleanupEdit.value();
+  board.polygon.status.lightPointId = null;
   board.polygon.bus.off("clickPolygon");
   board.polygon.container.stage.off("click.checkSelect");
 });