|
@@ -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>
|