Kaynağa Gözat

Merge branch 'master' of http://192.168.0.115:3000/bill/traffic-laser

xzw 2 yıl önce
ebeveyn
işleme
2fc8f2606c
51 değiştirilmiş dosya ile 1584 ekleme ve 1037 silme
  1. 1 1
      server/test/a0k4xu045_202305311600080410/attach/sceneStore
  2. 2 2
      src/components/base/assets/scss/_base.scss
  3. 1 1
      src/components/base/assets/scss/components/_dialog.scss
  4. 4 4
      src/components/base/assets/scss/components/_icon.scss
  5. 1 0
      src/components/base/assets/scss/editor/_menu.scss
  6. 1 1
      src/components/base/components/input/select.vue
  7. 6 6
      src/components/base/components/message/message.vue
  8. 11 5
      src/components/button-pane/index.vue
  9. 28 3
      src/components/group-button/index.vue
  10. 17 1
      src/components/photos/header.vue
  11. 545 546
      src/graphic/CanvasStyle/ImageLabels/SVGIcons.js
  12. 7 1
      src/graphic/CanvasStyle/default.js
  13. 1 1
      src/graphic/CanvasStyle/focus.js
  14. 1 1
      src/graphic/CanvasStyle/select.js
  15. 1 1
      src/graphic/Constant.js
  16. 34 16
      src/graphic/Controls/AddLine.js
  17. 4 0
      src/graphic/Controls/MoveMagnifier.js
  18. 2 2
      src/graphic/Controls/MovePoint.js
  19. 92 54
      src/graphic/Controls/UIControl.js
  20. 12 2
      src/graphic/Geometry/Geometry.js
  21. 20 20
      src/graphic/History/History.js
  22. 32 11
      src/graphic/History/HistoryUtil.js
  23. 64 34
      src/graphic/Layer.js
  24. 11 1
      src/graphic/ListenLayer.js
  25. 7 4
      src/graphic/Load.js
  26. 241 195
      src/graphic/Renderer/Draw.js
  27. 5 0
      src/graphic/Renderer/Render.js
  28. 7 7
      src/graphic/Service/CurveRoadService.js
  29. 1 0
      src/graphic/Service/HistoryService.js
  30. 122 9
      src/graphic/Service/LineService.js
  31. 4 0
      src/hook/custom/preset.ts
  32. 1 5
      src/store/sync.ts
  33. 6 4
      src/views/accidents/index.vue
  34. 25 10
      src/views/accidents/print.vue
  35. 2 1
      src/views/graphic/confirm.vue
  36. 4 5
      src/views/graphic/geos/arrow.vue
  37. 1 0
      src/views/graphic/geos/index.ts
  38. 8 3
      src/views/graphic/geos/magnifier.vue
  39. 19 14
      src/views/graphic/geos/normalLine.vue
  40. 38 20
      src/views/graphic/header.vue
  41. 3 3
      src/views/graphic/menus.ts
  42. 4 1
      src/views/photos/index.vue
  43. 6 1
      src/views/roads/index.vue
  44. 40 3
      src/views/roads/tabulation.vue
  45. 33 8
      src/views/scene/covers/basePoints.vue
  46. 32 5
      src/views/scene/covers/fixPoints.vue
  47. 27 3
      src/views/scene/covers/measures.vue
  48. 21 6
      src/views/scene/menus/actions.ts
  49. 11 4
      src/views/scene/menus/menus.ts
  50. 7 4
      src/views/scene/menus/pane.vue
  51. 11 8
      src/views/scene/photo.vue

Dosya farkı çok büyük olduğundan ihmal edildi
+ 1 - 1
server/test/a0k4xu045_202305311600080410/attach/sceneStore


+ 2 - 2
src/components/base/assets/scss/_base.scss

@@ -317,7 +317,7 @@ progress {
 .fun-ctrl {
     transition: color .3s ease;
     cursor: pointer;
-    color: rgba(255,255,255,0.7) !important;
+    color: rgba(255,255,255,1) !important;
     &:hover {
       color: rgba(255,255,255,1) !important;
     }
@@ -328,4 +328,4 @@ progress {
 
   .iconfont {
       font-weight: 400;
-  }
+  }

+ 1 - 1
src/components/base/assets/scss/components/_dialog.scss

@@ -60,7 +60,7 @@
         justify-content: center;
     }
     footer{
-        padding: 20px;
+        padding: 18px 0 24px;
         display: flex;
         align-items: center;
         justify-content: center;

+ 4 - 4
src/components/base/assets/scss/components/_icon.scss

@@ -17,7 +17,7 @@
 
 .icon {
   position: relative;
-  
+
 
   .tip {
     color: rgba(255,255,255,1);
@@ -36,14 +36,14 @@
 
   &.fore-show,
   &:hover {
-    z-index: 999;
+    //z-index: 999;
     .tip {
       opacity: 0.8;
     }
   }
 }
 
-  
+
 .tip-h-right .tip{
   right: 0;
   margin-right: 0;
@@ -72,4 +72,4 @@
 
 .tip-v-bottom .tip {
   top: 100%;
-}
+}

+ 1 - 0
src/components/base/assets/scss/editor/_menu.scss

@@ -30,6 +30,7 @@
 
         &.bottom {
             margin-top: auto;
+            margin-bottom: calc(var(--boundMargin) - 8px);
         }
     }
 }

+ 1 - 1
src/components/base/components/input/select.vue

@@ -17,7 +17,7 @@
     @click="clickShowHandler"
   >
     <template v-slot:icon>
-      <icon type="pull-down" small v-if="!$slots.icon" />
+      <icon type="unfold" small v-if="!$slots.icon"  />
       <slot name="icon" v-else />
     </template>
     <template v-slot:preIcon v-if="$slots.preIcon">

+ 6 - 6
src/components/base/components/message/message.vue

@@ -1,14 +1,14 @@
 <template>
   <teleport to="body">
     <transition name="fade">
-      <div 
-        class="ui-message" 
-        :style="{ zIndex: zIndex, marginTop: `${index.value * 60}px` }" 
+      <div
+        class="ui-message"
+        :style="{ zIndex: zIndex, marginTop: `${index.value * 60}px` }"
         :class="type" v-if="show">
 <!--        <ui-icon :type="icons[type]" class="icon" v-if="type" />-->
         <p>{{ msg }}</p>
 
-        <ui-icon ctrl type="close" v-if="!time" @click="destroy" class="message-close" />
+<!--        <ui-icon ctrl type="close" v-if="!time" @click="destroy" class="message-close" />-->
       </div>
     </transition>
   </teleport>
@@ -48,7 +48,7 @@ if (props.time) {
     () => {
       show.value = false
       setTimeout(props.destroy, 500)
-    }, 
+    },
     props.time
   )
 }
@@ -56,4 +56,4 @@ if (props.time) {
 onMounted(() => nextTick(() => show.value = true))
 </script>
 
-<script> export default { name: 'ui-message' } </script>
+<script> export default { name: 'ui-message' } </script>

+ 11 - 5
src/components/button-pane/index.vue

@@ -1,23 +1,29 @@
 <template>
-  <div class="button-pane" :style="style">
+  <div class="button-pane" :style="style" ref="pane">
     <slot />
   </div>
 </template>
 
 <script setup lang="ts">
-import {computed} from "vue";
+import {computed, onMounted, ref} from "vue";
 
 const props = withDefaults(
-  defineProps<{ dire?: 'row' | 'column', size?: number }>(),
+  defineProps<{ dire?: 'row' | 'column', size?: number, auto?: boolean }>(),
   { dire: 'row', size: 64 }
 );
 
+const pane = ref<HTMLDivElement>()
+const height = ref<number>(1000)
+onMounted(() => height.value = props.dire === 'row' ? pane.value.offsetWidth : pane.value.offsetHeight)
+
 const style = computed(() => {
   const isRow = props.dire === 'row';
   const bound = isRow ? { height: `${props.size}px` } : { width: `${props.size}px` }
+  const psize = height.value > props.size ? "10px" : `${props.size / 2}px`
 
+  console.log(height.value)
   return {
-    padding: isRow ? `4px ${props.size / 2}px` : `${props.size / 2}px 4px`,
+    padding: isRow ? `4px ${psize}` : `${psize} 4px`,
     borderRadius: `${props.size / 2}px`,
     ...bound,
     flexDirection: props.dire
@@ -33,4 +39,4 @@ const style = computed(() => {
   display: flex;
   align-items: center;
 }
-</style>
+</style>

+ 28 - 3
src/components/group-button/index.vue

@@ -5,7 +5,7 @@
       :key="menu.key"
       class="menu"
       :style="menuStyle"
-      :class="{ active: activeKey === menu.key, dire, disabled: disabledMap[menu.key] }"
+      :class="{ active: activeKey === menu.key, dire, disabled: disabledMap[menu.key], border: menu.border }"
       @click="menu.onClick && menu.onClick(menu)"
     >
       <template v-if="$slots.default">
@@ -25,6 +25,7 @@ import {computed} from "vue";
 type Menu =  {
   key: any,
   text?: string,
+  border?: boolean
   icon?: string,
   disabled?: boolean | (() => boolean)
   onClick?: (menu: Menu) => void
@@ -61,6 +62,13 @@ const menuStyle = computed(() => {
 
 <style lang="scss" scoped>
 .menu {
+  &:first-child:last-child {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    height: 80%;
+    transform: translate(-50%, -50%);
+  }
   min-width: 56px;
   display: flex;
   flex-direction: column;
@@ -70,6 +78,20 @@ const menuStyle = computed(() => {
   transition: color .3s ease;
   color: #fff;
   border-radius: 4px;
+  align-items: center;
+  justify-content: center;
+
+  &.border {
+    position: relative;
+    &:after {
+      content: "";
+      position: absolute;
+      border-bottom: 1px solid rgba(255, 255, 255, 0.2);
+      left: 10px;
+      right: 10px;
+      bottom: 0;
+    }
+  }
 
   &.active {
     color: var(--colors-primary-base);
@@ -84,13 +106,16 @@ const menuStyle = computed(() => {
     align-items: center;
     justify-content: center;
     font-size: 20px;
-    flex: 1;
+
   }
 
   p {
+    flex: 1;
+    flex: none;
+    margin-top: 4px;
     line-height: 17px;
     font-size: 14px;
     white-space:nowrap;
   }
 }
-</style>
+</style>

+ 17 - 1
src/components/photos/header.vue

@@ -1,7 +1,13 @@
 <template>
   <div class="photos-header">
     <div>
-      <ui-icon :type="type || 'return_l'" ctrl style="margin-right: 10px" @click="() => onBack ? onBack() : back()" />
+      <ui-icon
+          class="back-icon"
+          :type="type || 'return_l'"
+          ctrl
+          style="margin-right: 10px"
+          @click="() => onBack ? onBack() : back()"
+      />
       <span>{{ title }}</span>
     </div>
     <span class="center" v-if="count">
@@ -42,5 +48,15 @@ defineProps<{ count?: number, title: string, onBack?: () => void, type?: string
   }
 }
 
+.back-icon {
+  display: inline-flex;
+  width: 32px;
+  height: 32px;
+  background: rgba(255,255,255,0.1);
+  border-radius: 24px 24px 24px 24px;
+  align-items: center;
+  justify-content: center;
+}
+
 
 </style>

Dosya farkı çok büyük olduğundan ihmal edildi
+ 545 - 546
src/graphic/CanvasStyle/ImageLabels/SVGIcons.js


+ 7 - 1
src/graphic/CanvasStyle/default.js

@@ -81,6 +81,11 @@ const Point = {
   radius: 4 * coordinate.ratio,
   lineWidth: 4 * coordinate.ratio,
 };
+const NormalPoint = {
+  ...Point,
+  fillStyle: "#fff",
+
+}
 
 const RoadPoint = {
   ...Point,
@@ -201,7 +206,7 @@ const TestPoint = {
 };
 
 const SVG = {
-  fillStyle: "rgba(0,0,0,0)",
+  fillStyle: "#3290FF",
   strokeStyle: "#3290FF",
   lineWidth: 1 * coordinate.ratio,
 };
@@ -228,6 +233,7 @@ export default {
   MeasureLine,
   FreeMeasureLine: MeasureLine,
   PositionLine: MeasureLine,
+  NormalPoint,
   Measure,
   Element,
   TestPoint,

+ 1 - 1
src/graphic/CanvasStyle/focus.js

@@ -111,7 +111,7 @@ const BaseLine = {
 };
 
 const SVG = {
-  fillStyle: "rgba(0,0,0,0)",
+  fillStyle: "#3290FF",
   strokeStyle: "#3290FF",
   lineWidth: 2 * coordinate.ratio,
 };

+ 1 - 1
src/graphic/CanvasStyle/select.js

@@ -105,7 +105,7 @@ const TestPoint = {
 };
 
 const SVG = {
-  fillStyle: "rgba(0,0,0,0)",
+  fillStyle: "#3290FF",
   strokeStyle: "#3290FF",
   lineWidth: 2 * coordinate.ratio,
 };

+ 1 - 1
src/graphic/Constant.js

@@ -38,7 +38,7 @@ const Constant = {
   defaultMidDivideWidth: 2, //隔离带的宽度
   angleLocationMode: "AngleLocationMode", //直角定位
   allLocationMode: "AllLocationMode", //综合定位
-  normalLocationMode: "NormalLocationMode", //自由测量
+  normalLocationMode: "NormalLocationMode", //垂线定位
   freeLocationMode: "FreeLocationMode", //自由测量
 };
 export default Constant;

+ 34 - 16
src/graphic/Controls/AddLine.js

@@ -1,12 +1,12 @@
-import { dataService } from '../Service/DataService';
-import { lineService } from '../Service/LineService';
-import { listenLayer } from '../ListenLayer';
-import VectorCategory from '../enum/VectorCategory';
-import Point from '../Geometry/Point.js';
-import { mathUtil } from '../Util/MathUtil';
-import Settings from '../Settings';
-import { pointService } from '../Service/PointService';
-import Constant from '../Constant';
+import { dataService } from "../Service/DataService";
+import { lineService } from "../Service/LineService";
+import { listenLayer } from "../ListenLayer";
+import VectorCategory from "../enum/VectorCategory";
+import Point from "../Geometry/Point.js";
+import { mathUtil } from "../Util/MathUtil";
+import Settings from "../Settings";
+import { pointService } from "../Service/PointService";
+import Constant from "../Constant";
 export default class AddLine {
   constructor() {
     this.newLine = null;
@@ -36,7 +36,10 @@ export default class AddLine {
 
   buildLine(position) {
     // if (Settings.selectLineCategory == VectorCategory.Line.NormalLine) {
-    if (this.newLine == null && !mathUtil.equalPoint(this.startInfo.position, position)) {
+    if (
+      this.newLine == null &&
+      !mathUtil.equalPoint(this.startInfo.position, position)
+    ) {
       this.newLine = lineService.create(this.startInfo.position, position);
       if (Settings.selectLineCategory == VectorCategory.Line.FreeMeasureLine) {
         this.testLineIds.push(this.newLine.vectorId);
@@ -53,7 +56,10 @@ export default class AddLine {
   }
 
   updateLine(position) {
-    if (this.newLine != null && !mathUtil.equalPoint(this.startInfo.position, position)) {
+    if (
+      this.newLine != null &&
+      !mathUtil.equalPoint(this.startInfo.position, position)
+    ) {
       let point = dataService.getPoint(this.newLine.endId);
       point.setPosition(position);
     }
@@ -70,7 +76,10 @@ export default class AddLine {
         this.newLine.getCategory() != VectorCategory.Line.DoubleArrowLine &&
         this.newLine.getCategory() != VectorCategory.Line.GuideLine
       ) {
-        pointService.mergePoint(this.newLine.endId, listenLayer.modifyPoint.linkedPointId);
+        pointService.mergePoint(
+          this.newLine.endId,
+          listenLayer.modifyPoint.linkedPointId
+        );
       }
       if (this.newLine.getCategory() == VectorCategory.Line.BaseLine) {
         Settings.baseLineId = this.newLine.vectorId;
@@ -79,13 +88,22 @@ export default class AddLine {
   }
 
   buildCurveLine(position) {
-    if (this.newLine == null && !mathUtil.equalPoint(this.startInfo.position, position)) {
-      this.newLine = lineService.createCurveLine(this.startInfo.position, position);
+    if (
+      this.newLine == null &&
+      !mathUtil.equalPoint(this.startInfo.position, position)
+    ) {
+      this.newLine = lineService.createCurveLine(
+        this.startInfo.position,
+        position
+      );
     }
   }
 
   updateCurveLine(position) {
-    if (this.newLine != null && !mathUtil.equalPoint(this.startInfo.position, position)) {
+    if (
+      this.newLine != null &&
+      !mathUtil.equalPoint(this.startInfo.position, position)
+    ) {
       let curvePoint = dataService.getCurvePoint(this.newLine.endId);
       curvePoint.setPosition(position);
     }
@@ -94,7 +112,7 @@ export default class AddLine {
   finishCurveLine(position) {
     if (this.newLine != null) {
       if (mathUtil.equalPoint(this.startInfo.position, position)) {
-        dataService.deleteCurveLine(this.newLine.vectorId);
+        lineService.deleteCurveLine(this.newLine.vectorId);
       }
     }
   }

+ 4 - 0
src/graphic/Controls/MoveMagnifier.js

@@ -6,8 +6,12 @@ export default class MoveMagnifier {
 
   moveFullMagnifier(position, magnifierId, index) {
     let magnifier = dataService.getMagnifier(magnifierId);
+    //移动放大镜清除图片信息
+
     if (index == 0) {
       magnifier.setPosition(position);
+      magnifier.setPhotoUrl(null)
+      magnifier.setPhotoImg(null)
     } else {
       const popPosition = coordinate.getScreenXY(position);
       magnifier.popPosition = {

+ 2 - 2
src/graphic/Controls/MovePoint.js

@@ -17,7 +17,6 @@ export default class MovePoint {
     if (point.getCategory() == VectorCategory.Point.TestPoint) {
       this.updatePositionByTestPoint(pointId);
     } else if (point.getCategory() == VectorCategory.Point.BasePoint) {
-
       this.updateBasePoint(pointId);
     } else {
       let parent = point.getParent();
@@ -77,7 +76,6 @@ export default class MovePoint {
       ) {
         pointService.mergePoint(pointId, listenLayer.modifyPoint.linkedPointId);
         Settings.selectBasePointId = null;
-
       } else {
         let point = dataService.getPoint(pointId);
         const parent = point.getParent();
@@ -232,7 +230,9 @@ export default class MovePoint {
 
   moveCurvePoint(position, curvePointId) {
     let curvePoint = dataService.getCurvePoint(curvePointId);
+    let curveLine = dataService.getCurveLine(curvePoint.getParent());
     curvePoint.setPosition(position);
+    curveLine.curves = mathUtil.getCurvesByPoints(curveLine.points);
   }
 }
 

+ 92 - 54
src/graphic/Controls/UIControl.js

@@ -1,38 +1,38 @@
-import { coordinate } from '../Coordinate.js';
-import LayerEvents from '../enum/LayerEvents.js';
-import UIEvents from '../enum/UIEvents.js';
-import RoadTemplate from '../enum/RoadTemplate.js';
-import RoadStructure from '../enum/RoadStructure.js';
-import VectorType from '../enum/VectorType.js';
-import VectorStyle from '../enum/VectorStyle.js';
-import VectorWeight from '../enum/VectorWeight.js';
-import GeoActions from '../enum/GeoActions.js';
-import VectorEvents from '../enum/VectorEvents.js';
-import SVGType from '../enum/SVGType.js';
-import { stateService } from '../Service/StateService.js';
-import { uiService } from '../Service/UIService.js';
-import { dataService } from '../Service/DataService.js';
-import { historyService } from '../Service/HistoryService.js';
-import { elementService } from '../Service/ElementService';
-import { lineService } from '../Service/LineService.js';
-import { circleService } from '../Service/CircleService.js';
-import { textService } from '../Service/TextService.js';
-import { svgService } from '../Service/SVGService.js';
-import { magnifierService } from '../Service/MagnifierService.js';
-import { mathUtil } from '../Util/MathUtil';
-import Constant from '../Constant';
+import { coordinate } from "../Coordinate.js";
+import LayerEvents from "../enum/LayerEvents.js";
+import UIEvents from "../enum/UIEvents.js";
+import RoadTemplate from "../enum/RoadTemplate.js";
+import RoadStructure from "../enum/RoadStructure.js";
+import VectorType from "../enum/VectorType.js";
+import VectorStyle from "../enum/VectorStyle.js";
+import VectorWeight from "../enum/VectorWeight.js";
+import GeoActions from "../enum/GeoActions.js";
+import VectorEvents from "../enum/VectorEvents.js";
+import SVGType from "../enum/SVGType.js";
+import { stateService } from "../Service/StateService.js";
+import { uiService } from "../Service/UIService.js";
+import { dataService } from "../Service/DataService.js";
+import { historyService } from "../Service/HistoryService.js";
+import { elementService } from "../Service/ElementService";
+import { lineService } from "../Service/LineService.js";
+import { circleService } from "../Service/CircleService.js";
+import { textService } from "../Service/TextService.js";
+import { svgService } from "../Service/SVGService.js";
+import { magnifierService } from "../Service/MagnifierService.js";
+import { mathUtil } from "../Util/MathUtil";
+import Constant from "../Constant";
 // import { roomsUtil } from "../Room/RoomsUtil.js";
-import { addRoad } from '../Controls/AddRoad';
-import { addLine } from './AddLine.js';
-import VectorCategory from '../enum/VectorCategory.js';
+import { addRoad } from "../Controls/AddRoad";
+import { addLine } from "./AddLine.js";
+import VectorCategory from "../enum/VectorCategory.js";
 // import { floorplanData } from "../VectorData.js";
-import Message from '@/components/base/components/message/message.vue';
-import { pointService } from '../Service/PointService.js';
-import Settings from '../Settings.js';
-import { addPoint } from './AddPoint.js';
-import { curveRoadPointService } from '../Service/CurveRoadPointService.js';
-import { roadService } from '../Service/RoadService.js';
-import { curveRoadService } from '../Service/CurveRoadService.js';
+import Message from "@/components/base/components/message/message.vue";
+import { pointService } from "../Service/PointService.js";
+import Settings from "../Settings.js";
+import { addPoint } from "./AddPoint.js";
+import { curveRoadPointService } from "../Service/CurveRoadPointService.js";
+import { roadService } from "../Service/RoadService.js";
+import { curveRoadService } from "../Service/CurveRoadService.js";
 
 export default class UIControl {
   constructor(layer, newsletter, graphicStateUI) {
@@ -88,15 +88,17 @@ export default class UIControl {
         }
 
         //执行新的事件
-        if (uiService.isBelongRoad(selectUI) || selectUI == 'road') {
+        if (uiService.isBelongRoad(selectUI) || selectUI == "road") {
           stateService.setEventName(LayerEvents.AddRoad);
         } else if (selectUI == UIEvents.CurveRoad) {
           stateService.setEventName(LayerEvents.AddCurveRoad);
         } else if (uiService.isBelongLine(selectUI)) {
           stateService.setEventName(LayerEvents.AddLine);
-        } else if (selectUI == UIEvents.CurveLine) {
-          stateService.setEventName(LayerEvents.AddCurveLine);
-        } else if (uiService.isBelongPoint(selectUI)) {
+        }
+        //  else if (selectUI == UIEvents.CurveLine) {
+        //   stateService.setEventName(LayerEvents.AddCurveLine);
+        // }
+        else if (uiService.isBelongPoint(selectUI)) {
           stateService.setEventName(LayerEvents.AddPoint);
         } else if (selectUI == UIEvents.Circle) {
           stateService.setEventName(LayerEvents.AddCircle);
@@ -119,7 +121,7 @@ export default class UIControl {
   }
 
   updateVectorForSelectUI(selectUI) {
-    console.log('selectUI', selectUI);
+    console.log("selectUI", selectUI);
     const focusItem = stateService.getFocusItem();
 
     // if (selectUI == VectorStyle.Bold || selectUI == VectorStyle.Thinning) {
@@ -142,9 +144,9 @@ export default class UIControl {
     if (uiService.isBelongRoadEdgeStyle(selectUI)) {
       let key = null;
       if (VectorStyle[selectUI]) {
-        key = 'setStyle';
+        key = "setStyle";
       } else if (VectorWeight[selectUI]) {
-        key = 'setWeight';
+        key = "setWeight";
       }
 
       if (focusItem.type == VectorType.Line) {
@@ -351,6 +353,14 @@ export default class UIControl {
         }
         break;
       case VectorType.CurveLine:
+        lineService.deleteCurveLine(vectorId);
+        break;
+      case VectorType.CurvePoint:
+        const curvePoint = dataService.getCurvePoint(vectorId);
+        lineService.deleteCrossPointForCurveLine(
+          vectorId,
+          curvePoint.getParent()
+        );
         break;
       case VectorType.Circle:
         dataService.deleteCircle(vectorId);
@@ -385,6 +395,7 @@ export default class UIControl {
         lineService.copy(vectorId);
         break;
       case VectorType.CurveLine:
+        lineService.copyCurveLine(vectorId);
         break;
       case VectorType.Circle:
         circleService.copy(vectorId);
@@ -430,18 +441,18 @@ export default class UIControl {
   }
 
   getCadBlob(canvas) {
-    var type = 'jpg';
+    var type = "jpg";
     return new Promise((resolve) => canvas.toBlob(resolve, `${type}/image`));
   }
 
   downloadCadImg(canvas, filename) {
     // 图片导出为 jpg 格式
-    var type = 'jpg';
+    var type = "jpg";
     var imgData = canvas.toDataURL(type, 3);
     canvas.toBlob(`${type}/image`);
 
     // 加工image data,替换mime type
-    imgData = imgData.replace(this._fixType(type), 'image/octet-stream');
+    imgData = imgData.replace(this._fixType(type), "image/octet-stream");
     // 下载后的图片名
     //var filename = 'cad_' + new Date().getTime() + '.' + type
     // download
@@ -449,19 +460,38 @@ export default class UIControl {
   }
 
   saveFile(data, filename) {
-    var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
+    var save_link = document.createElementNS(
+      "http://www.w3.org/1999/xhtml",
+      "a"
+    );
     save_link.href = data;
     save_link.download = filename;
 
-    var event = document.createEvent('MouseEvents');
-    event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+    var event = document.createEvent("MouseEvents");
+    event.initMouseEvent(
+      "click",
+      true,
+      false,
+      window,
+      0,
+      0,
+      0,
+      0,
+      0,
+      false,
+      false,
+      false,
+      false,
+      0,
+      null
+    );
     save_link.dispatchEvent(event);
   }
 
   _fixType(type) {
-    type = type.toLowerCase().replace(/jpg/i, 'jpeg');
+    type = type.toLowerCase().replace(/jpg/i, "jpeg");
     var r = type.match(/png|jpeg|bmp|gif/)[0];
-    return 'image/' + r;
+    return "image/" + r;
   }
   /****************************************************************************针对菜单*******************************************************************************/
 
@@ -505,7 +535,7 @@ export default class UIControl {
     this.layer.renderer.autoRedraw();
   }
 
-  menu_clear() {
+  menu_clear(isBack) {
     dataService.clear();
     Settings.selectLocationMode = null;
     Settings.baseLineId = null;
@@ -513,14 +543,22 @@ export default class UIControl {
     elementService.hideAll();
     this.layer.exit();
     this.layer.initLocation();
-    this.layer.history.save();
+    if(!isBack){
+      this.layer.history.save();
+    }else{
+      historyService.clearHistoryRecord()
+      this.layer.uiControl.graphicStateUI.canRevoke = false;
+      this.layer.uiControl.graphicStateUI.canRecovery = false;
+    }
     this.layer.renderer.autoRedraw();
   }
 
   /******************************************************************************************************************************************************************/
 
   prompt(msg) {
-    this._prompts.push(Message.success(typeof msg === 'string' ? { msg } : msg));
+    this._prompts.push(
+      Message.success(typeof msg === "string" ? { msg } : msg)
+    );
   }
 
   // 进入持续添加出确认与取消框
@@ -528,7 +566,7 @@ export default class UIControl {
     this.graphicStateUI.continuedMode = true;
   }
   confirmEntry() {
-    console.log('确认');
+    console.log("确认");
     Settings.selectLocationMode = null;
     this.graphicStateUI.continuedMode = false;
     this.layer.exit();
@@ -539,7 +577,7 @@ export default class UIControl {
     this.layer.renderer.autoRedraw();
   }
   confirmCancel() {
-    console.log('取消');
+    console.log("取消");
     Settings.selectLocationMode = null;
     this.graphicStateUI.continuedMode = false;
     addPoint.deleteTestPoints();
@@ -553,7 +591,7 @@ export default class UIControl {
 
   // 设置默认设置
   setDefaultSetting(setting) {
-    console.log('获得设置', setting);
+    console.log("获得设置", setting);
 
     uiService.setRoadMidDivideWidth(
       // (setting.roadQuarantineWidth / coordinate.res) * coordinate.ratio

+ 12 - 2
src/graphic/Geometry/Geometry.js

@@ -111,6 +111,16 @@ export default class Geometry {
     this.weight = weight;
   }
 
+  getWeight() {
+    return this.weight;
+  }
+
+  setPhotoUrl(src) {
+    this.photoUrl = src;
+  }
+  setPhotoImg(type) {
+    this.photoImage = type;
+  }
   getType() {
     return this.type;
   }
@@ -127,10 +137,10 @@ export default class Geometry {
     this.locationMode = value;
   }
 
-  setLinkedBasePointId(id){
+  setLinkedBasePointId(id) {
     this.linkedBasePointId = id;
   }
-  setLinkedTestPointId(id){
+  setLinkedTestPointId(id) {
     this.linkedTestPointId = id;
   }
 

+ 20 - 20
src/graphic/History/History.js

@@ -17,6 +17,8 @@ import { crossPointService } from "../Service/CrossPointService";
 import { curveRoadPointService } from "../Service/CurveRoadPointService";
 import { curveEdgeService } from "../Service/CurveEdgeService";
 import { curveRoadService } from "../Service/CurveRoadService";
+import { curvePointService } from "../Service/CurvePointService";
+
 import Settings from "../Settings";
 
 export default class History {
@@ -46,7 +48,6 @@ export default class History {
       pre: 0,
       next: 0,
     };
-
     const currentRecordIndex = historyService.getCurrentRecordIndex();
     const records = historyService.getHistoryRecords();
 
@@ -176,9 +177,8 @@ export default class History {
           item.curvePoint,
           item.curvePoint.id
         );
-        curvePoint.setPoints(item.points);
         curvePoint.setIndex(item.index);
-        curvePoint.parent = item.curvePoint.parent;
+        curvePoint.setPointParent(item.curvePoint.parent);
       } else if (item.handle == HistoryEvents.ModifyCurvePoint) {
         const preCurvePoint = item.preCurvePoint;
         let currentCurvePoint = dataService.getCurvePoint(
@@ -199,9 +199,8 @@ export default class History {
         dataService.deleteCurveLine(item.curveLine.id);
       } else if (item.handle == HistoryEvents.DeleteCurveLine) {
         const preCurveLine = item.curveLine;
-        let newCurveLine = lineService.createCurveLine(
-          preCurveLine.start,
-          preCurveLine.end,
+        let newCurveLine = lineService.createCurveLineByPointIds(
+          preCurveLine.points,
           preCurveLine.id
         );
         historyUtil.assignCurveLineFromCurveLine(newCurveLine, preCurveLine);
@@ -545,21 +544,22 @@ export default class History {
   goNextForCurveLines(itemForCurveLines) {
     for (let i = 0; i < itemForCurveLines.length; ++i) {
       const item = itemForCurveLines[i];
-      if (item.handle == HistoryEvents.AddLine) {
-        const preLine = item.line;
-        let newLine = lineService.createByPointId(
-          preLine.start,
-          preLine.end,
-          preLine.category,
-          preLine.id
+      if (item.handle == HistoryEvents.AddCurveLine) {
+        const preCurveLine = item.curveLine;
+        let newCurveLine = lineService.createCurveLineByPointIds(
+          preCurveLine.points,
+          preCurveLine.id
+        );
+        historyUtil.assignCurveLineFromCurveLine(newCurveLine, preCurveLine);
+      } else if (item.handle == HistoryEvents.DeleteCurveLine) {
+        dataService.deleteCurveLine(item.curveLine.id);
+      } else if (item.handle == HistoryEvents.ModifyCurveLine) {
+        const currentCurveLine = item.curCurveLine;
+        let preCurveLine = dataService.getCurveLine(item.preCurveLine.id);
+        historyUtil.assignCurveLineFromCurveLine(
+          preCurveLine,
+          currentCurveLine
         );
-        historyUtil.assignLineFromLine(newLine, preLine);
-      } else if (item.handle == HistoryEvents.DeleteLine) {
-        dataService.deleteLine(item.line.id);
-      } else if (item.handle == HistoryEvents.ModifyLine) {
-        const currentLine = item.curLine;
-        let preLine = dataService.getLine(item.preLine.id);
-        historyUtil.assignLineFromLine(preLine, currentLine);
       }
     }
   }

+ 32 - 11
src/graphic/History/HistoryUtil.js

@@ -173,6 +173,22 @@ export default class HistoryUtil {
           road1.leftDrivewayCount == road2.leftDrivewayCount &&
           road1.rightDrivewayCount == road2.rightDrivewayCount &&
           road1.midDivide.midDivideWidth == road2.midDivide.midDivideWidth &&
+          mathUtil.clonePoint(
+            road1.midDivide.leftMidDivide.start,
+            road2.midDivide.leftMidDivide.start
+          ) &&
+          mathUtil.clonePoint(
+            road1.midDivide.leftMidDivide.end,
+            road2.midDivide.leftMidDivide.end
+          ) &&
+          mathUtil.clonePoint(
+            road1.midDivide.rightMidDivide.start,
+            road2.midDivide.rightMidDivide.start
+          ) &&
+          mathUtil.clonePoint(
+            road1.midDivide.rightMidDivide.end,
+            road2.midDivide.rightMidDivide.end
+          ) &&
           road1.leftLanes.length == road2.leftLanes.length &&
           road1.rightLanes.length == road2.rightLanes.length
         ) {
@@ -346,8 +362,8 @@ export default class HistoryUtil {
   assignCurveLineFromCurveLine(curveLine1, curveLine2) {
     const curveLineInfo = {};
     curveLineInfo.vectorId = curveLine1.vectorId;
-    curveLineInfo.start = curveLine2.start;
-    curveLineInfo.end = curveLine2.end;
+    curveLineInfo.startId = curveLine2.startId;
+    curveLineInfo.endId = curveLine2.endId;
     curveLineInfo.points = JSON.parse(JSON.stringify(curveLine2.points));
     curveLineInfo.curves = JSON.parse(JSON.stringify(curveLine2.curves));
     this.setCurveLineInfo(curveLineInfo);
@@ -587,9 +603,10 @@ export default class HistoryUtil {
   getDataForCurveLine(curveLine) {
     const data = {};
     data.id = curveLine.vectorId;
-    data.start = curveLine.startId;
-    data.end = curveLine.endId;
+    data.startId = curveLine.startId;
+    data.endId = curveLine.endId;
     data.points = JSON.parse(JSON.stringify(curveLine.points));
+    data.curves = JSON.parse(JSON.stringify(curveLine.curves));
     data.type = curveLine.geoType;
     return data;
   }
@@ -812,7 +829,11 @@ export default class HistoryUtil {
     let curveLine = dataService.getCurveLine(curveLineInfo.vectorId);
     curveLine.startId = curveLineInfo.start;
     curveLine.endId = curveLineInfo.end;
-    curveLine.points = JSON.parse(JSON.stringify(curveLineInfo.points));
+    for (let i = 0; i < curveLineInfo.points.length; ++i) {
+      curveLine.points[i] = dataService.getCurvePoint(
+        curveLineInfo.points[i].vectorId
+      );
+    }
     curveLine.curves = JSON.parse(JSON.stringify(curveLineInfo.curves));
     return curveLine;
   }
@@ -925,12 +946,12 @@ export default class HistoryUtil {
     curveRoad.endId = curveRoadInfo.endId;
     curveRoad.leftEdgeId = curveRoadInfo.leftEdgeId;
     curveRoad.rightEdgeId = curveRoadInfo.rightEdgeId;
-    // for (let i = 0; i < curveRoadInfo.points.length; ++i) {
-    //   curveRoad.points[i] = dataService.getCurveRoadPoint(
-    //     curveRoadInfo.points[i]
-    //   );
-    // }
-    curveRoad.points = JSON.parse(JSON.stringify(curveRoadInfo.points));
+    for (let i = 0; i < curveRoadInfo.points.length; ++i) {
+      curveRoad.points[i] = dataService.getCurveRoadPoint(
+        curveRoadInfo.points[i]
+      );
+    }
+    //curveRoad.points = JSON.parse(JSON.stringify(curveRoadInfo.points));
     curveRoad.curves = JSON.parse(JSON.stringify(curveRoadInfo.curves));
 
     if (curveRoad.way == Constant.oneWay) {

+ 64 - 34
src/graphic/Layer.js

@@ -42,6 +42,7 @@ import Constant from "./Constant";
 import { uiService } from "./Service/UIService";
 import { imageService } from "./Service/ImageService";
 import VectorEvents from "./enum/VectorEvents";
+import { lineService } from "./Service/LineService";
 
 const minDragDis = 10;
 const minZoom = 20;
@@ -145,10 +146,10 @@ export default class Layer {
         stateService.setEventName(LayerEvents.AddingLine);
         addLine.setNewLinePoint(position);
         break;
-      case LayerEvents.AddCurveLine:
-        stateService.setEventName(LayerEvents.AddingCurveLine);
-        addLine.setNewLinePoint(position);
-        break;
+      // case LayerEvents.AddCurveLine:
+      //   stateService.setEventName(LayerEvents.AddingCurveLine);
+      //   addLine.setNewLinePoint(position);
+      //   break;
       case LayerEvents.AddPoint:
         stateService.setEventName(LayerEvents.MovePoint);
         const newPoint = addPoint.buildPoint(position);
@@ -161,10 +162,10 @@ export default class Layer {
           this.history.save();
           this.renderer.autoRedraw();
         } else {
-          if(Settings.basePointIds.length>1){
-            this.uiControl.prompt({ msg: '请先选择基准点', time: 1000 });
-          }else{
-            this.uiControl.prompt({ msg: '请先添加基准点', time: 1000 });
+          if (Settings.basePointIds.length > 1) {
+            this.uiControl.prompt({ msg: "请先选择基准点", time: 1000 });
+          } else {
+            this.uiControl.prompt({ msg: "请先添加基准点", time: 1000 });
           }
 
           // this.uiControl.prompt({ msg: '请先选择基准点', time: 1000 });
@@ -284,37 +285,64 @@ export default class Layer {
         break;
       case VectorEvents.AddCrossPoint:
         if (focusItem && focusItem.vectorId) {
-          const curveRoad = dataService.getCurveRoad(focusItem.vectorId);
-          let index = mathUtil.getIndexForCurvesPoints(
-            position,
-            curveRoad.points
-          );
-          if (index != -1) {
-            curveRoadService.addCPoint(curveRoad, position, index);
-          } else {
-            const dis1 = mathUtil.getDistance(curveRoad.points[0], position);
-            const dis2 = mathUtil.getDistance(
-              curveRoad.points[curveRoad.points.length - 1],
+          if (focusItem.type == VectorType.CurveRoad) {
+            const curveRoad = dataService.getCurveRoad(focusItem.vectorId);
+            let index = mathUtil.getIndexForCurvesPoints(
+              position,
+              curveRoad.points
+            );
+            if (index != -1) {
+              curveRoadService.addCPoint(curveRoad, position, index);
+            } else {
+              const dis1 = mathUtil.getDistance(curveRoad.points[0], position);
+              const dis2 = mathUtil.getDistance(
+                curveRoad.points[curveRoad.points.length - 1],
+                position
+              );
+              if (dis1 > dis2) {
+                index = curveRoad.points.length - 2;
+              } else {
+                index = 1;
+              }
+              curveRoadService.addCPoint(curveRoad, position, index);
+            }
+            curveRoadService.updateForMovePoint(
+              curveRoad.points[index + 1].vectorId,
               position
             );
-            if (dis1 > dis2) {
-              index = curveRoad.points.length - 2;
-              // curveRoadService.addCPoint(
-              //   curveRoad,
-              //   position,
-              //   curveRoad.points.length - 2
-              // );
+          } else if (focusItem.type == VectorType.Line) {
+            let line = dataService.getLine(focusItem.vectorId);
+            const weight = line.getWeight();
+            let startPoint = dataService.getPoint(line.startId);
+            let endPoint = dataService.getPoint(line.endId);
+            dataService.deleteLine(focusItem.vectorId);
+            let curveLine = lineService.createCurveLine(startPoint, endPoint);
+            mathUtil.clonePoint(curveLine.points[1], position);
+            curveLine.curves = mathUtil.getCurvesByPoints(curveLine.points);
+            curveLine.setWeight(weight);
+          } else if (focusItem.type == VectorType.CurveLine) {
+            let curveLine = dataService.getCurveLine(focusItem.vectorId);
+            let index = mathUtil.getIndexForCurvesPoints(
+              position,
+              curveLine.points
+            );
+            if (index != -1) {
+              lineService.addCPoint(position, index, focusItem.vectorId);
             } else {
-              //curveRoadService.addCPoint(curveRoad, position, 1);
-              index = 1;
+              const dis1 = mathUtil.getDistance(curveLine.points[0], position);
+              const dis2 = mathUtil.getDistance(
+                curveLine.points[curveLine.points.length - 1],
+                position
+              );
+              if (dis1 > dis2) {
+                index = curveLine.points.length - 2;
+              } else {
+                index = 1;
+              }
+              lineService.addCPoint(position, index, focusItem.vectorId);
             }
-            curveRoadService.addCPoint(curveRoad, position, index);
           }
-          //curveRoadService.setLanes(curveRoad.vectorId);
-          curveRoadService.updateForMovePoint(
-            curveRoad.points[index + 1].vectorId,
-            position
-          );
+
           stateService.clearEventName();
           this.history.save();
           this.renderer.autoRedraw();
@@ -827,7 +855,9 @@ export default class Layer {
               y: listenLayer.modifyPoint.y,
             };
           }
+
           movePoint.moveCurvePoint(position, draggingItem.vectorId);
+          let curveLine = dataService.getCurveLine(curvePoint.getParent());
           this.showElementLine(curvePoint, eventName);
           needAutoRedraw = true;
         }

+ 11 - 1
src/graphic/ListenLayer.js

@@ -13,6 +13,7 @@ import { edgeService } from "./Service/EdgeService";
 import VectorCategory from "./enum/VectorCategory";
 import LayerEvents from "./enum/LayerEvents";
 import Style from "./CanvasStyle";
+import Settings from "./Settings";
 export default class ListenLayer {
   constructor(canvas, newsletter, graphicState) {
     this.modifyPoint = null;
@@ -186,7 +187,8 @@ export default class ListenLayer {
     for (const curveLineId in curveLines) {
       if (
         exceptCurveLineIds &&
-        exceptCurveLineIds.hasOwnProperty(curveLineId)
+        (exceptCurveLineIds.hasOwnProperty(curveLineId) ||
+          exceptCurveLineIds == curveLineId)
       ) {
         continue;
       }
@@ -225,9 +227,11 @@ export default class ListenLayer {
         continue;
       }
       const point = dataService.getPoint(pointId);
+  
       if (point.getCategory() == VectorCategory.Point.TestBasePoint) {
         continue;
       }
+   
       const distance = this.getDistance(position, point);
       if (distance < Constant.minAdsorbPix) {
         if (pointInfo.pointId == null) {
@@ -262,6 +266,10 @@ export default class ListenLayer {
       const linkedPoint = dataService.getPoint(pointInfo.pointId);
       pointInfo.x = linkedPoint.x;
       pointInfo.y = linkedPoint.y;
+      //判断当时基准点则要高亮
+      if(linkedPoint.getCategory() ==VectorCategory.Point.BasePoint ){
+        Settings.selectBasePointId = linkedPoint.vectorId
+      }
     } else {
       if (seqInfo.hasOwnProperty("linkedPointIdX")) {
         pointInfo.linkedPointIdX = seqInfo.linkedPointIdX;
@@ -278,6 +286,8 @@ export default class ListenLayer {
         pointInfo.y = position.y;
       }
     }
+
+
     return pointInfo;
   }
 

+ 7 - 4
src/graphic/Load.js

@@ -14,6 +14,7 @@ import { magnifierService } from "./Service/MagnifierService.js";
 import { textService } from "./Service/TextService.js";
 import { svgService } from "./Service/SVGService.js";
 import { mathUtil } from "./Util/MathUtil.js";
+import { historyService } from "./Service/HistoryService.js";
 
 export default class Load {
   constructor(layer) {
@@ -82,7 +83,7 @@ export default class Load {
           point.setLinkedBasePointId(dataLocal.points[key].linkedBasePointId);
           point.setLinkedTestPointId(dataLocal.points[key].linkedTestPointId);
         }
-    
+
         // let points = dataService.vectorData.points;
         let points = dataLocal.points;
         Settings.basePointIds =[]
@@ -107,7 +108,7 @@ export default class Load {
           svg.setPoints(dataLocal.svgs[key].points);
         }
       }
-   
+
       if (dataLocal.lines) {
         for (let key in dataLocal.lines) {
           let line = lineService.createByPointId(
@@ -139,7 +140,7 @@ export default class Load {
         }
       }
       if(dataLocal.roadPoints){
-        
+
         for (let key in dataLocal.roadPoints) {
           let roadPoint = roadPointService.create(
             dataLocal.roadPoints[key],
@@ -280,6 +281,7 @@ export default class Load {
       this.layer.updateForLocation();
     }
     this.layer.history.init();
+
     this.layer.renderer.autoRedraw();
   }
 
@@ -301,7 +303,8 @@ export default class Load {
 
   // 退出页面清除缓存及其他操作
   clear() {
-    this.layer.uiControl.menu_clear();
+    console.error("clear")
+    this.layer.uiControl.menu_clear(true);
     console.warn("clear");
   }
 }

+ 241 - 195
src/graphic/Renderer/Draw.js

@@ -26,6 +26,7 @@ const help = {
     ];
     let currentAttr;
 
+    //console.log(itemsEntry)
     return [
       itemsEntry.reduce((prev, [item, attr]) => {
         if (!item) return prev;
@@ -101,7 +102,7 @@ const help = {
     for (const curve of coves) {
       ctx.beginPath();
       ctx.moveTo(curve.start.x, curve.start.y);
-      help.drawCove(ctx, curve)
+      help.drawCove(ctx, curve);
       ctx.stroke();
     }
   },
@@ -146,7 +147,9 @@ const help = {
   },
   getRealDistance(p1, p2) {
     return (
-      Math.round((mathUtil.getDistance(p1, p2) * coordinate.res * 100) / coordinate.ratio) / 100
+      Math.round(
+        (mathUtil.getDistance(p1, p2) * coordinate.res * 100) / coordinate.ratio
+      ) / 100
     );
   },
   getPerpendicularPoint(p1, p2, p3, d) {
@@ -206,47 +209,72 @@ const help = {
     ctx.restore();
   },
   isTriangleClockwise(p1, p2, p3) {
-    const crossProduct = (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);
+    const crossProduct =
+      (p2.x - p1.x) * (p3.y - p1.y) - (p3.x - p1.x) * (p2.y - p1.y);
     return crossProduct < 0;
   },
-  drawStyleLine(ctx, line, style = VectorStyle.SingleSolidLine, weight = VectorStyle.Thinning) {
+  drawStyleLine(
+    ctx,
+    line,
+    style = VectorStyle.SingleSolidLine,
+    weight = VectorStyle.Thinning
+  ) {
     ctx.save();
-    style = style || VectorStyle.SingleSolidLine
+    style = style || VectorStyle.SingleSolidLine;
     ctx.beginPath();
-    const lineWidth = Settings.lineWidth * (ctx.lineWidth || 1) * (weight === VectorWeight.Bold ? 2 : 1);
+    const lineWidth =
+      Settings.lineWidth *
+      (ctx.lineWidth || 1) *
+      (weight === VectorWeight.Bold ? 2 : 1);
 
     switch (style) {
       case VectorStyle.PointDrawLine:
       case VectorStyle.SingleDashedLine:
       case VectorStyle.SingleSolidLine:
-        ctx.lineWidth = lineWidth
+        ctx.lineWidth = lineWidth;
         if (style === VectorStyle.SingleDashedLine) {
           ctx.setLineDash([8 * coordinate.ratio, 8 * coordinate.ratio]);
         } else if (style === VectorStyle.PointDrawLine) {
-          ctx.setLineDash([6 * coordinate.ratio, 6* coordinate.ratio, 2 * coordinate.ratio]);
+          ctx.setLineDash([
+            6 * coordinate.ratio,
+            6 * coordinate.ratio,
+            2 * coordinate.ratio,
+          ]);
         }
 
         ctx.moveTo(line[0].x, line[0].y);
         ctx.lineTo(line[1].x, line[1].y);
-        break
-        // 单实线
+        break;
+      // 单实线
       case VectorStyle.DoubleDashedLine:
       case VectorStyle.DoubleSolidLine:
         if (style === VectorStyle.DoubleDashedLine) {
           ctx.setLineDash([8 * coordinate.ratio, 8 * coordinate.ratio]);
         }
         const pd1 = help.getPerpendicularPoint(
-          line[0], line[1], line[0], 4 * coordinate.ratio,
-        )
+          line[0],
+          line[1],
+          line[0],
+          4 * coordinate.ratio
+        );
         const pd2 = help.getPerpendicularPoint(
-          line[0], line[1], line[1], 4 * coordinate.ratio,
-        )
+          line[0],
+          line[1],
+          line[1],
+          4 * coordinate.ratio
+        );
         const pd3 = help.getPerpendicularPoint(
-          line[0], line[1], line[0], -4 * coordinate.ratio,
-        )
+          line[0],
+          line[1],
+          line[0],
+          -4 * coordinate.ratio
+        );
         const pd4 = help.getPerpendicularPoint(
-          line[0], line[1], line[1], -4 * coordinate.ratio,
-        )
+          line[0],
+          line[1],
+          line[1],
+          -4 * coordinate.ratio
+        );
 
         ctx.moveTo(pd1.x, pd1.y);
         ctx.lineTo(pd2.x, pd2.y);
@@ -254,24 +282,24 @@ const help = {
 
         ctx.moveTo(pd3.x, pd3.y);
         ctx.lineTo(pd4.x, pd4.y);
-        break
+        break;
       case VectorStyle.BrokenLine:
-        const ldis = 5 * coordinate.ratio
+        const ldis = 5 * coordinate.ratio;
         if (mathUtil.getDistance(...line) < ldis * 2) {
           ctx.moveTo(line[0].x, line[0].y);
           ctx.lineTo(line[1].x, line[1].y);
         } else {
-          const start = mathUtil.translate(line[0], line[1], line[0], ldis)
-          const end = mathUtil.translate(line[0], line[1], line[1], -ldis)
-          const lineDis = mathUtil.getDistance(start, end)
-          const len = Math.ceil(lineDis / (6 * coordinate.ratio))
-          const split = lineDis / len
-
-          const points = [start]
-          let temp = start
-          for (let i = 0; i < len ; i++) {
-            temp = mathUtil.translate(temp, line[1], temp, split)
-            points.push(temp)
+          const start = mathUtil.translate(line[0], line[1], line[0], ldis);
+          const end = mathUtil.translate(line[0], line[1], line[1], -ldis);
+          const lineDis = mathUtil.getDistance(start, end);
+          const len = Math.ceil(lineDis / (6 * coordinate.ratio));
+          const split = lineDis / len;
+
+          const points = [start];
+          let temp = start;
+          for (let i = 0; i < len; i++) {
+            temp = mathUtil.translate(temp, line[1], temp, split);
+            points.push(temp);
           }
 
           ctx.moveTo(line[0].x, line[0].y);
@@ -281,68 +309,66 @@ const help = {
               points[i],
               points[i + 1],
               mathUtil.lineCenter(points[i], points[i + 1]),
-              (split * ((i%2) ? -1 : 1)) / 2
-            )
+              (split * (i % 2 ? -1 : 1)) / 2
+            );
             ctx.lineTo(vTop.x, vTop.y);
           }
           ctx.lineTo(end.x, end.y);
           ctx.lineTo(line[1].x, line[1].y);
         }
-        ctx.lineWidth = lineWidth
-        break
+        ctx.lineWidth = lineWidth;
+        break;
       case VectorStyle.Greenbelt:
-        const dis = 4 * coordinate.ratio
-        const size = 8 * coordinate.ratio
-        const p1 = help.getPerpendicularPoint(
-          line[0], line[1], line[0], dis
-        )
-        const p2 = help.getPerpendicularPoint(
-          line[0], line[1], line[1], dis
-        )
-        const p3 = help.getPerpendicularPoint(
-          p1, p2, p2, size
-        )
-        const p4 = help.getPerpendicularPoint(
-          p1, p2, p1, size
-        )
-
-        ctx.beginPath()
-        ctx.lineWidth = lineWidth
+        const dis = 4 * coordinate.ratio;
+        const size = 8 * coordinate.ratio;
+        const p1 = help.getPerpendicularPoint(line[0], line[1], line[0], dis);
+        const p2 = help.getPerpendicularPoint(line[0], line[1], line[1], dis);
+        const p3 = help.getPerpendicularPoint(p1, p2, p2, size);
+        const p4 = help.getPerpendicularPoint(p1, p2, p1, size);
+
+        ctx.beginPath();
+        ctx.lineWidth = lineWidth;
         ctx.moveTo(line[0].x, line[0].y);
         ctx.lineTo(line[1].x, line[1].y);
         ctx.stroke();
-        ctx.beginPath()
+        ctx.beginPath();
         ctx.moveTo(p4.x, p4.y);
         ctx.lineTo(p1.x, p1.y);
         ctx.lineTo(p2.x, p2.y);
         ctx.lineTo(p3.x, p3.y);
         ctx.stroke();
 
+        const rdis = 6 * coordinate.ratio;
+        const lineDis = mathUtil.getDistance(p3, p4);
+        const len = Math.ceil(lineDis / rdis);
+        const split = lineDis / len;
+        const points = [p3];
+        const geo = [p4, { ...p4, x: 999 }, p3];
+        let angle = (mathUtil.Angle1(...geo) / 180) * Math.PI;
+        const isClock = help.isTriangleClockwise(...geo) || angle === 0;
 
-        const rdis = 6 * coordinate.ratio
-        const lineDis = mathUtil.getDistance(p3, p4)
-        const len = Math.ceil(lineDis / rdis)
-        const split = lineDis / len
-        const points = [p3]
-        const geo = [p4, {...p4, x: 999}, p3]
-        let angle = (mathUtil.Angle1(...geo) / 180) * Math.PI
-        const isClock = help.isTriangleClockwise(...geo) || angle === 0
-
-        angle = isClock ? -angle : angle
+        angle = isClock ? -angle : angle;
 
-        let temp = p3
+        let temp = p3;
         for (let i = 0; i < len; i++) {
-          temp = mathUtil.translate(temp, p4, temp, split)
-          points.push(temp)
+          temp = mathUtil.translate(temp, p4, temp, split);
+          points.push(temp);
         }
         for (let i = 0; i < points.length - 1; i++) {
-          const center = mathUtil.lineCenter(points[i], points[i+1])
-          ctx.beginPath()
-          ctx.arc(center.x, center.y, split / 2, angle, angle + Math.PI, !isClock)
+          const center = mathUtil.lineCenter(points[i], points[i + 1]);
+          ctx.beginPath();
+          ctx.arc(
+            center.x,
+            center.y,
+            split / 2,
+            angle,
+            angle + Math.PI,
+            !isClock
+          );
           ctx.stroke();
         }
-        ctx.lineWidth = lineWidth
-        break
+        ctx.lineWidth = lineWidth;
+        break;
     }
     ctx.stroke();
     ctx.restore();
@@ -433,7 +459,7 @@ export default class Draw {
         const endScreen = coordinate.getScreenXY(midDivide.end);
         ctx.beginPath();
         if (label) {
-          help.setStyle(ctx, Style.Focus.Road)
+          help.setStyle(ctx, Style.Focus.Road);
         }
         ctx.moveTo(startScreen.x, startScreen.y);
         ctx.lineTo(endScreen.x, endScreen.y);
@@ -474,14 +500,13 @@ export default class Draw {
     ctx.save();
     ctx.beginPath();
     help.setVectorStyle(ctx, null, "Lane");
-    ctx.lineWidth *= Settings.lineWidth
+    ctx.lineWidth *= Settings.lineWidth;
     ctx.setLineDash(Style.Lane.dash);
     ctx.moveTo(start.x, start.y);
     ctx.lineTo(end.x, end.y);
     ctx.stroke();
     ctx.restore();
 
-
     if (import.meta.env.DEV) {
       // this.drawPoint(lan.start);
       // this.drawPoint(lan.end);
@@ -495,7 +520,6 @@ export default class Draw {
       : dataService.getRoadPoint(vector.startId);
     const end = isTemp ? vector.end : dataService.getRoadPoint(vector.endId);
 
-
     const drawRoadEdgeChild = (edgeVector) => {
       const flag = mathUtil.isSameDirForVector(
         start,
@@ -507,7 +531,12 @@ export default class Draw {
       if (flag) {
         const point1 = coordinate.getScreenXY(edgeVector.start);
         const point2 = coordinate.getScreenXY(edgeVector.end);
-        help.drawStyleLine(ctx, [point1, point2], edgeVector.style, edgeVector.weight)
+        help.drawStyleLine(
+          ctx,
+          [point1, point2],
+          edgeVector.style,
+          edgeVector.weight
+        );
       }
       if (import.meta.env.DEV) {
         this.drawTextByInfo(
@@ -530,46 +559,44 @@ export default class Draw {
     ctx.save();
     isTemp && (ctx.globalAlpha = 0.3);
     help.setVectorStyle(ctx, leftEdge);
-    let [style, fo] = help.getVectorStyle(vector)
-    fo && help.setStyle(ctx, style)
+    let [style, fo] = help.getVectorStyle(vector);
+    fo && help.setStyle(ctx, style);
     drawRoadEdgeChild(leftEdge);
 
     help.setVectorStyle(ctx, rightEdge);
-    fo && help.setStyle(ctx, style)
+    fo && help.setStyle(ctx, style);
 
     drawRoadEdgeChild(rightEdge);
 
     ctx.restore();
 
     if (fo) {
-      ctx.save()
+      ctx.save();
       const p1 = coordinate.getScreenXY(leftEdge.start);
       const p2 = coordinate.getScreenXY(rightEdge.start);
       const p3 = coordinate.getScreenXY(leftEdge.end);
       const p4 = coordinate.getScreenXY(rightEdge.end);
-      ctx.lineWidth = 1 * coordinate.ratio
-      ctx.setLineDash([5 * coordinate.ratio, 5 * coordinate.ratio ]);
-      ctx.strokeStyle = Style.Road.strokeStyle
-
-      ctx.beginPath()
-      ctx.moveTo(p1.x, p1.y)
-      ctx.lineTo(p2.x, p2.y)
-      ctx.stroke()
-      ctx.beginPath()
-      ctx.moveTo(p3.x, p3.y)
-      ctx.lineTo(p4.x, p4.y)
-      ctx.stroke()
-
-      ctx.fillStyle = 'rgba(23, 121, 237, 0.30)'
-      ctx.moveTo(p1.x, p1.y)
-      ctx.lineTo(p2.x, p2.y)
-      ctx.lineTo(p4.x, p4.y)
-      ctx.lineTo(p3.x, p3.y)
-      ctx.fill()
-      ctx.restore()
-    }
+      ctx.lineWidth = 1 * coordinate.ratio;
+      ctx.setLineDash([5 * coordinate.ratio, 5 * coordinate.ratio]);
+      ctx.strokeStyle = Style.Road.strokeStyle;
 
+      ctx.beginPath();
+      ctx.moveTo(p1.x, p1.y);
+      ctx.lineTo(p2.x, p2.y);
+      ctx.stroke();
+      ctx.beginPath();
+      ctx.moveTo(p3.x, p3.y);
+      ctx.lineTo(p4.x, p4.y);
+      ctx.stroke();
 
+      ctx.fillStyle = "rgba(23, 121, 237, 0.30)";
+      ctx.moveTo(p1.x, p1.y);
+      ctx.lineTo(p2.x, p2.y);
+      ctx.lineTo(p4.x, p4.y);
+      ctx.lineTo(p3.x, p3.y);
+      ctx.fill();
+      ctx.restore();
+    }
 
     if (import.meta.env.DEV) {
       // this.drawPoint(leftEdge.start);
@@ -600,7 +627,7 @@ export default class Draw {
     const extremePoint = coordinate.getScreenXY(vector.extremePoint);
     const ctx = this.context;
     ctx.save();
-    help.setVectorStyle(ctx, vector)
+    help.setVectorStyle(ctx, vector);
     ctx.beginPath();
     ctx.arc(
       extremePoint.x,
@@ -629,13 +656,14 @@ export default class Draw {
   drawCurveRoad(vector) {
     const ctx = this.context;
     ctx.save();
-    let midCovesArray
+    let midCovesArray;
     const [_, foo] = help.setVectorStyle(ctx, vector);
     if (vector.display && vector.midDivide) {
       midCovesArray = help.transformCoves([
         vector.midDivide.leftMidDivideCurves,
-        vector.midDivide.rightMidDivideCurves,
+        // vector.midDivide.rightMidDivideCurves,
       ]);
+      ctx.setLineDash([8 * coordinate.ratio, 8 * coordinate.ratio])
       ctx.lineWidth *= Settings.lineWidth
       for (let coves of midCovesArray) {
         help.drawCoves(ctx, coves);
@@ -643,75 +671,77 @@ export default class Draw {
     }
     ctx.restore();
 
-    this.drawCurveRoadEdge(dataService.getCurveRoadEdge(vector.rightEdgeId), vector);
-    this.drawCurveRoadEdge(dataService.getCurveRoadEdge(vector.leftEdgeId), vector);
+    this.drawCurveRoadEdge(
+      dataService.getCurveRoadEdge(vector.rightEdgeId),
+      vector
+    );
+    this.drawCurveRoadEdge(
+      dataService.getCurveRoadEdge(vector.leftEdgeId),
+      vector
+    );
     vector.leftLanesCurves &&
       vector.leftLanesCurves.forEach(this.drawCurveLan.bind(this));
     vector.rightLanesCurves &&
       vector.rightLanesCurves.forEach(this.drawCurveLan.bind(this));
 
-
     if (foo) {
-      const leftEdge = dataService.getCurveRoadEdge(vector.leftEdgeId)
-      const rightEdge = dataService.getCurveRoadEdge(vector.rightEdgeId)
+      const leftEdge = dataService.getCurveRoadEdge(vector.leftEdgeId);
+      const rightEdge = dataService.getCurveRoadEdge(vector.rightEdgeId);
       const p1 = coordinate.getScreenXY(leftEdge.start);
       const p2 = coordinate.getScreenXY(rightEdge.start);
       const p3 = coordinate.getScreenXY(leftEdge.end);
       const p4 = coordinate.getScreenXY(rightEdge.end);
       ctx.save();
-      ctx.setLineDash([5 * coordinate.ratio, 5 * coordinate.ratio ]);
-      ctx.lineWidth = 1 * coordinate.ratio
-      ctx.strokeStyle = Style.Lane.strokeStyle
-      ctx.beginPath()
-      ctx.moveTo(p1.x, p1.y)
-      ctx.lineTo(p2.x, p2.y)
-      ctx.stroke()
-      ctx.beginPath()
-      ctx.moveTo(p3.x, p3.y)
-      ctx.lineTo(p4.x, p4.y)
-      ctx.stroke()
+      ctx.setLineDash([5 * coordinate.ratio, 5 * coordinate.ratio]);
+      ctx.lineWidth = 1 * coordinate.ratio;
+      ctx.strokeStyle = Style.Lane.strokeStyle;
+      ctx.beginPath();
+      ctx.moveTo(p1.x, p1.y);
+      ctx.lineTo(p2.x, p2.y);
+      ctx.stroke();
+      ctx.beginPath();
+      ctx.moveTo(p3.x, p3.y);
+      ctx.lineTo(p4.x, p4.y);
+      ctx.stroke();
 
       if (midCovesArray) {
         const edgeCurves = help.transformCoves([
           leftEdge.curves,
-          rightEdge.curves
+          rightEdge.curves,
         ]);
-        edgeCurves[1] = edgeCurves[1].reverse().map(curve => ({
+        edgeCurves[1] = edgeCurves[1].reverse().map((curve) => ({
           start: curve.end,
           end: curve.start,
-          controls: curve.controls.reverse()
-        }))
-
+          controls: curve.controls.reverse(),
+        }));
 
         ctx.beginPath();
-        ctx.setLineDash([])
+        ctx.setLineDash([]);
         ctx.moveTo(edgeCurves[0][0].start.x, edgeCurves[0][0].start.y);
-        edgeCurves[0].forEach(cuve => help.drawCove(ctx, cuve))
-        ctx.lineTo(edgeCurves[1][0].start.x, edgeCurves[1][0].start.y)
-        edgeCurves[1].forEach(cuve => help.drawCove(ctx, cuve))
-        ctx.closePath()
-        ctx.fillStyle = 'rgba(23, 121, 237, 0.30)'
-        ctx.fill()
+        edgeCurves[0].forEach((cuve) => help.drawCove(ctx, cuve));
+        ctx.lineTo(edgeCurves[1][0].start.x, edgeCurves[1][0].start.y);
+        edgeCurves[1].forEach((cuve) => help.drawCove(ctx, cuve));
+        ctx.closePath();
+        ctx.fillStyle = "rgba(23, 121, 237, 0.30)";
+        ctx.fill();
       }
 
-
       ctx.restore();
     }
 
-
     // if (import.meta.env.DEV) {
-      vector.points.forEach(this.drawPoint.bind(this));
+    vector.points.forEach(this.drawPoint.bind(this));
     // }
   }
 
   drawCurveRoadEdge(vector, roadVector) {
     const [coves] = help.transformCoves([vector.curves]);
     const ctx = this.context;
-    const [style, select] = help.getVectorStyle(roadVector)
+    const [style, select] = help.getVectorStyle(roadVector);
     ctx.save();
     help.setVectorStyle(ctx, vector);
-    select && help.setStyle(ctx, style)
-    ctx.lineWidth *= Settings.lineWidth
+    select && help.setStyle(ctx, style);
+    ctx.lineWidth *= Settings.lineWidth;
     help.drawCoves(ctx, coves);
     ctx.restore();
 
@@ -726,16 +756,16 @@ export default class Draw {
     ctx.save();
 
     help.setVectorStyle(ctx, null, "CurveLan");
-    ctx.lineWidth *= Settings.lineWidth
+    ctx.lineWidth *= Settings.lineWidth;
     ctx.setLineDash(Style.Lane.dash);
     help.drawCoves(ctx, coves);
     ctx.restore();
 
     // if (import.meta.env.DEV) {
-      lines.map((line) => {
-        this.drawPoint(line.start);
-        this.drawPoint(line.end);
-      });
+    lines.map((line) => {
+      this.drawPoint(line.start);
+      this.drawPoint(line.end);
+    });
     // }
   }
 
@@ -791,7 +821,7 @@ export default class Draw {
       y: vector.popPosition.y,
     };
     const offset = radius / 2;
-    const targetPts =[mathUtil.translate(pt, target, pt, radius), target];
+    const targetPts = [mathUtil.translate(pt, target, pt, radius), target];
 
     ctx.beginPath();
     ctx.moveTo(pt.x - offset, pt.y);
@@ -811,13 +841,15 @@ export default class Draw {
       let img, imgBound;
       if (vector.photoImage) {
         img = vector.photoImage;
-        let top = 0, left = 0, size = 0
+        let top = 0,
+          left = 0,
+          size = 0;
         if (img.width > img.height) {
-          size = img.height
-          left = (img.width - size) / 2
+          size = img.height;
+          left = (img.width - size) / 2;
         } else {
-          size = img.width
-          top = (img.height - size) / 2
+          size = img.width;
+          top = (img.height - size) / 2;
         }
 
         imgBound = [left, top, size, size];
@@ -859,7 +891,7 @@ export default class Draw {
 
   drawElliptic(element, radiusX = element.radiusX, radiusY = element.radiusY) {
     function drawEllipse(context, x, y, a, b) {
-      const step = (a > b) ? 1 / a : 1 / b;
+      const step = a > b ? 1 / a : 1 / b;
       context.beginPath();
       context.moveTo(x + a, y);
       for (let i = 0; i < 2 * Math.PI; i += step) {
@@ -868,47 +900,56 @@ export default class Draw {
       context.closePath();
     }
 
-    const pt = coordinate.getScreenXY({ x: element.center.x, y: element.center.y });
+    const pt = coordinate.getScreenXY({
+      x: element.center.x,
+      y: element.center.y,
+    });
     const ctx = this.context;
     ctx.save();
     const [_, label] = help.setVectorStyle(ctx, element);
 
-    ctx.strokeStyle = element.color
+    ctx.strokeStyle = element.color;
     drawEllipse(
-      ctx, pt.x, pt.y,
+      ctx,
+      pt.x,
+      pt.y,
       (radiusX * coordinate.zoom) / coordinate.defaultZoom,
       (radiusY * coordinate.zoom) / coordinate.defaultZoom
-    )
+    );
     ctx.stroke();
     ctx.fill();
     ctx.restore();
   }
 
   drawCircle(element) {
-    this.context.save()
-    const geo = [element.center, element.points[1], {...element.center, x: 999}]
-    let angle = mathUtil.Angle(...geo)
-    angle = help.isTriangleClockwise(...geo) ? -angle : angle
-
-
-    const center = coordinate.getScreenXY(element.center)
-    this.context.translate(center.x, center.y)
-    this.context.rotate((angle / 180) * Math.PI)
-    this.context.translate(-center.x, -center.y)
-    this.drawElliptic(element, element.radiusX, element.radiusY)
-    this.context.restore()
+    this.context.save();
+    const geo = [
+      element.center,
+      element.points[1],
+      { ...element.center, x: 999 },
+    ];
+    let angle = mathUtil.Angle(...geo);
+    angle = help.isTriangleClockwise(...geo) ? -angle : angle;
+
+    const center = coordinate.getScreenXY(element.center);
+    this.context.translate(center.x, center.y);
+    this.context.rotate((angle / 180) * Math.PI);
+    this.context.translate(-center.x, -center.y);
+    this.drawElliptic(element, element.radiusX, element.radiusY);
+    this.context.restore();
 
     const [_, label] = help.getVectorStyle(element);
     label && element.points.forEach((point) => this.drawPoint(point));
   }
 
   drawPoint(vector, screenSave) {
-    const screenNotDrawTypes = [
-      VectorCategory.Point.NormalPoint,
-    ]
+    const screenNotDrawTypes = [VectorCategory.Point.NormalPoint];
     if (!screenSave) {
-      if ((Settings.screenMode && (!vector.category || screenNotDrawTypes.includes(vector.category))) ||
-        (vector.category === VectorCategory.Point.TestBasePoint)) {
+      if (
+        (Settings.screenMode &&
+          (!vector.category || screenNotDrawTypes.includes(vector.category))) ||
+        vector.category === VectorCategory.Point.TestBasePoint
+      ) {
         return;
       }
     }
@@ -930,15 +971,15 @@ export default class Draw {
       const [stylea, attr] = help.getVectorStyle(line, line.category);
       style = {
         ...style,
-        ...stylea
-      }
+        ...stylea,
+      };
     }
 
     if (vector.color) {
       ctx.strokeStyle = vector.color;
       style = {
         ...style,
-        strokeStyle: vector.color
+        strokeStyle: vector.color,
       };
     }
     const draw = (style) => {
@@ -951,7 +992,7 @@ export default class Draw {
       ctx.fill();
       ctx.restore();
     };
-    if (Settings.selectBasePointId === vector.vectorId  ) {
+    if (Settings.selectBasePointId === vector.vectorId) {
       style = {
         ...style,
         strokeStyle: "rgba(255,255,255,1)",
@@ -962,22 +1003,23 @@ export default class Draw {
       };
     }
 
+    //console.log(vector, style, Settings.selectBasePointId)
     draw(style);
     if (style.out) {
       draw(style.out);
     }
 
     if (vector.category === "BasePoint") {
-      ctx.font = `${12 * coordinate.ratio}px Microsoft YaHei`
-      const bound = help.getTextCenter(ctx, "基准点")
+      ctx.font = `${12 * coordinate.ratio}px Microsoft YaHei`;
+      const bound = help.getTextCenter(ctx, "基准点");
 
-      const screen = coordinate.getScreenXY(vector)
+      const screen = coordinate.getScreenXY(vector);
       const textPt = coordinate.getXYFromScreenNotRatio({
         y: screen.y + bound.height + style.radius,
-        x: screen.x - (bound.width / 2)
-      })
+        x: screen.x - bound.width / 2,
+      });
 
-      ctx.fillStyle = style.fillStyle
+      ctx.fillStyle = style.fillStyle;
       this.drawTextByInfo(textPt, "基准点", 0, false);
     } else {
       if (import.meta.env.DEV) {
@@ -1018,16 +1060,16 @@ export default class Draw {
     this.context.font = `${
       vector.fontSize * coordinate.ratio
     }px Microsoft YaHei`;
-    const bound = help.getTextCenter(this.context, vector.value)
+    const bound = help.getTextCenter(this.context, vector.value);
 
     // console.log(vector)
-    const screen = coordinate.getScreenXY(vector.center)
+    const screen = coordinate.getScreenXY(vector.center);
     this.drawTextByInfo(
       // vector.center,
       coordinate.getXYFromScreenNotRatio({
         // y: screen.y + (bound.height + Style.Point.radius),
-        y: screen.y + (bound.height + Style.Point.radius ),
-        x: screen.x - (bound.width / 2)
+        y: screen.y + (bound.height + Style.Point.radius),
+        x: screen.x - bound.width / 2,
       }),
       vector.value,
       -(vector.angle || 0),
@@ -1036,7 +1078,8 @@ export default class Draw {
 
     this.context.restore();
 
-    vector.displayPoint && this.drawPoint({...vector.center, color: vector.color}, true)
+    vector.displayPoint &&
+      this.drawPoint({ ...vector.center, color: vector.color }, true);
   }
 
   drawSVG(vector) {
@@ -1054,7 +1097,7 @@ export default class Draw {
     this.context.scale(width / svgWidth, height / svgHidth);
     const [style, label] = help.setVectorStyle(this.context, vector);
     this.context.lineWidth = style.lineWidth / (width / svgWidth);
-    SVGIcons[vector.type].draw(this.context);
+    SVGIcons[vector.type].draw(this.context, style.fillStyle, style.strokeStyle);
     this.context.restore();
 
     if (label) {
@@ -1064,13 +1107,15 @@ export default class Draw {
       this.context.lineTo(points[1].x, points[1].y);
       this.context.lineTo(points[2].x, points[2].y);
       this.context.lineTo(points[3].x, points[3].y);
-      this.context.strokeStyle = style.strokeStyle
-      this.context.lineWidth = 2 *  coordinate.ratio
+      this.context.strokeStyle = style.strokeStyle;
+      this.context.lineWidth = 2 * coordinate.ratio;
       this.context.setLineDash([6 * coordinate.ratio, 2 * coordinate.ratio]);
       this.context.closePath();
       this.context.stroke();
       this.context.restore();
-      vector.points.forEach(point => this.drawPoint({...point, color: style.strokeStyle, radius: 5 }))
+      vector.points.forEach((point) =>
+        this.drawPoint({ ...point, color: style.strokeStyle, radius: 5 })
+      );
     }
   }
 
@@ -1106,7 +1151,7 @@ export default class Draw {
       30 * coordinate.ratio
     );
     const ctx = this.context;
-    ctx.save()
+    ctx.save();
     ctx.beginPath();
     const [style] = help.setVectorStyle(
       this.context,
@@ -1135,7 +1180,7 @@ export default class Draw {
         fillColor: style.strokeStyle,
       }
     );
-    ctx.restore()
+    ctx.restore();
   }
 
   drawCurveLine(vector) {
@@ -1143,7 +1188,9 @@ export default class Draw {
     const ctx = this.context;
     ctx.save();
     help.setVectorStyle(ctx, vector);
-    help.drawCoves(ctx, help.transformCoves([vector.points]));
+    help.transformCoves([vector.curves]).forEach((coves) => {
+      help.drawCoves(ctx, coves);
+    });
     ctx.restore();
 
     if (import.meta.env.DEV) {
@@ -1167,8 +1214,7 @@ export default class Draw {
       this.context.setLineDash(style.dash);
     }
 
-    help.drawStyleLine(this.context, [start, end], vector.style, vector.weight)
-
+    help.drawStyleLine(this.context, [start, end], vector.style, vector.weight);
 
     switch (vector.category) {
       case VectorCategory.Line.SingleArrowLine:

+ 5 - 0
src/graphic/Renderer/Render.js

@@ -157,6 +157,11 @@ export default class Render {
       this.drawGeometry(lines[key]);
     }
 
+    const curveLines = dataService.getCurveLines();
+    for (const key in curveLines) {
+      this.drawGeometry(curveLines[key]);
+    }
+
     const circles = dataService.getCircles();
     for (const key in circles) {
       this.drawGeometry(circles[key]);

+ 7 - 7
src/graphic/Service/CurveRoadService.js

@@ -747,22 +747,22 @@ export default class CurveRoadService extends RoadService {
     let leftCurveEdge = dataService.getCurveRoadEdge(curveRoad.leftEdgeId);
     let rightCurveEdge = dataService.getCurveRoadEdge(curveRoad.rightEdgeId);
 
-    lineService.createCurveLineForPoints(leftCurveEdge.points);
-    lineService.createCurveLineForPoints(rightCurveEdge.points);
+    lineService.createCurveLineByPoints(leftCurveEdge.points);
+    lineService.createCurveLineByPoints(rightCurveEdge.points);
 
     if (curveRoad.way == Constant.oneWay) {
       for (let i = 0; i < curveRoad.singleLanesCurves.length; ++i) {
-        lineService.createCurveLineForPoints(curveRoad.singleLanesCurves[i]);
+        lineService.createCurveLineByPoints(curveRoad.singleLanesCurves[i]);
       }
     } else if (curveRoad.way == Constant.twoWay) {
       for (let i = 0; i < curveRoad.leftLanesCurves.length; ++i) {
-        lineService.createCurveLineForPoints(curveRoad.leftLanesCurves[i]);
+        lineService.createCurveLineByPoints(curveRoad.leftLanesCurves[i]);
       }
       for (let i = 0; i < curveRoad.rightLanesCurves.length; ++i) {
-        lineService.createCurveLineForPoints(curveRoad.rightLanesCurves[i]);
+        lineService.createCurveLineByPoints(curveRoad.rightLanesCurves[i]);
       }
-      lineService.createCurveLineForPoints(curveRoad.midDivide.leftMidDivide);
-      lineService.createCurveLineForPoints(curveRoad.midDivide.rightMidDivide);
+      lineService.createCurveLineByPoints(curveRoad.midDivide.leftMidDivide);
+      lineService.createCurveLineByPoints(curveRoad.midDivide.rightMidDivide);
     }
   }
 }

+ 1 - 0
src/graphic/Service/HistoryService.js

@@ -49,6 +49,7 @@ export class HistoryService {
     }
 
     setHistoryState(pre, next) {
+       
         this.history.state.pre = pre
         this.history.state.next = next
     }

+ 122 - 9
src/graphic/Service/LineService.js

@@ -72,6 +72,12 @@ export default class LineService {
     endPoint = uiService.getNewPositionForPop(endPoint);
     let newLine = this.create(startPoint, endPoint, line.category);
     newLine.setColor(line.color);
+    if (line.weight) {
+      newLine.setWeight(line.weight);
+    }
+    if (line.style) {
+      newLine.setStyle(line.style);
+    }
     return newLine;
   }
 
@@ -106,13 +112,16 @@ export default class LineService {
       vectorId
     );
 
-    startPoint.setPointParent(curveLine.vectorId, "start");
-    endPoint.setPointParent(curveLine.vectorId, "end");
+    startPoint.setPointParent(curveLine.vectorId);
+    startPoint.setIndex(0);
+    endPoint.setPointParent(curveLine.vectorId);
+    endPoint.setIndex(2);
     let midPoint = curvePointService.create({
       x: (startPoint.x + endPoint.x) / 2,
       y: (startPoint.y + endPoint.y) / 2,
     });
-
+    midPoint.setPointParent(curveLine.vectorId);
+    midPoint.setIndex(1);
     curveLine.points = [];
     curveLine.points.push(startPoint);
     curveLine.points.push(midPoint);
@@ -122,10 +131,28 @@ export default class LineService {
     return curveLine;
   }
 
-  createCurveLineForPoints(points, vectorId) {
+  createCurveLineByPointIds(curvePoints, vectorId) {
+    let curveLine = new CurveLine(
+      curvePoints[0].vectorId,
+      curvePoints[curvePoints.length - 1].vectorId,
+      vectorId
+    );
+    curveLine.points = [];
+    for (let i = 0; i < curvePoints.length; ++i) {
+      curveLine.points[i] = dataService.getCurvePoint(curvePoints[i].vectorId);
+      curveLine.points[i].setIndex(i);
+      curveLine.points[i].setPointParent(curveLine.vectorId);
+    }
+    curveLine.curves = mathUtil.getCurvesByPoints(curveLine.points);
+    dataService.addCurveLine(curveLine);
+    return curveLine;
+  }
+
+  createCurveLineByPoints(points, vectorId) {
     let curvePoints = [];
     for (let i = 0; i < points.length; ++i) {
       let curvePoint = curvePointService.create(points[i]);
+      curvePoint.setIndex(i);
       curvePoints.push(curvePoint);
     }
     let curveLine = new CurveLine(
@@ -133,16 +160,102 @@ export default class LineService {
       curvePoints[curvePoints.length - 1].vectorId,
       vectorId
     );
-    curvePoints[0].setPointParent(curveLine.vectorId, "start");
-    curvePoints[curvePoints.length - 1].setPointParent(
-      curveLine.vectorId,
-      "end"
-    );
     curveLine.points = JSON.parse(JSON.stringify(curvePoints));
+    for (let i = 0; i < curveLine.points.length; ++i) {
+      curveLine.points[i].setIndex(i);
+      curveLine.points[i].setPointParent(curveLine.vectorId);
+    }
     curveLine.curves = mathUtil.getCurvesByPoints(curveLine.points);
     dataService.addCurveLine(curveLine);
     return curveLine;
   }
+
+  addCPoint(position, index, vectorId) {
+    let curveLine = dataService.getCurveLine(vectorId);
+    let newPoint = curvePointService.create(position);
+    newPoint.setIndex(index);
+    newPoint.setPointParent(vectorId);
+    curveLine.points.splice(index + 1, 0, newPoint);
+    curveLine.curves = mathUtil.getCurvesByPoints(curveLine.points);
+  }
+
+  copyCurveLine(vectorId) {
+    let curveLine = dataService.getCurveLine(vectorId);
+    let startPoint = dataService.getCurvePoint(curveLine.startId);
+    let endPoint = dataService.getCurvePoint(curveLine.endId);
+    startPoint = uiService.getNewPositionForPop(startPoint);
+    endPoint = uiService.getNewPositionForPop(endPoint);
+
+    let newCurveLine = this.createCurveLine(startPoint, endPoint);
+    newCurveLine.setColor(curveLine.color);
+    if (curveLine.weight) {
+      newCurveLine.setWeight(curveLine.weight);
+    }
+    if (curveLine.style) {
+      newCurveLine.setStyle(curveLine.style);
+    }
+    mathUtil.clonePoint(newCurveLine.points[1], curveLine.points[1]);
+    for (let i = 2; i < curveLine.points.length - 1; ++i) {
+      let newPoint = uiService.getNewPositionForPop(curveLine.points[i]);
+      newPoint = curvePointService.create(newPoint);
+      newPoint.setPointParent(vectorId);
+      newPoint.setIndex(i);
+      newCurveLine.points.splice(i + 1, 0, newPoint);
+    }
+    newCurveLine.curves = mathUtil.getCurvesByPoints(newCurveLine.points);
+    return newCurveLine;
+  }
+
+  deleteCrossPointForCurveLine(curvePointId, curveLineId) {
+    let curveLine = dataService.getCurveLine(curveLineId);
+    for (let i = 0; i < curveLine.points.length; ++i) {
+      if (curveLine.points[i].vectorId == curvePointId) {
+        if (i == 0) {
+          curveLine.points.shift();
+          curveLine.startId = curveLine.points[0].vectorId;
+          for (let j = 0; j < curveLine.points.length; ++j) {
+            let _curvePoint = dataService.getCurvePoint(
+              curveLine.points[j].vectorId
+            );
+            const index = _curvePoint.getIndex();
+            _curvePoint.setIndex(index - 1);
+          }
+        } else if (i == curveLine.points.length - 1) {
+          curveLine.points.pop();
+          curveLine.endId =
+            curveLine.points[curveLine.points.length - 1].vectorId;
+        } else {
+          curveLine.points.splice(i, 1);
+          for (let j = i; j < curveLine.points.length; ++j) {
+            let _curvePoint = dataService.getCurvePoint(
+              curveLine.points[j].vectorId
+            );
+            const index = _curvePoint.getIndex();
+            _curvePoint.setIndex(index - 1);
+          }
+        }
+        break;
+      }
+    }
+    if (curveLine.points.length == 2) {
+      let startPoint = dataService.getCurvePoint(curveLine.startId);
+      let endPoint = dataService.getCurvePoint(curveLine.endId);
+      let line = this.create(startPoint, endPoint);
+      const weight = curveLine.getWeight();
+      line.setWeight(weight);
+      this.deleteCurveLine(curveLineId);
+    } else {
+      curveLine.curves = mathUtil.getCurvesByPoints(curveLine.points);
+    }
+  }
+
+  deleteCurveLine(curveLineId) {
+    let curveLine = dataService.getCurveLine(curveLineId);
+    for (let i = 0; i < curveLine.points.length; ++i) {
+      dataService.deleteCurvePoint(curveLine.points[i].vectorId);
+    }
+    dataService.deleteCurveLine(curveLineId);
+  }
 }
 
 const lineService = new LineService();

+ 4 - 0
src/hook/custom/preset.ts

@@ -2,6 +2,7 @@ import { Mode, PointInfo, Pos } from "@/sdk/types";
 import { stackFactory, Stack, fastStacksValue, os } from "@/utils/vue";
 import { Ref, ref } from "vue";
 import {FixPoint} from "@/store/fixPoint";
+import {BasePoint} from "@/store/basePoint";
 
 export enum DisabledCom {
   Search = "search",
@@ -79,6 +80,7 @@ export enum CustomCom {
   MagnifierMode = "magnifier",
   CustomMouseMenu = "cMoseMenu",
   ActiveFixPoint = "activeFixPoint",
+  ActiveBasePoint = "activeBasePoint",
   ResidenMouseMenu = "rMouseMenu",
   CarryView = "carryView",
   SysView = "sysView",
@@ -126,12 +128,14 @@ export const boxWidthStack = stackFactory(
 export const autoSysViewLeftStack = stackFactory(ref<string>("70px"));
 export const controlFullStack = stackFactory(ref<boolean>(false));
 export const activeFixPointStack = stackFactory(ref<FixPoint>());
+export const activeBasePointStack = stackFactory(ref<BasePoint>());
 
 export const customMapStack = {
   [CustomCom.LaserMode]: laserModeStack,
   [CustomCom.FullView]: fullViewStack,
   [CustomCom.SpiltView]: spiltViewModeStack,
   [CustomCom.ActiveFixPoint]: activeFixPointStack,
+  [CustomCom.ActiveBasePoint]: activeBasePointStack,
   [CustomCom.MagnifierMode]: magnifierModeStack,
   [CustomCom.ResidenMouseMenu]: residenMouseMenuStack,
   [CustomCom.CustomMouseMenu]: customMouseMenuStack,

+ 1 - 5
src/store/sync.ts

@@ -193,11 +193,7 @@ export const api =
       };
 
 export const back = () => {
-  if (history.state.back) {
-    router.back();
-  } else {
-    api.closePage();
-  }
+  api.closePage()
 };
 
 const loadStore = async () => {

+ 6 - 4
src/views/accidents/index.vue

@@ -1,7 +1,7 @@
 <template>
   <MainPanel>
     <template v-slot:header>
-      <Header type="return_l" :count="selects.length" :title="`已标注照片(${sortPhotos.length})`">
+      <Header type="return_l" :count="selects.length" :title="`已标注照片(${sortPhotos.length})`" :on-back="() => api.closePage()">
         <ui-button
             :type="selectMode ? 'primary' : 'normal'"
             @click="selectMode = !selectMode"
@@ -58,17 +58,16 @@ import MainPanel from '@/components/main-panel/index.vue'
 import FillSlide from '@/components/fill-slide/index.vue'
 import ActionMenus from "@/components/group-button/index.vue";
 import {types, accidentPhotos, AccidentPhoto} from '@/store/accidentPhotos'
-import UiIcon from "@/components/base/components/icon/index.vue";
 import {router, writeRouteName} from '@/router'
 import {computed, onDeactivated, reactive, ref, watchEffect} from "vue";
 import {Mode} from '@/views/graphic/menus'
 import UiButton from "@/components/base/components/button/index.vue";
 import Photos from "@/components/photos/index.vue";
 import Header from "@/components/photos/header.vue";
-import ButtonPane from "@/components/button-pane/index.vue";
 import {useConfirm} from "@/hook";
-import {roadPhotos} from "@/store/roadPhotos";
 import Undata from "@/components/photos/undata.vue";
+import {api} from "@/store/sync";
+import {photos} from "@/store/photos";
 
 const sortPhotos = computed(() => {
   const photos = [...accidentPhotos.value]
@@ -162,6 +161,9 @@ const delSelects = async () => {
       delPhotoRaw(selects.value[0])
       selects.value.shift()
     }
+    if (!sortPhotos.value.length) {
+      selectMode.value = false
+    }
   }
 }
 const gotoDraw = () => {

+ 25 - 10
src/views/accidents/print.vue

@@ -12,10 +12,10 @@
       </Header>
     </template>
 
-    <div class="print-layout">
-      <div class="content" ref="layoutRef">
+    <div class="print-layout" :class="{downMode}">
+      <div class="content " ref="layoutRef" >
         <div v-for="accidentPhoto in genAccidentPhotos" :key="accidentPhoto.id" class="item">
-          <h4>{{accidentPhoto.title}}</h4>
+<!--          <h4>{{accidentPhoto.title}}</h4>-->
           <img :src="useStaticUrl(accidentPhoto.url).value">
         </div>
       </div>
@@ -26,7 +26,7 @@
 import UiButton from "@/components/base/components/button/index.vue";
 import Header from "@/components/photos/header.vue";
 import MainPanel from "@/components/main-panel/index.vue";
-import {computed, ref} from "vue";
+import {computed, nextTick, ref} from "vue";
 import html2canvas from "html2canvas";
 import {router, writeRouteName} from "@/router";
 import {AccidentPhoto, accidentPhotos} from "@/store/accidentPhotos";
@@ -49,13 +49,17 @@ const genAccidentPhotos = computed<AccidentPhoto[]>(() => {
 })
 
 const layoutRef = ref<HTMLDivElement>()
+const downMode = ref(false)
 const saveHandler = async () => {
+  downMode.value = true
+  await nextTick()
   const canvas = await html2canvas(layoutRef.value)
   const blob = await new Promise<Blob>(
     resolve => canvas.toBlob(resolve, "image/jpeg", 0.95)
   )
   const success = await downloadImage(blob)
-  const hide = Message.success({ msg: success  ? "照片已生成" : "照片生成失败" })
+  const hide = Message.success({ msg: success  ? "已保存至相册" : "照片生成失败" })
+  downMode.value = false
   setTimeout(() => {
     hide()
     back()
@@ -68,7 +72,6 @@ const saveHandler = async () => {
   top: calc(var(--header-top) + var(--editor-head-height));
   position: absolute;
   background: #16181A;
-  padding: 65px;
   bottom: 0;
   left: 0;
   right: 0;
@@ -76,15 +79,19 @@ const saveHandler = async () => {
 
 }
 .content {
-  width: 1066px;
-  max-width: 100%;
+  width: 100%;
   height: 1514px;
-  padding: 0 64px;
+  padding: 125px 100px;
   margin: 0 auto;
   background: #fff;
+  display: flex;
+  flex-direction: column;
 }
 
 .item {
+  height: 50%;
+  display: flex;
+  align-items: center;
   h4 {
     font-size: 32px;
     color: #000000;
@@ -96,8 +103,16 @@ const saveHandler = async () => {
 
   img {
     width: 100%;
-    height: 600px;
+    max-height: 90%;
     object-fit: cover;
   }
 }
+
+.downMode {
+  .content {
+    width: 1050px;
+    height: 1485px;
+    padding: 125px 100px;
+  }
+}
 </style>

+ 2 - 1
src/views/graphic/confirm.vue

@@ -33,6 +33,7 @@ import {uiType, drawRef} from '@/hook/useGraphic'
   width: 64px;
   font-size: 22px;
   justify-content: center;
-  background-color: #fff
+  background-color: #fff;
+  box-shadow: 0px 0px 4px 0px rgba(0,0,0,0.5);
 }
 </style>

+ 4 - 5
src/views/graphic/geos/arrow.vue

@@ -7,7 +7,7 @@
       </template>
     </template>
   </GeoTeleport>
-  <GeoTeleport :menus="typeMenus" v-if="typeMenus" class="type-geo" />
+  <GeoTeleport :menus="typeMenus" v-if="typeMenus" class="type-geo" :active="typeMenus.find(menu => menu.key === type)" />
 </template>
 
 <script setup lang="ts">
@@ -25,10 +25,9 @@ const props = defineProps<{geo: FocusVector}>()
 const vector = computed(() => dataService.getLine(props.geo.vectorId))
 const color = ref("#000000")
 const type = ref(props.geo.category || "SingleArrowLine")
-console.log(type.value)
 useChange(() => {
   color.value = vector.value.color
-  color.value = vector.value.category
+  type.value = vector.value.category
 })
 
 
@@ -57,13 +56,13 @@ const menus = ref([
       typeMenus.value = !typeMenus.value
         ? [
           {
-            key: 'color',
+            key: 'SingleArrowLine',
             icon: 'arrows_s',
             text: "单向",
             onClick: () => type.value = "SingleArrowLine"
           },
           {
-            key: 'color',
+            key: 'DoubleArrowLine',
             icon: 'arrows_d',
             text: "双向",
             onClick: () => type.value = "DoubleArrowLine"

+ 1 - 0
src/views/graphic/geos/index.ts

@@ -23,6 +23,7 @@ export default {
   [VectorType.DoubleArrowLine]: Arrow,
   // [VectorCategory.Line.MeasureLine]: Arrow,
   [VectorCategory.Line.NormalLine]: NormalLine,
+  [VectorType.CurveLine]: NormalLine,
   [VectorType.Text]: Text,
   [VectorType.Circle]: Circle,
   [VectorType.Magnifier]: magnifier

+ 8 - 3
src/views/graphic/geos/magnifier.vue

@@ -9,7 +9,7 @@ import UiInput from "@/components/base/components/input/index.vue";
 import UiIcon from "@/components/base/components/icon/index.vue";
 import {uploadImage} from '@/store/sync'
 import {drawRef, FocusVector, uiType, UIType} from '@/hook/useGraphic'
-import {computed, ref, UnwrapRef, watch} from "vue";
+import {computed, reactive, ref, UnwrapRef, watch} from "vue";
 import {dataService} from "@/graphic/Service/DataService";
 import {api} from "@/store/sync";
 import GeoActions from "@/graphic/enum/GeoActions";
@@ -17,7 +17,8 @@ import GeoActions from "@/graphic/enum/GeoActions";
 const props = defineProps<{geo: FocusVector}>()
 const vector = computed(() => dataService.getMagnifier(props.geo.vectorId))
 const typeMenus = ref<UnwrapRef<typeof menus>>()
-const menus = [
+console.log(vector.value)
+const menus = reactive([
   {
     key: 'file',
     text: "拍照",
@@ -49,6 +50,7 @@ const menus = [
     key: 'reset',
     icon: "recover",
     text: "恢复默认",
+    disabled: !vector.value.photoUrl,
     onClick: () => syncVector(null)
   },
   {
@@ -59,7 +61,7 @@ const menus = [
       drawRef.value.uiControl.handleGeo(GeoActions.DeleteAction)
     }
   }
-]
+])
 const syncVector = (url: string) => {
   vector.value.setSrc(url)
   vector.value.setImageData()
@@ -67,6 +69,9 @@ const syncVector = (url: string) => {
       drawRef.value.renderer.autoRedraw()
       drawRef.value.history.save()
     })
+
+
+  menus[1].disabled = !vector.value.photoUrl
 }
 
 </script>

+ 19 - 14
src/views/graphic/geos/normalLine.vue

@@ -1,9 +1,9 @@
 <template>
-  <GeoTeleport :menus="menus" class="geo-teleport-use" :active="active"/>
-  <GeoTeleport :menus="childMenus" v-if="childMenus" class="type-geo"/>
+  <GeoTeleport :active="active" :menus="menus" class="geo-teleport-use"/>
+  <GeoTeleport v-if="childMenus" :menus="childMenus" class="type-geo"/>
 </template>
 
-<script setup lang="ts">
+<script lang="ts" setup>
 import GeoTeleport from "@/views/graphic/geos/geo-teleport.vue";
 import {drawRef, FocusVector, VectorType} from '@/hook/useGraphic'
 import {computed, ref, toRaw, UnwrapRef} from "vue";
@@ -49,7 +49,12 @@ const lineTypeMenu = [
     text: "双虚线",
     onClick: clickHandlerFactory(VectorStyle.DoubleDashedLine)
   },
-  {key: VectorStyle.BrokenLine, icon: "line_broken", text: "折线", onClick: clickHandlerFactory(VectorStyle.BrokenLine)},
+  {
+    key: VectorStyle.BrokenLine,
+    icon: "line_broken",
+    text: "折线",
+    onClick: clickHandlerFactory(VectorStyle.BrokenLine)
+  },
   {
     key: VectorStyle.PointDrawLine,
     icon: "line_dot",
@@ -79,7 +84,7 @@ const lineWidthMenu = [
   },
 ]
 
-const appendMenus = props.geo.category === VectorCategory.Line.NormalLine
+const appendMenus = (props.geo.category === VectorCategory.Line.NormalLine || props.geo.type === VectorType.CurveLine)
   ? [
     {
       key: VectorEvents.AddCrossPoint,
@@ -87,24 +92,24 @@ const appendMenus = props.geo.category === VectorCategory.Line.NormalLine
       text: "加控制点",
       onClick: clickHandlerFactory(VectorEvents.AddCrossPoint)
     },
-    {
-      key: VectorEvents.MinusCrossPoint,
-      icon: "control_d",
-      text: "减控制点",
-      onClick: clickHandlerFactory(VectorEvents.MinusCrossPoint)
-    },
+    // {
+    //   key: VectorEvents.MinusCrossPoint,
+    //   icon: "control_d",
+    //   text: "减控制点",
+    //   onClick: clickHandlerFactory(VectorEvents.MinusCrossPoint)
+    // },
   ]
   : []
 const childMenus = ref<UnwrapRef<typeof menus>>()
 const menus = ref([
-  {
+    ...(props.geo.type !== VectorType.CurveLine ? [{
     key: UITypeExtend.lineType,
     text: "单实线",
     icon: "line",
     onClick() {
       childMenus.value = toRaw(childMenus.value) === lineTypeMenu ? null : lineTypeMenu
     }
-  },
+  }] : []),
   vector.value?.weight === VectorWeight.Bold ? lineWidthMenu[0] : lineWidthMenu[1],
   ...appendMenus,
   {
@@ -132,7 +137,7 @@ const active = computed(() =>
 
 </script>
 
-<style scoped lang="scss">
+<style lang="scss" scoped>
 .color {
   width: 18px;
   height: 18px;

+ 38 - 20
src/views/graphic/header.vue

@@ -1,47 +1,48 @@
 <template>
-  <div class="graphic-header" v-if="data">
+  <div v-if="data" class="graphic-header">
     <div class="title">
-      <ui-icon type="return" @click="back" class="head-icon" />
+      <ui-icon class="head-icon" type="return" @click="back"/>
       <p>{{ isRoad ? '现场绘图' : '事故照片' }}</p>
     </div>
     <div class="actions">
       <div
           v-for="menu in menus"
           :key="menu.text"
-          class="action fun-ctrl"
           :class="{disabled: menu.disable}"
+          class="action fun-ctrl"
           @click="menu.onClick"
       >
-        <ui-icon :type="menu.icon"  />
+        <ui-icon :type="menu.icon"/>
         <p>{{ menu.text }}</p>
         <ui-input
-            type="checkbox"
+            v-if="menu.icon === 'map'"
             :modelValue="graphicState.showBackImage"
             class="map-status"
-            v-if="menu.icon === 'map'"
+            type="checkbox"
         />
       </div>
     </div>
 
     <div class="table">
       <ui-input
-          width="120px"
+          v-if="options"
+          v-model="(data as AccidentPhoto).type"
+          :options="options"
           height="32px"
           type="select"
-          :options="options"
-          v-model="(data as AccidentPhoto).type"
-          v-if="options"
+          width="120px"
       />
-      <ui-button width="100px" class="save save-file" @click="saveHandler">
+      <ui-button :class="{['save-file']: isRoad}" :type="isRoad ? undefined : 'primary'" class="save" width="100px"
+                 @click="saveHandler">
         保存
       </ui-button>
-      <ui-button width="100px" type="primary" class="save" @click="createTable" v-if="isRoad">
+      <ui-button v-if="isRoad" class="save" type="primary" width="100px" @click="createTable">
         制表
       </ui-button>
     </div>
   </div>
 </template>
-<script setup lang="ts">
+<script lang="ts" setup>
 import UiIcon from "@/components/base/components/icon/index.vue";
 import UiButton from "@/components/base/components/button/index.vue";
 import {Mode} from './menus'
@@ -60,7 +61,7 @@ const data = useData()
 const mode = computed(() => Number(router.currentRoute.value.params.mode) as Mode)
 const isRoad = computed(() => mode.value === Mode.Road)
 const options = computed(() =>
-  !isRoad.value ? types.map(t => ({ label: t, value: t })) : null
+  !isRoad.value ? types.map(t => ({label: t, value: t})) : null
 )
 const backImageChang = (show) => {
   dataService.setGridDisplay(!show)
@@ -73,7 +74,7 @@ watchEffect(() => {
   }
 })
 
-type Menu = {disable?: boolean, text: string, icon: string, onClick: () => void}
+type Menu = { disable?: boolean, text: string, icon: string, onClick: () => void }
 const menus = computed<Menu[]>(() => {
   const menus = [
     {
@@ -142,13 +143,13 @@ const saveHandler = async () => {
 
 const createTable = async () => {
   await saveStore()
-  await router.replace({name: writeRouteName.tabulation, params: {id: data.value.id} })
+  await router.replace({name: writeRouteName.tabulation, params: {id: data.value.id}})
 }
 
 
 </script>
 
-<style scoped lang="scss">
+<style lang="scss" scoped>
 .graphic-header {
   display: flex;
   position: relative;
@@ -161,6 +162,7 @@ const createTable = async () => {
 .actions {
   display: flex;
 }
+
 .action {
   font-size: 20px;
   margin: 0 15px;
@@ -169,6 +171,7 @@ const createTable = async () => {
   align-items: center;
   position: relative;
   justify-content: center;
+
   p {
     font-size: 14px;
     text-align: center;
@@ -186,6 +189,7 @@ const createTable = async () => {
   left: 0;
   display: flex;
   align-items: center;
+
   p {
     margin-left: 10px;
   }
@@ -196,7 +200,7 @@ const createTable = async () => {
 }
 
 .save {
-  margin-left: 24px;
+  margin-left: 16px;
 }
 
 .map-status {
@@ -207,15 +211,27 @@ const createTable = async () => {
   bottom: 0;
   z-index: 1;
 }
+.head-icon {
+  width: 32px;
+  height: 32px;
+  background: rgba(255,255,255,0.1);
+  border-radius: 24px 24px 24px 24px;
+  font-size: 16px !important;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin-left: -3px;
+}
 </style>
 
 <style lang="scss">
 .map-status.ui-input,
-.map-status.ui-input .checkbox{
+.map-status.ui-input .checkbox {
   width: 12px;
   height: 7px;
 
 }
+
 .map-status.ui-input .checkbox input + .replace {
   border-radius: 4px;
   background-color: #7E7E7E;
@@ -234,12 +250,14 @@ const createTable = async () => {
     left: 1px;
     transition: all .3s ease;
   }
+
   i {
     display: none;
   }
 
-  &.checked{
+  &.checked {
     background-color: var(--colors-primary-base) !important;
+
     &:before {
       left: calc(100% - 6px);
     }

+ 3 - 3
src/views/graphic/menus.ts

@@ -68,11 +68,11 @@ export const templateMenusRaw = [
   { key: RoadTemplate.Bend, icon: 'mb_wd', text: '弯道' },
   { key: RoadTemplate.SharpCurve, icon: 'mb_jzwd', text: '急转弯道' },
   { key: RoadTemplate.SixForkIntersection, icon: 'mb_lclk', text: '六岔路口' },
-  { key: RoadTemplate.WideNarrowRoad, icon: 'mb_kbzld', text: '宽变窄路段' },
+  // { key: RoadTemplate.WideNarrowRoad, icon: 'mb_kbzld', text: '宽变窄路段' },
   { key: RoadTemplate.Corner, icon: 'mb_zjwd', text: '直角弯道' },
   { key: RoadTemplate.ImportSmashedRoad, icon: 'mb_jkzd', text: '进口匝道' },
   { key: RoadTemplate.HighSpeedTollBooth, icon: 'mb_gssfz', text: '高速收费站' },
-  { key: RoadTemplate.HighSpeedHarbor, icon: 'mb_gsgw', text: '高速港湾' },
+  // { key: RoadTemplate.HighSpeedHarbor, icon: 'mb_gsgw', text: '高速港湾' },
   { key: RoadTemplate.HighwaySection, icon: 'mb_gsld', text: '高速路段' },
 ];
 
@@ -165,7 +165,7 @@ export const mainMenusRaw: MenusRaw = [
   {
     key: UITypeExtend.image,
     text: '图例',
-    icon: 'road',
+    icon: 'legend',
     // children: [
     //   { key: UIType.BusPlane, text: "客车平面图" }
     // ]

+ 4 - 1
src/views/photos/index.vue

@@ -1,7 +1,7 @@
 <template>
   <MainPanel>
     <template v-slot:header>
-      <Header :count="selects.length" :title="`全部照片(${photos.length})`">
+      <Header :count="selects.length" :title="`全部照片(${photos.length})`" type="return">
         <ui-button type="primary" @click="selectMode = !selectMode" width="96px" v-if="sortPhotos.length">
           {{ selectMode ? '取消' : '选择' }}
         </ui-button>
@@ -162,6 +162,9 @@ const delSelects = async () => {
       delPhotoRaw(selects.value[0])
       selects.value.shift()
     }
+    if (!sortPhotos.value.length) {
+      selectMode.value = false
+    }
   }
 }
 

+ 6 - 1
src/views/roads/index.vue

@@ -1,7 +1,7 @@
 <template>
   <MainPanel>
     <template v-slot:header>
-      <Header :count="selects.length" :title="`现场图管理(${sortPhotos.length})`" type="return_l">
+      <Header :count="selects.length" :title="`现场图管理(${sortPhotos.length})`" type="return_l" :on-back="() => api.closePage()">
         <ui-button
             :type="selectMode ? 'primary' : 'normal'"
             @click="selectMode = !selectMode"
@@ -66,6 +66,8 @@ import Photos from "@/components/photos/index.vue";
 import ButtonPane from "@/components/button-pane/index.vue";
 import UiIcon from "@/components/base/components/icon/index.vue";
 import {useConfirm} from "@/hook";
+import {api} from "@/store/sync";
+import {photos} from "@/store/photos";
 
 
 const sortPhotos = computed(() => [...roadPhotos.value].reverse())
@@ -133,6 +135,9 @@ const delSelects = async () => {
       delPhotoRaw(selects.value[0])
       selects.value.shift()
     }
+    if (!sortPhotos.value.length) {
+      selectMode.value = false
+    }
   }
 }
 

+ 40 - 3
src/views/roads/tabulation.vue

@@ -12,7 +12,7 @@
       </Header>
     </template>
 
-    <div class="tab-layout" v-if="roadPhoto">
+    <div class="tab-layout" v-if="roadPhoto" :class="{downMode}">
       <div class="content" ref="layoutRef">
         <table>
           <tr>
@@ -139,6 +139,7 @@ import Header from "@/components/photos/header.vue";
 import MainPanel from "@/components/main-panel/index.vue";
 import {downloadImage, uploadImage} from "@/store/sync";
 import {Mode} from "@/views/graphic/menus";
+import Message from "@/components/base/components/message/message.vue";
 
 const roadPhoto = computed<RoadPhoto>(() => {
   let route, params, data
@@ -207,6 +208,7 @@ const getLayoutImage = async () => {
   downMode.value = true
   await nextTick()
   const canvas = await html2canvas(layoutRef.value)
+  Message.success({ msg: "已保存至相册", time: 2000 } )
   downMode.value = false
   const blob = await new Promise<Blob>(resolve => canvas.toBlob(resolve, "image/jpeg", 0.95))
   await downloadImage(blob)
@@ -235,8 +237,7 @@ const saveHandler = async () => {
 }
 
 .content {
-  box-sizing: content-box;
-  width: 1066px;
+  width: 100%;
   padding: 20px 20px 60px;
   margin: 0 auto;
 }
@@ -329,6 +330,42 @@ const saveHandler = async () => {
   }
 }
 
+.downMode {
+  .content {
+    width: 1485px;
+    height: 1050px;
+    padding: 125px 100px 75px 100px;
+    overflow: hidden;
+  }
+  .content table {
+    .value {
+      background: none;
+    }
+
+    tr:not(:first-child) {
+      td {
+        border-right: 5px solid #000;
+        border-bottom: 5px solid #000;
+      }
+
+      &:nth-child(2) td {
+        border-top: 7.5px solid #000;
+      }
+
+      td:first-child {
+        border-left: 7.5px solid #000;
+      }
+      td:last-child {
+        border-right: 7.5px solid #000;
+      }
+
+      &:last-child td {
+        border-bottom: 7.5px solid #000;
+      }
+    }
+  }
+}
+
 .signatures {
   margin-top: 13px;
   display: flex;

+ 33 - 8
src/views/scene/covers/basePoints.vue

@@ -4,12 +4,19 @@
     :key="point.id"
     :pos="point.pos"
     @change-pos="pos => point.pos = pos"
-    :active="active === point"
-    @blur="() => active = active === point ? null : active"
-    @focus="() => active = point"
+    :active="customMap.activeBasePoint === point"
+    @blur="() => customMap.activeBasePoint = customMap.activeBasePoint === point ? null : customMap.activeBasePoint"
+    @focus="() => customMap.activeBasePoint = point"
   />
 
-  <ActionsPanel :menus="activeActionMenus" v-if="active" />
+<!--  <ActionsPanel :menus="activeActionMenus" v-if="active" />-->
+  <div ref="menu" @touchstart.stop class="action-menus">
+    <ActionMenus
+        v-if="customMap.activeBasePoint"
+        :menus="activeActionMenus"
+        dire="row"
+    />
+  </div>
 </template>
 
 <script setup lang="ts">
@@ -18,21 +25,39 @@ import BasePoint from './basePoint.vue'
 import {ref} from "vue";
 import {FixPoint} from "@/store/fixPoint";
 import ActionsPanel from "@/views/scene/covers/actions.vue";
+import {customMap} from "@/hook";
+import ActionMenus from "@/components/group-button/index.vue";
 
-const active = ref<BasePoint>()
 const activeActionMenus = [
   {
     key: "delete",
     icon: "del",
+    text: "删除",
     color: "#FF4D4F",
     iconColor: "#fff",
-    action() {
-      const index = basePoints.value.indexOf(active.value)
+    onClick() {
+      const index = basePoints.value.indexOf(customMap.activeBasePoint)
+      console.log(index)
       if (~index) {
         basePoints.value.splice(index, 1)
-        active.value = null
+        customMap.activeBasePoint = null
       }
     }
   }
 ]
 </script>
+
+<style scoped>
+
+.action-menus {
+  position: absolute;
+  bottom: var(--boundMargin);
+  left: 50%;
+  transform: translateX(-50%);
+  display: flex;
+  z-index: 2;
+  .menus {
+    position: static;
+  }
+}
+</style>

+ 32 - 5
src/views/scene/covers/fixPoints.vue

@@ -9,8 +9,14 @@
     @blur="() => customMap.activeFixPoint = customMap.activeFixPoint === point ? null : customMap.activeFixPoint"
   />
 
-  <div ref="menu" @touchstart.stop>
-    <ActionsPanel :menus="activeActionMenus" v-show="customMap.activeFixPoint" />
+  <div ref="menu" @touchstart.stop class="action-menus">
+<!--    <ActionsPanel :menus="activeActionMenus" v-show="customMap.activeFixPoint" />-->
+    <ActionMenus
+        v-if="customMap.activeFixPoint"
+        :menus="activeActionMenus"
+        :active-key="edit ? 'edit' : null"
+        dire="row"
+    />
   </div>
 
   <div class="edit-fix-point" v-if="edit" ref="dom"  @touchstart.stop>
@@ -42,6 +48,7 @@ import {ref, watch, watchEffect} from "vue";
 import {customMap} from '@/hook'
 import UiIcon from "@/components/base/components/icon/index.vue";
 import UiInput from "@/components/base/components/input/index.vue";
+import ActionMenus from "@/components/group-button/index.vue";
 
 const edit = ref<FixPoint>()
 const options = [
@@ -62,18 +69,20 @@ const activeActionMenus = [
   {
     key: "edit",
     icon: "edit",
+    text: "编辑",
     color: "#161A1A",
     iconColor: "#2F8FFF",
-    action() {
-      edit.value = customMap.activeFixPoint
+    onClick() {
+      edit.value = edit.value === customMap.activeFixPoint ? null : customMap.activeFixPoint
     }
   },
   {
     key: "delete",
     icon: "del",
+    text: "删除",
     color: "#FF4D4F",
     iconColor: "#fff",
-    action() {
+    onClick() {
       const index = fixPoints.value.indexOf(customMap.activeFixPoint)
       if (~index) {
         fixPoints.value.splice(index, 1)
@@ -143,4 +152,22 @@ watchEffect((onCleanup) => {
     }
   }
 }
+
+.action-menus {
+  position: absolute;
+  bottom: var(--boundMargin);
+  left: 50%;
+  transform: translateX(-50%);
+  display: flex;
+  z-index: 2;
+  .menus {
+    position: static;
+  }
+}
+</style>
+
+<style>
+.action-menus .menu.active {
+  background: none;
+}
 </style>

+ 27 - 3
src/views/scene/covers/measures.vue

@@ -8,7 +8,13 @@
       @focus="() => active = measure"
   />
 
-  <ActionsPanel :menus="activeActionMenus" v-if="active" />
+  <div ref="menu" @touchstart.stop class="action-menus">
+    <ActionMenus
+        v-if="active"
+        :menus="activeActionMenus"
+        dire="row"
+    />
+  </div>
 </template>
 
 <script setup lang="ts">
@@ -17,6 +23,8 @@ import { baseLines } from '@/store/baseLine'
 import Measure from './measure.vue'
 import {ref} from "vue";
 import ActionsPanel from "@/views/scene/covers/actions.vue";
+import {customMap} from "@/hook";
+import ActionMenus from "@/components/group-button/index.vue";
 
 const active = ref<MeasureAtom>()
 const getStore = (item: MeasureAtom) =>
@@ -29,9 +37,10 @@ const activeActionMenus = [
   {
     key: "delete",
     icon: "del",
+    text: "删除",
     color: "#FF4D4F",
     iconColor: "#fff",
-    action() {
+    onClick() {
       console.log('aa')
       const store = getStore(active.value)
       if (store) {
@@ -45,4 +54,19 @@ const activeActionMenus = [
 const changePoints = (measure, points) => {
   measure.points = points.map(point => ({...point}))
 }
-</script>
+</script>
+
+<style scoped>
+
+.action-menus {
+  position: absolute;
+  bottom: var(--boundMargin);
+  left: 50%;
+  transform: translateX(-50%);
+  display: flex;
+  z-index: 2;
+  .menus {
+    position: static;
+  }
+}
+</style>

+ 21 - 6
src/views/scene/menus/actions.ts

@@ -4,7 +4,7 @@ import {list, MeasureAtom, MeasureType} from "@/store/measure";
 import {baseLines} from '@/store/baseLine'
 import {basePoints} from "@/store/basePoint";
 import {Ref, watch} from "vue";
-import {activeFixPointStack, customMap} from "@/hook";
+import {activeBasePointStack, activeFixPointStack, customMap} from "@/hook";
 import {getCoverPos} from '../linkage/cover'
 import {Pos3D} from "@/sdk";
 import {fixPoints} from "@/store/fixPoint";
@@ -45,13 +45,21 @@ const trackMeasureMenuAction = (
   color = "#3290ff"
 ) => {
   let hide
+  let startTipEd = false
+  let endTipEd = false
   const startTip = () => {
     hide && hide()
-    hide = Message.success({ msg: "请选择一个位置单击,确定基准线的起点" })
+    if (!startTipEd) {
+      hide = Message.success({msg: `请选择一个位置单击,确定${name}的起点`})
+      startTipEd = true
+    }
   }
   const firstTip = () => {
     hide && hide()
-    hide = Message.success({ msg: "再选择一个位置单击,确定基准线的终点" })
+    if (!endTipEd) {
+      endTipEd = true
+      hide = Message.success({msg: `再选择一个位置单击,确定${name}的终点`})
+    }
   }
   startTip()
   // customMap.magnifier = true
@@ -84,11 +92,18 @@ const menuActions = {
     let hide = Message.success({ msg: "请单击选择基准点位置" })
     const onDestroy = trackPosMenuAction(
       () => {
-        hide()
-        hide = null
+        hide && hide()
         onComplete()
       },
-      pos => basePoints.value.push({ id: getId(), pos })
+      pos => {
+        const len = basePoints.value.push({ id: getId(), pos })
+        activeBasePointStack.current.value.value = basePoints.value[len - 1]
+        if (hide) {
+          hide()
+          hide = null
+        }
+      },
+      true
     )
     return () => {
       onDestroy()

+ 11 - 4
src/views/scene/menus/menus.ts

@@ -4,6 +4,9 @@ import {useSDK} from "@/hook";
 import {laserModeStack, modeDisabled} from '@/hook/custom/index'
 import {Mode} from "@/sdk";
 import {baseLines} from "@/store/baseLine";
+import {fixPoints} from "@/store/fixPoint";
+import {basePoints} from "@/store/basePoint";
+import {list} from "@/store/measure";
 
 export type MenuRaw = {
   key: string,
@@ -12,6 +15,7 @@ export type MenuRaw = {
   defaultSelect?: true | (() => boolean),
   icon?: string,
   disabled?: boolean | (() => boolean),
+  border?: boolean,
   children?: MenuRaw[],
   onClick?: () => void | (() => void)
 }
@@ -36,7 +40,9 @@ export const menus: MenuRaw[] = [
   {
     icon: "clear",
     text: "清除",
-    key: menuEnum.CLEAR
+    key: menuEnum.CLEAR,
+    disabled: () => (baseLines.value.length + fixPoints.value.length + list.value.length + basePoints.value.length) === 0,
+    border: true
   },
   {
     icon: "measure",
@@ -45,20 +51,20 @@ export const menus: MenuRaw[] = [
     children: [
       {
         icon: "line_h",
-        // continued: true,
+        continued: true,
         text: "水平",
         defaultSelect: true,
         key: menuEnum.MEASURE_ROW
       },
       {
         icon: "line_v",
-        // continued: true,
+        continued: true,
         text: "垂直",
         key: menuEnum.MEASURE_COLUMN
       },
       {
         icon: "line_f",
-        // continued: true,
+        continued: true,
         text: "自由",
         key: menuEnum.MEASURE_FREE
       }
@@ -109,6 +115,7 @@ export const menus: MenuRaw[] = [
       {
         defaultSelect: true,
         icon: "point",
+        continued: true,
         text: "基准点",
         key: menuEnum.BASE_POINT
       },

+ 7 - 4
src/views/scene/menus/pane.vue

@@ -98,24 +98,27 @@ onMounted(() => {
 }
 </style>
 
-<style>
+<style lang="scss">
 .level div:first-child {
   background-color: rgba(255, 255, 255, .3);
   height: 50px;
   width: 50px;
   min-width: 50px;
-  margin-top: -26px;
   border-radius: 50%;
   margin-bottom: 30px !important;
   position: relative;
+  i {
+    font-size: 16px !important;
+  }
 
   &:after {
     position: absolute;
     content: "";
-    width: 100%;
     height: 1px;
+    left: 10px;
+    right: 10px;
     bottom: -15px;
-    background-color: rgba(255, 255, 255, .3);
+    background-color: rgba(255, 255, 255, .2);
 
   }
 }

+ 11 - 8
src/views/scene/photo.vue

@@ -7,7 +7,8 @@
     </ButtonPane>
 
     <img
-        :src="showCoverUrl"
+        v-if="showCoverUrl"
+        :src="showCoverUrl.value"
         class="cover"
         :style="{opacity: showCoverUrl ? '1' : 0}"
         @click="router.push(writeRouteName.photos)"
@@ -27,19 +28,21 @@ import { useSDK } from '@/hook/useLaser'
 import {genUseLoading} from "@/hook";
 import {disabledMap} from "@/hook/custom";
 import {base64ToBlob, getId} from "@/utils";
-import {nextTick, ref} from "vue";
+import {computed, nextTick, ref} from "vue";
 import {api, downloadImage, uploadImage} from "@/store/sync";
 import {router, writeRouteName} from "@/router";
 import {LaserSDK, Pos, Pos3D} from "@/sdk";
+import {useStaticUrl} from "@/hook/useStaticUrl";
 
-const showCoverUrl = ref<string>()
-if (photos.value[photos.value.length - 1]?.url) {
-  api.getFile(photos.value[photos.value.length - 1]?.url)
-    .then(url => showCoverUrl.value = url)
-}
+const showCoverUrl = computed(() => {
+  if (photos.value[photos.value.length - 1]?.url) {
+    return useStaticUrl(photos.value[photos.value.length - 1].url)
+  }
+})
 
 const tempPhoto = ref<string>();
 const coverRef = ref<HTMLImageElement>()
+const audio = new Audio("/camera1.mp3")
 const getCurrentScreen = (pos: Pos3D): Pos => {
   const sdk = useSDK()
   const data = sdk.scene.getScreenByPoint(pos)
@@ -82,6 +85,7 @@ const getCurrentScreens = (poss: Array<Pos3D>): Array<Pos> =>
   poss.map(getCurrentScreen).filter(pos => !!pos);
 
 const photo = genUseLoading(async () => {
+  await audio.play();
   const sdk = useSDK()
   const data = await screenshot(sdk)
   tempPhoto.value = await api.getFile(data.rawUrl)
@@ -89,7 +93,6 @@ const photo = genUseLoading(async () => {
 
   const handler = async () => {
     coverRef.value.removeEventListener("animationend", handler)
-    showCoverUrl.value = tempPhoto.value
     tempPhoto.value = null
 
     photos.value.push({