Преглед изворни кода

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

xzw пре 2 година
родитељ
комит
f59ab9ec23
52 измењених фајлова са 2277 додато и 346 уклоњено
  1. BIN
      public/static/compass.png
  2. 1 1
      server/test/SS-t-P1d6CwREny2/attach/sceneStore
  3. 831 3
      src/components/base/components/icon/iconfont/demo_index.html
  4. 147 3
      src/components/base/components/icon/iconfont/iconfont.css
  5. 1 1
      src/components/base/components/icon/iconfont/iconfont.js
  6. 252 0
      src/components/base/components/icon/iconfont/iconfont.json
  7. BIN
      src/components/base/components/icon/iconfont/iconfont.ttf
  8. BIN
      src/components/base/components/icon/iconfont/iconfont.woff
  9. BIN
      src/components/base/components/icon/iconfont/iconfont.woff2
  10. 1 1
      src/components/base/components/input/checkbox.vue
  11. 1 1
      src/components/fill-slide/index.vue
  12. 1 0
      src/graphic/Controls/MovePoint.js
  13. 13 1
      src/graphic/Controls/UIControl.js
  14. 28 15
      src/graphic/Coordinate.js
  15. 2 0
      src/graphic/Geometry/CurveLine.js
  16. 12 0
      src/graphic/Geometry/Geometry.js
  17. 2 5
      src/graphic/Geometry/Line.js
  18. 56 14
      src/graphic/History/Change.js
  19. 167 0
      src/graphic/History/History.js
  20. 262 10
      src/graphic/History/HistoryUtil.js
  21. 33 6
      src/graphic/Layer.js
  22. 24 4
      src/graphic/ListenLayer.js
  23. 48 38
      src/graphic/Load.js
  24. 83 66
      src/graphic/Renderer/Draw.js
  25. 13 0
      src/graphic/Service/CurveRoadService.js
  26. 16 0
      src/graphic/Service/DataService.js
  27. 63 57
      src/graphic/Service/EdgeService.js
  28. 1 1
      src/graphic/Service/LineService.js
  29. 2 2
      src/graphic/Service/RoadService.js
  30. 1 0
      src/graphic/Service/StateService.js
  31. 37 3
      src/graphic/Util/MathUtil.js
  32. 2 1
      src/graphic/enum/LayerEvents.js
  33. 2 0
      src/graphic/enum/UIEvents.js
  34. 1 0
      src/hook/useParams.ts
  35. 2 2
      src/main.ts
  36. 1 1
      src/store/photos.ts
  37. 40 44
      src/store/sync.ts
  38. 5 1
      src/views/accidents/index.vue
  39. 2 2
      src/views/accidents/print.vue
  40. 1 1
      src/views/graphic/geos/arrow.vue
  41. 11 4
      src/views/graphic/header.vue
  42. 2 2
      src/views/graphic/index.vue
  43. 33 30
      src/views/graphic/menus.ts
  44. 5 1
      src/views/photos/index.vue
  45. 3 0
      src/views/roads/index.vue
  46. 35 3
      src/views/roads/tabulation.vue
  47. 3 2
      src/views/scene/container.vue
  48. 11 11
      src/views/scene/menus/menus.ts
  49. 1 1
      src/views/scene/menus/pane.vue
  50. 4 4
      src/views/scene/mode.vue
  51. 14 4
      src/views/scene/photo.vue
  52. 1 0
      vite.config.ts

BIN
public/static/compass.png


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
server/test/SS-t-P1d6CwREny2/attach/sceneStore


+ 831 - 3
src/components/base/components/icon/iconfont/demo_index.html

@@ -55,6 +55,222 @@
           <ul class="icon_lists dib-box">
           
             <li class="dib">
+              <span class="icon iconfont">&#xe740;</span>
+                <div class="name">control_a</div>
+                <div class="code-name">&amp;#xe740;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe741;</span>
+                <div class="name">control_d</div>
+                <div class="code-name">&amp;#xe741;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe742;</span>
+                <div class="name">lane_a</div>
+                <div class="code-name">&amp;#xe742;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe743;</span>
+                <div class="name">l_thick</div>
+                <div class="code-name">&amp;#xe743;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe744;</span>
+                <div class="name">l_thin</div>
+                <div class="code-name">&amp;#xe744;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe745;</span>
+                <div class="name">lane_d</div>
+                <div class="code-name">&amp;#xe745;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe735;</span>
+                <div class="name">copy</div>
+                <div class="code-name">&amp;#xe735;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe736;</span>
+                <div class="name">label</div>
+                <div class="code-name">&amp;#xe736;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe737;</span>
+                <div class="name">point_a</div>
+                <div class="code-name">&amp;#xe737;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe738;</span>
+                <div class="name">line_v</div>
+                <div class="code-name">&amp;#xe738;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe739;</span>
+                <div class="name">line_f</div>
+                <div class="code-name">&amp;#xe739;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe73a;</span>
+                <div class="name">screen_c</div>
+                <div class="code-name">&amp;#xe73a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe73b;</span>
+                <div class="name">line_h</div>
+                <div class="code-name">&amp;#xe73b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe73c;</span>
+                <div class="name">screen_f</div>
+                <div class="code-name">&amp;#xe73c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe73d;</span>
+                <div class="name">draw_s</div>
+                <div class="code-name">&amp;#xe73d;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe73e;</span>
+                <div class="name">home</div>
+                <div class="code-name">&amp;#xe73e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe73f;</span>
+                <div class="name">edit</div>
+                <div class="code-name">&amp;#xe73f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe733;</span>
+                <div class="name">arrows</div>
+                <div class="code-name">&amp;#xe733;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe734;</span>
+                <div class="name">circle</div>
+                <div class="code-name">&amp;#xe734;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe726;</span>
+                <div class="name">del</div>
+                <div class="code-name">&amp;#xe726;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe727;</span>
+                <div class="name">lock</div>
+                <div class="code-name">&amp;#xe727;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe728;</span>
+                <div class="name">recover</div>
+                <div class="code-name">&amp;#xe728;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe729;</span>
+                <div class="name">line</div>
+                <div class="code-name">&amp;#xe729;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe72a;</span>
+                <div class="name">point</div>
+                <div class="code-name">&amp;#xe72a;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe72b;</span>
+                <div class="name">panorama_f</div>
+                <div class="code-name">&amp;#xe72b;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe72c;</span>
+                <div class="name">panorama_t</div>
+                <div class="code-name">&amp;#xe72c;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe72d;</span>
+                <div class="name">point_c_t</div>
+                <div class="code-name">&amp;#xe72d;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe72e;</span>
+                <div class="name">cancel</div>
+                <div class="code-name">&amp;#xe72e;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe72f;</span>
+                <div class="name">standard</div>
+                <div class="code-name">&amp;#xe72f;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe730;</span>
+                <div class="name">affirm</div>
+                <div class="code-name">&amp;#xe730;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe731;</span>
+                <div class="name">setting</div>
+                <div class="code-name">&amp;#xe731;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe732;</span>
+                <div class="name">point_c_f</div>
+                <div class="code-name">&amp;#xe732;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe722;</span>
+                <div class="name">redo</div>
+                <div class="code-name">&amp;#xe722;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe723;</span>
+                <div class="name">backout</div>
+                <div class="code-name">&amp;#xe723;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe724;</span>
+                <div class="name">reset</div>
+                <div class="code-name">&amp;#xe724;</div>
+              </li>
+          
+            <li class="dib">
+              <span class="icon iconfont">&#xe725;</span>
+                <div class="name">map</div>
+                <div class="code-name">&amp;#xe725;</div>
+              </li>
+          
+            <li class="dib">
               <span class="icon iconfont">&#xe71d;</span>
                 <div class="name">text</div>
                 <div class="code-name">&amp;#xe71d;</div>
@@ -144,9 +360,9 @@
 <pre><code class="language-css"
 >@font-face {
   font-family: 'iconfont';
-  src: url('iconfont.woff2?t=1684996225484') format('woff2'),
-       url('iconfont.woff?t=1684996225484') format('woff'),
-       url('iconfont.ttf?t=1684996225484') format('truetype');
+  src: url('iconfont.woff2?t=1685323395791') format('woff2'),
+       url('iconfont.woff?t=1685323395791') format('woff'),
+       url('iconfont.ttf?t=1685323395791') format('truetype');
 }
 </code></pre>
           <h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
@@ -173,6 +389,330 @@
         <ul class="icon_lists dib-box">
           
           <li class="dib">
+            <span class="icon iconfont icon-control_a"></span>
+            <div class="name">
+              control_a
+            </div>
+            <div class="code-name">.icon-control_a
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-control_d"></span>
+            <div class="name">
+              control_d
+            </div>
+            <div class="code-name">.icon-control_d
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-lane_a"></span>
+            <div class="name">
+              lane_a
+            </div>
+            <div class="code-name">.icon-lane_a
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-l_thick"></span>
+            <div class="name">
+              l_thick
+            </div>
+            <div class="code-name">.icon-l_thick
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-l_thin"></span>
+            <div class="name">
+              l_thin
+            </div>
+            <div class="code-name">.icon-l_thin
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-lane_d"></span>
+            <div class="name">
+              lane_d
+            </div>
+            <div class="code-name">.icon-lane_d
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-copy"></span>
+            <div class="name">
+              copy
+            </div>
+            <div class="code-name">.icon-copy
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-label"></span>
+            <div class="name">
+              label
+            </div>
+            <div class="code-name">.icon-label
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-point_a"></span>
+            <div class="name">
+              point_a
+            </div>
+            <div class="code-name">.icon-point_a
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-line_v"></span>
+            <div class="name">
+              line_v
+            </div>
+            <div class="code-name">.icon-line_v
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-line_f"></span>
+            <div class="name">
+              line_f
+            </div>
+            <div class="code-name">.icon-line_f
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-screen_c"></span>
+            <div class="name">
+              screen_c
+            </div>
+            <div class="code-name">.icon-screen_c
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-line_h"></span>
+            <div class="name">
+              line_h
+            </div>
+            <div class="code-name">.icon-line_h
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-screen_f"></span>
+            <div class="name">
+              screen_f
+            </div>
+            <div class="code-name">.icon-screen_f
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-draw_s"></span>
+            <div class="name">
+              draw_s
+            </div>
+            <div class="code-name">.icon-draw_s
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-home"></span>
+            <div class="name">
+              home
+            </div>
+            <div class="code-name">.icon-home
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-edit"></span>
+            <div class="name">
+              edit
+            </div>
+            <div class="code-name">.icon-edit
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-arrows"></span>
+            <div class="name">
+              arrows
+            </div>
+            <div class="code-name">.icon-arrows
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-circle"></span>
+            <div class="name">
+              circle
+            </div>
+            <div class="code-name">.icon-circle
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-del"></span>
+            <div class="name">
+              del
+            </div>
+            <div class="code-name">.icon-del
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-lock"></span>
+            <div class="name">
+              lock
+            </div>
+            <div class="code-name">.icon-lock
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-recover"></span>
+            <div class="name">
+              recover
+            </div>
+            <div class="code-name">.icon-recover
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-line"></span>
+            <div class="name">
+              line
+            </div>
+            <div class="code-name">.icon-line
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-point"></span>
+            <div class="name">
+              point
+            </div>
+            <div class="code-name">.icon-point
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-panorama_f"></span>
+            <div class="name">
+              panorama_f
+            </div>
+            <div class="code-name">.icon-panorama_f
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-panorama_t"></span>
+            <div class="name">
+              panorama_t
+            </div>
+            <div class="code-name">.icon-panorama_t
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-point_c_t"></span>
+            <div class="name">
+              point_c_t
+            </div>
+            <div class="code-name">.icon-point_c_t
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-cancel"></span>
+            <div class="name">
+              cancel
+            </div>
+            <div class="code-name">.icon-cancel
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-standard"></span>
+            <div class="name">
+              standard
+            </div>
+            <div class="code-name">.icon-standard
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-affirm"></span>
+            <div class="name">
+              affirm
+            </div>
+            <div class="code-name">.icon-affirm
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-setting"></span>
+            <div class="name">
+              setting
+            </div>
+            <div class="code-name">.icon-setting
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-point_c_f"></span>
+            <div class="name">
+              point_c_f
+            </div>
+            <div class="code-name">.icon-point_c_f
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-redo"></span>
+            <div class="name">
+              redo
+            </div>
+            <div class="code-name">.icon-redo
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-backout"></span>
+            <div class="name">
+              backout
+            </div>
+            <div class="code-name">.icon-backout
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-reset"></span>
+            <div class="name">
+              reset
+            </div>
+            <div class="code-name">.icon-reset
+            </div>
+          </li>
+          
+          <li class="dib">
+            <span class="icon iconfont icon-map"></span>
+            <div class="name">
+              map
+            </div>
+            <div class="code-name">.icon-map
+            </div>
+          </li>
+          
+          <li class="dib">
             <span class="icon iconfont icon-text"></span>
             <div class="name">
               text
@@ -309,6 +849,294 @@
           
             <li class="dib">
                 <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-control_a"></use>
+                </svg>
+                <div class="name">control_a</div>
+                <div class="code-name">#icon-control_a</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-control_d"></use>
+                </svg>
+                <div class="name">control_d</div>
+                <div class="code-name">#icon-control_d</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-lane_a"></use>
+                </svg>
+                <div class="name">lane_a</div>
+                <div class="code-name">#icon-lane_a</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-l_thick"></use>
+                </svg>
+                <div class="name">l_thick</div>
+                <div class="code-name">#icon-l_thick</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-l_thin"></use>
+                </svg>
+                <div class="name">l_thin</div>
+                <div class="code-name">#icon-l_thin</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-lane_d"></use>
+                </svg>
+                <div class="name">lane_d</div>
+                <div class="code-name">#icon-lane_d</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-copy"></use>
+                </svg>
+                <div class="name">copy</div>
+                <div class="code-name">#icon-copy</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-label"></use>
+                </svg>
+                <div class="name">label</div>
+                <div class="code-name">#icon-label</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-point_a"></use>
+                </svg>
+                <div class="name">point_a</div>
+                <div class="code-name">#icon-point_a</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-line_v"></use>
+                </svg>
+                <div class="name">line_v</div>
+                <div class="code-name">#icon-line_v</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-line_f"></use>
+                </svg>
+                <div class="name">line_f</div>
+                <div class="code-name">#icon-line_f</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-screen_c"></use>
+                </svg>
+                <div class="name">screen_c</div>
+                <div class="code-name">#icon-screen_c</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-line_h"></use>
+                </svg>
+                <div class="name">line_h</div>
+                <div class="code-name">#icon-line_h</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-screen_f"></use>
+                </svg>
+                <div class="name">screen_f</div>
+                <div class="code-name">#icon-screen_f</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-draw_s"></use>
+                </svg>
+                <div class="name">draw_s</div>
+                <div class="code-name">#icon-draw_s</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-home"></use>
+                </svg>
+                <div class="name">home</div>
+                <div class="code-name">#icon-home</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-edit"></use>
+                </svg>
+                <div class="name">edit</div>
+                <div class="code-name">#icon-edit</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-arrows"></use>
+                </svg>
+                <div class="name">arrows</div>
+                <div class="code-name">#icon-arrows</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-circle"></use>
+                </svg>
+                <div class="name">circle</div>
+                <div class="code-name">#icon-circle</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-del"></use>
+                </svg>
+                <div class="name">del</div>
+                <div class="code-name">#icon-del</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-lock"></use>
+                </svg>
+                <div class="name">lock</div>
+                <div class="code-name">#icon-lock</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-recover"></use>
+                </svg>
+                <div class="name">recover</div>
+                <div class="code-name">#icon-recover</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-line"></use>
+                </svg>
+                <div class="name">line</div>
+                <div class="code-name">#icon-line</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-point"></use>
+                </svg>
+                <div class="name">point</div>
+                <div class="code-name">#icon-point</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-panorama_f"></use>
+                </svg>
+                <div class="name">panorama_f</div>
+                <div class="code-name">#icon-panorama_f</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-panorama_t"></use>
+                </svg>
+                <div class="name">panorama_t</div>
+                <div class="code-name">#icon-panorama_t</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-point_c_t"></use>
+                </svg>
+                <div class="name">point_c_t</div>
+                <div class="code-name">#icon-point_c_t</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-cancel"></use>
+                </svg>
+                <div class="name">cancel</div>
+                <div class="code-name">#icon-cancel</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-standard"></use>
+                </svg>
+                <div class="name">standard</div>
+                <div class="code-name">#icon-standard</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-affirm"></use>
+                </svg>
+                <div class="name">affirm</div>
+                <div class="code-name">#icon-affirm</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-setting"></use>
+                </svg>
+                <div class="name">setting</div>
+                <div class="code-name">#icon-setting</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-point_c_f"></use>
+                </svg>
+                <div class="name">point_c_f</div>
+                <div class="code-name">#icon-point_c_f</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-redo"></use>
+                </svg>
+                <div class="name">redo</div>
+                <div class="code-name">#icon-redo</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-backout"></use>
+                </svg>
+                <div class="name">backout</div>
+                <div class="code-name">#icon-backout</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-reset"></use>
+                </svg>
+                <div class="name">reset</div>
+                <div class="code-name">#icon-reset</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
+                  <use xlink:href="#icon-map"></use>
+                </svg>
+                <div class="name">map</div>
+                <div class="code-name">#icon-map</div>
+            </li>
+          
+            <li class="dib">
+                <svg class="icon svg-icon" aria-hidden="true">
                   <use xlink:href="#icon-text"></use>
                 </svg>
                 <div class="name">text</div>

+ 147 - 3
src/components/base/components/icon/iconfont/iconfont.css

@@ -1,8 +1,8 @@
 @font-face {
   font-family: "iconfont"; /* Project id 4084834 */
-  src: url('iconfont.woff2?t=1684996225484') format('woff2'),
-       url('iconfont.woff?t=1684996225484') format('woff'),
-       url('iconfont.ttf?t=1684996225484') format('truetype');
+  src: url('iconfont.woff2?t=1685323395791') format('woff2'),
+       url('iconfont.woff?t=1685323395791') format('woff'),
+       url('iconfont.ttf?t=1685323395791') format('truetype');
 }
 
 .iconfont {
@@ -13,6 +13,150 @@
   -moz-osx-font-smoothing: grayscale;
 }
 
+.icon-control_a:before {
+  content: "\e740";
+}
+
+.icon-control_d:before {
+  content: "\e741";
+}
+
+.icon-lane_a:before {
+  content: "\e742";
+}
+
+.icon-l_thick:before {
+  content: "\e743";
+}
+
+.icon-l_thin:before {
+  content: "\e744";
+}
+
+.icon-lane_d:before {
+  content: "\e745";
+}
+
+.icon-copy:before {
+  content: "\e735";
+}
+
+.icon-label:before {
+  content: "\e736";
+}
+
+.icon-point_a:before {
+  content: "\e737";
+}
+
+.icon-line_v:before {
+  content: "\e738";
+}
+
+.icon-line_f:before {
+  content: "\e739";
+}
+
+.icon-screen_c:before {
+  content: "\e73a";
+}
+
+.icon-line_h:before {
+  content: "\e73b";
+}
+
+.icon-screen_f:before {
+  content: "\e73c";
+}
+
+.icon-draw_s:before {
+  content: "\e73d";
+}
+
+.icon-home:before {
+  content: "\e73e";
+}
+
+.icon-edit:before {
+  content: "\e73f";
+}
+
+.icon-arrows:before {
+  content: "\e733";
+}
+
+.icon-circle:before {
+  content: "\e734";
+}
+
+.icon-del:before {
+  content: "\e726";
+}
+
+.icon-lock:before {
+  content: "\e727";
+}
+
+.icon-recover:before {
+  content: "\e728";
+}
+
+.icon-line:before {
+  content: "\e729";
+}
+
+.icon-point:before {
+  content: "\e72a";
+}
+
+.icon-panorama_f:before {
+  content: "\e72b";
+}
+
+.icon-panorama_t:before {
+  content: "\e72c";
+}
+
+.icon-point_c_t:before {
+  content: "\e72d";
+}
+
+.icon-cancel:before {
+  content: "\e72e";
+}
+
+.icon-standard:before {
+  content: "\e72f";
+}
+
+.icon-affirm:before {
+  content: "\e730";
+}
+
+.icon-setting:before {
+  content: "\e731";
+}
+
+.icon-point_c_f:before {
+  content: "\e732";
+}
+
+.icon-redo:before {
+  content: "\e722";
+}
+
+.icon-backout:before {
+  content: "\e723";
+}
+
+.icon-reset:before {
+  content: "\e724";
+}
+
+.icon-map:before {
+  content: "\e725";
+}
+
 .icon-text:before {
   content: "\e71d";
 }

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
src/components/base/components/icon/iconfont/iconfont.js


+ 252 - 0
src/components/base/components/icon/iconfont/iconfont.json

@@ -6,6 +6,258 @@
   "description": "交通事故现场勘验系统",
   "glyphs": [
     {
+      "icon_id": "35710135",
+      "name": "control_a",
+      "font_class": "control_a",
+      "unicode": "e740",
+      "unicode_decimal": 59200
+    },
+    {
+      "icon_id": "35710136",
+      "name": "control_d",
+      "font_class": "control_d",
+      "unicode": "e741",
+      "unicode_decimal": 59201
+    },
+    {
+      "icon_id": "35710137",
+      "name": "lane_a",
+      "font_class": "lane_a",
+      "unicode": "e742",
+      "unicode_decimal": 59202
+    },
+    {
+      "icon_id": "35710138",
+      "name": "l_thick",
+      "font_class": "l_thick",
+      "unicode": "e743",
+      "unicode_decimal": 59203
+    },
+    {
+      "icon_id": "35710139",
+      "name": "l_thin",
+      "font_class": "l_thin",
+      "unicode": "e744",
+      "unicode_decimal": 59204
+    },
+    {
+      "icon_id": "35710140",
+      "name": "lane_d",
+      "font_class": "lane_d",
+      "unicode": "e745",
+      "unicode_decimal": 59205
+    },
+    {
+      "icon_id": "35709605",
+      "name": "copy",
+      "font_class": "copy",
+      "unicode": "e735",
+      "unicode_decimal": 59189
+    },
+    {
+      "icon_id": "35709606",
+      "name": "label",
+      "font_class": "label",
+      "unicode": "e736",
+      "unicode_decimal": 59190
+    },
+    {
+      "icon_id": "35709607",
+      "name": "point_a",
+      "font_class": "point_a",
+      "unicode": "e737",
+      "unicode_decimal": 59191
+    },
+    {
+      "icon_id": "35709608",
+      "name": "line_v",
+      "font_class": "line_v",
+      "unicode": "e738",
+      "unicode_decimal": 59192
+    },
+    {
+      "icon_id": "35709609",
+      "name": "line_f",
+      "font_class": "line_f",
+      "unicode": "e739",
+      "unicode_decimal": 59193
+    },
+    {
+      "icon_id": "35709610",
+      "name": "screen_c",
+      "font_class": "screen_c",
+      "unicode": "e73a",
+      "unicode_decimal": 59194
+    },
+    {
+      "icon_id": "35709611",
+      "name": "line_h",
+      "font_class": "line_h",
+      "unicode": "e73b",
+      "unicode_decimal": 59195
+    },
+    {
+      "icon_id": "35709612",
+      "name": "screen_f",
+      "font_class": "screen_f",
+      "unicode": "e73c",
+      "unicode_decimal": 59196
+    },
+    {
+      "icon_id": "35709613",
+      "name": "draw_s",
+      "font_class": "draw_s",
+      "unicode": "e73d",
+      "unicode_decimal": 59197
+    },
+    {
+      "icon_id": "35709614",
+      "name": "home",
+      "font_class": "home",
+      "unicode": "e73e",
+      "unicode_decimal": 59198
+    },
+    {
+      "icon_id": "35709615",
+      "name": "edit",
+      "font_class": "edit",
+      "unicode": "e73f",
+      "unicode_decimal": 59199
+    },
+    {
+      "icon_id": "35695033",
+      "name": "arrows",
+      "font_class": "arrows",
+      "unicode": "e733",
+      "unicode_decimal": 59187
+    },
+    {
+      "icon_id": "35695034",
+      "name": "circle",
+      "font_class": "circle",
+      "unicode": "e734",
+      "unicode_decimal": 59188
+    },
+    {
+      "icon_id": "35694805",
+      "name": "del",
+      "font_class": "del",
+      "unicode": "e726",
+      "unicode_decimal": 59174
+    },
+    {
+      "icon_id": "35694807",
+      "name": "lock",
+      "font_class": "lock",
+      "unicode": "e727",
+      "unicode_decimal": 59175
+    },
+    {
+      "icon_id": "35694808",
+      "name": "recover",
+      "font_class": "recover",
+      "unicode": "e728",
+      "unicode_decimal": 59176
+    },
+    {
+      "icon_id": "35694809",
+      "name": "line",
+      "font_class": "line",
+      "unicode": "e729",
+      "unicode_decimal": 59177
+    },
+    {
+      "icon_id": "35694810",
+      "name": "point",
+      "font_class": "point",
+      "unicode": "e72a",
+      "unicode_decimal": 59178
+    },
+    {
+      "icon_id": "35694811",
+      "name": "panorama_f",
+      "font_class": "panorama_f",
+      "unicode": "e72b",
+      "unicode_decimal": 59179
+    },
+    {
+      "icon_id": "35694812",
+      "name": "panorama_t",
+      "font_class": "panorama_t",
+      "unicode": "e72c",
+      "unicode_decimal": 59180
+    },
+    {
+      "icon_id": "35694813",
+      "name": "point_c_t",
+      "font_class": "point_c_t",
+      "unicode": "e72d",
+      "unicode_decimal": 59181
+    },
+    {
+      "icon_id": "35694814",
+      "name": "cancel",
+      "font_class": "cancel",
+      "unicode": "e72e",
+      "unicode_decimal": 59182
+    },
+    {
+      "icon_id": "35694815",
+      "name": "standard",
+      "font_class": "standard",
+      "unicode": "e72f",
+      "unicode_decimal": 59183
+    },
+    {
+      "icon_id": "35694816",
+      "name": "affirm",
+      "font_class": "affirm",
+      "unicode": "e730",
+      "unicode_decimal": 59184
+    },
+    {
+      "icon_id": "35694817",
+      "name": "setting",
+      "font_class": "setting",
+      "unicode": "e731",
+      "unicode_decimal": 59185
+    },
+    {
+      "icon_id": "35694818",
+      "name": "point_c_f",
+      "font_class": "point_c_f",
+      "unicode": "e732",
+      "unicode_decimal": 59186
+    },
+    {
+      "icon_id": "35690775",
+      "name": "redo",
+      "font_class": "redo",
+      "unicode": "e722",
+      "unicode_decimal": 59170
+    },
+    {
+      "icon_id": "35690776",
+      "name": "backout",
+      "font_class": "backout",
+      "unicode": "e723",
+      "unicode_decimal": 59171
+    },
+    {
+      "icon_id": "35690777",
+      "name": "reset",
+      "font_class": "reset",
+      "unicode": "e724",
+      "unicode_decimal": 59172
+    },
+    {
+      "icon_id": "35690778",
+      "name": "map",
+      "font_class": "map",
+      "unicode": "e725",
+      "unicode_decimal": 59173
+    },
+    {
       "icon_id": "35676724",
       "name": "text",
       "font_class": "text",

BIN
src/components/base/components/icon/iconfont/iconfont.ttf


BIN
src/components/base/components/icon/iconfont/iconfont.woff


BIN
src/components/base/components/icon/iconfont/iconfont.woff2


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

@@ -2,7 +2,7 @@
     <div class="input checkbox" :style="{ width, height }">
         <input :id="id" type="checkbox" class="replace-input" :checked="props.modelValue" @input="ev => emit('update:modelValue', ev.target.checked)" />
         <span class="replace" :class="{checked: props.modelValue}">
-            <icon type="checkbox" :size="width > height ? height : width" />
+            <icon type="affirm" :size="width > height ? height : width" />
         </span>
     </div>
     <label class="label" v-if="props.label" :for="id">

+ 1 - 1
src/components/fill-slide/index.vue

@@ -70,7 +70,7 @@ const clickHandler = () => {
 .image {
   width: 100%;
   height: 100%;
-  object-fit: cover;
+  object-fit: contain;
   border-radius: 4px;
 }
 

+ 1 - 0
src/graphic/Controls/MovePoint.js

@@ -22,6 +22,7 @@ export default class MovePoint {
       let parent = point.getParent();
       for (let key in parent) {
         let line = dataService.getLine(key);
+        line.setValue(null);
         //拖拽的点是基准线
         if (line.category == VectorCategory.Line.BaseLine) {
           let points = dataService.getPoints();

+ 13 - 1
src/graphic/Controls/UIControl.js

@@ -83,6 +83,8 @@ export default class UIControl {
           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)) {
           stateService.setEventName(LayerEvents.AddPoint);
         } else if (selectUI == UIEvents.Circle) {
@@ -135,6 +137,8 @@ export default class UIControl {
           Settings.baseLineId = null;
         }
         break;
+      case VectorType.CurveLine:
+        break;
       case VectorType.Circle:
         dataService.deleteCircle(vectorId);
         break;
@@ -145,6 +149,10 @@ export default class UIControl {
         dataService.deleteMagnifier(vectorId);
         break;
     }
+    this.layer.exit();
+    uiService.setLineCategory(VectorCategory.Line.NormalLine);
+    uiService.setPointCategory(VectorCategory.Point.NormalPoint);
+    this.focusVector = null;
   }
 
   //复制按钮
@@ -153,6 +161,8 @@ export default class UIControl {
       case VectorType.Line:
         lineService.copy(vectorId);
         break;
+      case VectorType.CurveLine:
+        break;
       case VectorType.Circle:
         circleService.copy(vectorId);
         break;
@@ -292,7 +302,9 @@ export default class UIControl {
   /******************************************************************************************************************************************************************/
 
   prompt(msg) {
-    this._prompts.push(Message.success({ msg }));
+    this._prompts.push(
+      Message.success(typeof msg === "string" ? { msg } : msg)
+    );
   }
 
   // 进入持续添加出确认与取消框

+ 28 - 15
src/graphic/Coordinate.js

@@ -42,8 +42,8 @@ export default class Coordinate {
     let y =
       this.height / 2 - ((pt.y - this.center.y) * this.zoom) / defaultZoom;
 
-    x *= this.ratio;
-    y *= this.ratio;
+    // x *= this.ratio;
+    // y *= this.ratio;
 
     x = (0.5 + x) << 0;
     y = (0.5 + y) << 0;
@@ -57,10 +57,12 @@ export default class Coordinate {
   getXYFromScreen(screenPoint) {
     const point = {};
     point.x =
-      ((screenPoint.x - this.width / 2) * defaultZoom) / this.zoom +
+      ((screenPoint.x * this.ratio - this.width / 2) * defaultZoom) /
+        this.zoom +
       this.center.x;
     point.y =
-      ((this.height / 2 - screenPoint.y) * defaultZoom) / this.zoom +
+      ((this.height / 2 - screenPoint.y * this.ratio) * defaultZoom) /
+        this.zoom +
       this.center.y;
     return point;
   }
@@ -82,13 +84,22 @@ export default class Coordinate {
 
   updateForCanvas(canvas) {
     if (canvas) {
-      console.log(canvas.offsetWidth, canvas.offsetHeight)
+      console.log(canvas.offsetWidth, canvas.offsetHeight);
       canvas.width = canvas.offsetWidth * this.ratio;
       canvas.height = canvas.offsetHeight * this.ratio;
       this.width = canvas.width;
       this.height = canvas.height;
     }
     this.setCenter(canvas);
+    console.log(
+      "updateForCanvas" +
+        canvas.offsetWidth +
+        "," +
+        canvas.offsetHeight +
+        "," +
+        this.ratio +
+        JSON.stringify(this.center)
+    );
   }
 
   updateZoom(screenPosition, zoom) {
@@ -96,21 +107,23 @@ export default class Coordinate {
     this.zoom = zoom;
     this.center.x =
       position.x -
-      ((screenPosition.x - this.width / 2) * defaultZoom) / this.zoom;
+      ((screenPosition.x * this.ratio - this.width / 2) * defaultZoom) /
+        this.zoom;
 
     this.center.y =
       position.y -
-      ((this.height / 2 - screenPosition.y) * defaultZoom) / this.zoom;
+      ((this.height / 2 - screenPosition.y * this.ratio) * defaultZoom) /
+        this.zoom;
   }
 
-  moveTo(zoom, screenPosition) {
-    const position = this.getXYFromScreen(screenPosition);
-    this.zoom = zoom;
-    const dx = (screenPosition.x * defaultZoom) / this.zoom - this.width / 2;
-    const dy = this.height / 2 - (screenPosition.y * defaultZoom) / this.zoom;
-    this.center.x = position.x - dx;
-    this.center.y = position.y - dy;
-  }
+  // moveTo(zoom, screenPosition) {
+  //   const position = this.getXYFromScreen(screenPosition);
+  //   this.zoom = zoom;
+  //   const dx = (screenPosition.x * defaultZoom) / this.zoom - this.width / 2;
+  //   const dy = this.height / 2 - (screenPosition.y * defaultZoom) / this.zoom;
+  //   this.center.x = position.x - dx;
+  //   this.center.y = position.y - dy;
+  // }
 
   getPixelRatio(context) {
     var backingStore =

+ 2 - 0
src/graphic/Geometry/CurveLine.js

@@ -6,6 +6,8 @@ import Constant from "../Constant.js";
 export default class CurveLine extends Geometry {
   constructor(points, vectorId) {
     super();
+    this.startId = startId;
+    this.endId = endId;
     this.points = points;
     this.geoType = VectorType.CurveLine;
     this.setId(vectorId);

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

@@ -52,6 +52,14 @@ export default class Geometry {
     return this.parent;
   }
 
+  setValue(value) {
+    this.value = value;
+  }
+
+  getValue() {
+    return this.value;
+  }
+
   setCenter(center) {
     if (center) {
       this.center = {};
@@ -68,6 +76,10 @@ export default class Geometry {
     this.color = value;
   }
 
+  getColor() {
+    return this.color;
+  }
+
   // ptSrc: 圆上某点(初始点);
   // ptRotationCenter: 圆心点;
   // angle: 旋转角度°  -- [angle * M_PI / 180]:将角度换算为弧度

+ 2 - 5
src/graphic/Geometry/Line.js

@@ -12,7 +12,8 @@ export default class Line extends Geometry {
     this.startId = startId;
     this.endId = endId;
     this.category = Settings.lineCategory;
-    this.arrowColor = Style.ArrowLine.strokeStyle; //箭头类型会用到
+    this.color = Style.ArrowLine.strokeStyle; //箭头类型会用到
+    this.value = null; //测量线会用到
     this.geoType = VectorType.Line;
     this.setId(vectorId);
   }
@@ -30,10 +31,6 @@ export default class Line extends Geometry {
     return this.category;
   }
 
-  setArrowColor(value) {
-    this.arrowColor = value;
-  }
-
   getDir(pointId) {
     if (this.startId == pointId) {
       return "start";

+ 56 - 14
src/graphic/History/Change.js

@@ -61,9 +61,9 @@ export default class Change {
     this.compareRoadPoints();
     this.compareRoadEdges();
     this.compareRoads();
-    // this.compareCurveRoadPoints();
-    // this.compareCurveRoadEdges();
-    // this.compareCurveRoads();
+    this.compareCurveRoadPoints();
+    this.compareCurveRoadEdges();
+    this.compareCurveRoads();
     this.compareCrossPoints();
     if (
       this.currentData.points.length == 0 &&
@@ -74,9 +74,9 @@ export default class Change {
       this.currentData.roadPoints.length == 0 &&
       this.currentData.roadEdges.length == 0 &&
       this.currentData.roads.length == 0 &&
-      // this.currentData.curveRoadPoints.length == 0 &&
-      // this.currentData.curveRoadEdges.length == 0 &&
-      // this.currentData.curveRoads.length == 0 &&
+      this.currentData.curveRoadPoints.length == 0 &&
+      this.currentData.curveRoadEdges.length == 0 &&
+      this.currentData.curveRoads.length == 0 &&
       this.currentData.crossPoints.length == 0
     ) {
       this.saveCurrentInfo();
@@ -498,12 +498,12 @@ export default class Change {
       if (!lastCurveRoadPoint) {
         const item = {
           handle: HistoryEvents.AddCurveRoadPoint,
-          curveRoadPoint: historyUtil.getDataForRoadPoint(curveRoadPoint),
+          curveRoadPoint: historyUtil.getDataForCurveRoadPoint(curveRoadPoint),
         };
         this.currentData.curveRoadPoints.push(item);
       } else {
         if (
-          !historyUtil.isDifferentForRoadPoints(
+          !historyUtil.isDifferentForCurveRoadPoints(
             curveRoadPoint,
             lastCurveRoadPoint
           )
@@ -512,9 +512,11 @@ export default class Change {
           continue;
         } else {
           const item = {
-            handle: HistoryEvents.ModifyRoadPoint,
-            preRoadPoint: historyUtil.getDataForRoadPoint(lastCurveRoadPoint),
-            curRoadPoint: historyUtil.getDataForRoadPoint(curveRoadPoint),
+            handle: HistoryEvents.ModifyCurveRoadPoint,
+            preCurveRoadPoint:
+              historyUtil.getDataForCurveRoadPoint(lastCurveRoadPoint),
+            curCurveRoadPoint:
+              historyUtil.getDataForCurveRoadPoint(curveRoadPoint),
           };
           this.currentData.curveRoadPoints.push(item);
         }
@@ -524,8 +526,8 @@ export default class Change {
 
     for (const key in this.lastData.curveRoadPoints) {
       const item = {
-        handle: HistoryEvents.DeleteRoadPoint,
-        curveRoadPoint: historyUtil.getDataForRoadPoint(
+        handle: HistoryEvents.DeleteCurveRoadPoint,
+        curveRoadPoint: historyUtil.getDataForCurveRoadPoint(
           this.lastData.curveRoadPoints[key]
         ),
       };
@@ -533,7 +535,47 @@ export default class Change {
     }
   }
 
-  compareCurveRoads() {}
+  compareCurveRoads() {
+    this.currentData.curveRoads = [];
+    const curveRoads = dataService.getCurveRoads();
+
+    for (const key in curveRoads) {
+      const curveRoad = curveRoads[key];
+      const lastCurveRoad = this.lastData.curveRoads[key];
+
+      // 不存在意味着增加
+      if (!lastCurveRoad) {
+        const item = {
+          handle: HistoryEvents.AddCurveRoad,
+          curveRoad: historyUtil.getDataForCurveRoad(curveRoad),
+        };
+        this.currentData.curveRoads.push(item);
+      } else {
+        if (!historyUtil.isDifferentForCurveRoads(curveRoad, lastCurveRoad)) {
+          delete this.lastData.curveRoads[key];
+          continue;
+        } else {
+          const item = {
+            handle: HistoryEvents.ModifyCurveRoad,
+            preCurveRoad: historyUtil.getDataForCurveRoad(lastCurveRoad),
+            curCurveRoad: historyUtil.getDataForCurveRoad(curveRoad),
+          };
+          this.currentData.curveRoads.push(item);
+        }
+      }
+      delete this.lastData.curveRoads[key];
+    }
+
+    for (const key in this.lastData.curveRoads) {
+      const item = {
+        handle: HistoryEvents.DeleteCurveRoad,
+        curveRoad: historyUtil.getDataForCurveRoad(
+          this.lastData.curveRoads[key]
+        ),
+      };
+      this.currentData.curveRoads.push(item);
+    }
+  }
 
   compareCurveRoadEdges() {
     this.currentData.curveRoadEdges = [];

+ 167 - 0
src/graphic/History/History.js

@@ -14,6 +14,9 @@ import { pointService } from "../Service/PointService";
 import { edgeService } from "../Service/EdgeService";
 import { magnifierService } from "../Service/MagnifierService";
 import { crossPointService } from "../Service/CrossPointService";
+import { curveRoadPointService } from "../Service/CurveRoadPointService";
+import { curveEdgeService } from "../Service/CurveEdgeService";
+import { curveRoadService } from "../Service/CurveRoadService";
 
 export default class History {
   constructor(layer) {
@@ -104,6 +107,9 @@ export default class History {
       this.goPreForRoadPoints(item.roadPoints);
       this.goPreForRoadEdges(item.roadEdges);
       this.goPreForRoads(item.roads);
+      this.goPreForCurveRoadPoints(item.curveRoadPoints);
+      this.goPreForCurveRoadEdges(item.curveRoadEdges);
+      this.goPreForCurveRoads(item.curveRoads);
       this.goPreForCrossPoints(item.crossPoints);
       historyService.undoHistoryRecord();
       change.saveCurrentInfo();
@@ -290,6 +296,85 @@ export default class History {
     }
   }
 
+  goPreForCurveRoadPoints(itemForCurveRoadPoints) {
+    for (let i = 0; i < itemForCurveRoadPoints.length; ++i) {
+      const item = itemForCurveRoadPoints[i];
+      if (item.handle == HistoryEvents.AddCurveRoadPoint) {
+        dataService.deleteCurveRoadPoint(item.curveRoadPoint.id);
+      } else if (item.handle == HistoryEvents.DeleteCurveRoadPoint) {
+        let newCurveRoadPoint = curveRoadPointService.create(
+          item.curveRoadPoint.position,
+          item.curveRoadPoint.id
+        );
+        historyUtil.assignCurveRoadPointFromCurveRoadPoint(
+          newCurveRoadPoint,
+          item.curveRoadPoint
+        );
+      } else if (item.handle == HistoryEvents.ModifyCurveRoadPoint) {
+        const preCurveRoadPoint = item.preCurveRoadPoint;
+        let currentCurveRoadPoint = dataService.getCurveRoadPoint(
+          item.curCurveRoadPoint.id
+        );
+        historyUtil.assignCurveRoadPointFromCurveRoadPoint(
+          currentCurveRoadPoint,
+          preCurveRoadPoint
+        );
+      }
+    }
+  }
+
+  goPreForCurveRoadEdges(itemForCurveRoadEdges) {
+    for (let i = 0; i < itemForCurveRoadEdges.length; ++i) {
+      const item = itemForCurveRoadEdges[i];
+      if (item.handle == HistoryEvents.AddCurveRoadEdge) {
+        dataService.deleteCurveRoadEdge(item.curveRoadEdge.id);
+      } else if (item.handle == HistoryEvents.DeleteCurveRoadEdge) {
+        let newCurveRoadEdge = curveEdgeService.create(
+          item.curveRoadEdge.start,
+          item.curveRoadEdge.end,
+          item.curveRoadEdge.id,
+          item.curveRoadEdge.parent
+        );
+        historyUtil.assignCurveRoadEdgeFromCurveRoadEdge(
+          newCurveRoadEdge,
+          item.curveRoadEdge
+        );
+      } else if (item.handle == HistoryEvents.ModifyCurveRoadEdge) {
+        const preCurveRoadEdge = item.preCurveRoadEdge;
+        let currentCurveRoadEdge = dataService.getCurveRoadEdge(
+          item.curCurveRoadEdge.id
+        );
+        historyUtil.assignCurveRoadEdgeFromCurveRoadEdge(
+          currentCurveRoadEdge,
+          preCurveRoadEdge
+        );
+      }
+    }
+  }
+
+  goPreForCurveRoads(itemForCurveRoads) {
+    for (let i = 0; i < itemForCurveRoads.length; ++i) {
+      const item = itemForCurveRoads[i];
+      if (item.handle == HistoryEvents.AddCurveRoad) {
+        dataService.deleteCurveRoad(item.curveRoad.id);
+      } else if (item.handle == HistoryEvents.DeleteCurveRoad) {
+        let newCurveRoad = curveRoadService.createOnlyCurveRoad(
+          item.curveRoad.startId,
+          item.curveRoad.endId,
+          item.curveRoad.id
+        );
+        historyUtil.assignCurveRoadFromCurveRoad(newCurveRoad, item.curveRoad);
+      } else if (item.handle == HistoryEvents.ModifyCurveRoad) {
+        const preCurveRoad = item.preCurveRoad;
+        let currentCurveRoad = dataService.getCurveRoad(item.curCurveRoad.id);
+        historyUtil.assignCurveRoadFromCurveRoad(
+          currentCurveRoad,
+          preCurveRoad
+        );
+      }
+    }
+  }
+
   goPreForCrossPoints(itemForCrossPoints) {
     for (let i = 0; i < itemForCrossPoints.length; ++i) {
       const item = itemForCrossPoints[i];
@@ -494,6 +579,85 @@ export default class History {
     }
   }
 
+  goNextForCurveRoadPoints(itemForCurveRoadPoints) {
+    for (let i = 0; i < itemForCurveRoadPoints.length; ++i) {
+      const item = itemForCurveRoadPoints[i];
+      if (item.handle == HistoryEvents.AddCurveRoadPoint) {
+        let vCurveRoadPoint = curveRoadPointService.create(
+          item.curveRoadPoint.position,
+          item.curveRoadPoint.id
+        );
+        historyUtil.assignCurveRoadPointFromCurveRoadPoint(
+          vCurveRoadPoint,
+          item.curveRoadPoint
+        );
+      } else if (item.handle == HistoryEvents.DeleteCurveRoadPoint) {
+        dataService.deleteCurveRoadPoint(item.curveRoadPoint.id);
+      } else if (item.handle == HistoryEvents.ModifyCurveRoadPoint) {
+        const currentCurveRoadPoint = item.curCurveRoadPoint;
+        let preCurveRoadPoint = dataService.getCurveRoadPoint(
+          item.curCurveRoadPoint.id
+        );
+        historyUtil.assignCurveRoadPointFromCurveRoadPoint(
+          preCurveRoadPoint,
+          currentCurveRoadPoint
+        );
+      }
+    }
+  }
+
+  goNextForCurveRoadEdges(itemForCurveRoadEdges) {
+    for (let i = 0; i < itemForCurveRoadEdges.length; ++i) {
+      const item = itemForCurveRoadEdges[i];
+      if (item.handle == HistoryEvents.AddCurveRoadEdge) {
+        let vCurveRoadEdge = curveEdgeService.create(
+          item.curveRoadEdge.start,
+          item.curveRoadEdge.end,
+          item.curveRoadEdge.id,
+          item.curveRoadEdge.parent
+        );
+        historyUtil.assignCurveRoadEdgeFromCurveRoadEdge(
+          vCurveRoadEdge,
+          item.curveRoadEdge
+        );
+      } else if (item.handle == HistoryEvents.DeleteCurveRoadEdge) {
+        dataService.deleteCurveRoadEdge(item.curveRoadEdge.id);
+      } else if (item.handle == HistoryEvents.ModifyCurveRoadEdge) {
+        const currentRoadEdge = item.curCurveRoadEdge;
+        let preRoadEdge = dataService.getCurveRoadEdge(
+          item.curCurveRoadEdge.id
+        );
+        historyUtil.assignCurveRoadEdgeFromCurveRoadEdge(
+          preRoadEdge,
+          currentRoadEdge
+        );
+      }
+    }
+  }
+
+  goNextForCurveRoads(itemForCurveRoads) {
+    for (let i = 0; i < itemForCurveRoads.length; ++i) {
+      const item = itemForCurveRoads[i];
+      if (item.handle == HistoryEvents.AddCurveRoad) {
+        let vCurveRoad = curveRoadService.createOnlyCurveRoad(
+          item.curveRoad.startId,
+          item.curveRoad.endId,
+          item.curveRoad.id
+        );
+        historyUtil.assignCurveRoadFromCurveRoad(vCurveRoad, item.curveRoad);
+      } else if (item.handle == HistoryEvents.DeleteCurveRoad) {
+        dataService.deleteCurveRoad(item.curveRoad.id);
+      } else if (item.handle == HistoryEvents.ModifyCurveRoad) {
+        const currentCurveRoad = item.curCurveRoad;
+        let preCurveRoad = dataService.getCurveRoad(item.curCurveRoad.id);
+        historyUtil.assignCurveRoadFromCurveRoad(
+          preCurveRoad,
+          currentCurveRoad
+        );
+      }
+    }
+  }
+
   goNextForCrossPoints(itemForCrossPoints) {
     for (let i = 0; i < itemForCrossPoints.length; ++i) {
       const item = itemForCrossPoints[i];
@@ -535,6 +699,9 @@ export default class History {
       this.goNextForRoadPoints(item.roadPoints);
       this.goNextForRoadEdges(item.roadEdges);
       this.goNextForRoads(item.roads);
+      this.goNextForCurveRoadPoints(item.curveRoadPoints);
+      this.goNextForCurveRoadEdges(item.curveRoadEdges);
+      this.goNextForCurveRoads(item.curveRoads);
       this.goNextForCrossPoints(item.crossPoints);
       change.saveCurrentInfo();
       this.setState();

+ 262 - 10
src/graphic/History/HistoryUtil.js

@@ -6,19 +6,11 @@ import Constant from "../Constant";
 export default class HistoryUtil {
   constructor() {}
 
-  isDifferentForRoads(road1, road2) {
-    if (road1.startId == road2.startId && road1.endId == road2.endId) {
-      return false;
-    } else {
-      return true;
-    }
-  }
-
   isDifferentForPoints(point1, point2) {
     if (
       point1.x == point2.x &&
       point1.y == point2.y &&
-      JSON.stringify(point1.parent) == JSON.stringify(point2.parent) &&
+      mathUtil.equalJSON(point1.parent, point1.parent) &&
       point1.category == point2.category &&
       point1.locationMode == point2.locationMode &&
       point1.linkedBasePointId == point2.linkedBasePointId &&
@@ -90,7 +82,7 @@ export default class HistoryUtil {
   isDifferentForRoadPoints(roadPoint1, roadPoint2) {
     if (
       mathUtil.equalPoint(roadPoint1, roadPoint2) &&
-      JSON.stringify(roadPoint1.parent) == JSON.stringify(roadPoint2.parent)
+      mathUtil.equalJSON(roadPoint1.parent, roadPoint2.parent)
     ) {
       return false;
     } else {
@@ -147,6 +139,71 @@ export default class HistoryUtil {
     }
   }
 
+  isDifferentForCurveRoadPoints(curveRoadPoint1, curveRoadPoint2) {
+    if (
+      mathUtil.equalPoint(curveRoadPoint1, curveRoadPoint2) &&
+      mathUtil.equalJSON(curveRoadPoint1.parent, curveRoadPoint2.parent) &&
+      curveRoadPoint1.index == curveRoadPoint2.index
+    ) {
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  isDifferentForCurveRoadEdges(curveRoadEdge1, curveRoadEdge2) {
+    if (
+      mathUtil.equalPoint(curveRoadEdge1.start, curveRoadEdge2.start) &&
+      mathUtil.equalPoint(curveRoadEdge1.end, curveRoadEdge2.end) &&
+      mathUtil.equalPoints(curveRoadEdge1.points, curveRoadEdge2.points) &&
+      curveRoadEdge1.parent == curveRoadEdge2.parent
+    ) {
+      return false;
+    } else {
+      return true;
+    }
+  }
+
+  isDifferentForCurveRoads(curveRoad1, curveRoad2) {
+    if (
+      curveRoad1.startId == curveRoad2.startId &&
+      curveRoad1.endId == curveRoad2.endId &&
+      mathUtil.equalPoints(curveRoad1.points, curveRoad2.points) &&
+      curveRoad1.leftEdgeId == curveRoad2.leftEdgeId &&
+      curveRoad1.rightEdgeId == curveRoad2.rightEdgeId &&
+      curveRoad1.way == curveRoad2.way
+    ) {
+      if (curveRoad1.way == Constant.oneWay) {
+        if (
+          curveRoad1.singleRoadWidth == curveRoad2.singleRoadWidth &&
+          curveRoad1.singleRoadDrivewayCount ==
+            curveRoad2.singleRoadDrivewayCount
+        ) {
+          return false;
+        } else {
+          return true;
+        }
+      } else if (curveRoad1.way == Constant.twoWay) {
+        if (
+          curveRoad1.leftWidth == curveRoad2.leftWidth &&
+          curveRoad1.rightWidth == curveRoad2.rightWidth &&
+          curveRoad1.leftDrivewayCount == curveRoad2.leftDrivewayCount &&
+          curveRoad1.rightDrivewayCount == curveRoad2.rightDrivewayCount &&
+          curveRoad1.midDivide.midDivideWidth ==
+            curveRoad2.midDivide.midDivideWidth
+        ) {
+          return false;
+        } else {
+          return true;
+        }
+      } else {
+        return true;
+      }
+    } else {
+      return true;
+    }
+  }
+
   isDifferentForCrossPoints(crossPoint1, crossPoint2) {
     if (
       mathUtil.equalPoint(crossPoint1, crossPoint2) &&
@@ -180,6 +237,7 @@ export default class HistoryUtil {
     lineInfo.start = line2.start;
     lineInfo.end = line2.end;
     lineInfo.category = line2.category;
+    lineInfo.value = line2.value;
     this.setLineInfo(lineInfo);
   }
 
@@ -264,6 +322,81 @@ export default class HistoryUtil {
     this.setRoadInfo(roadInfo);
   }
 
+  assignCurveRoadPointFromCurveRoadPoint(curveRoadPoint1, curveRoadPoint2) {
+    const curveRoadPointInfo = {};
+    curveRoadPointInfo.vectorId = curveRoadPoint1.vectorId;
+    curveRoadPointInfo.position = {
+      x: curveRoadPoint2.position.x,
+      y: curveRoadPoint2.position.y,
+    };
+    curveRoadPointInfo.parent = JSON.parse(
+      JSON.stringify(curveRoadPoint2.parent)
+    );
+    curveRoadPointInfo.index = curveRoadPoint1.index;
+    this.setCurveRoadPointInfo(curveRoadPointInfo);
+  }
+
+  assignCurveRoadEdgeFromCurveRoadEdge(curveRoadEdge1, curveRoadEdge2) {
+    const curveRoadEdgeInfo = {};
+    curveRoadEdgeInfo.vectorId = curveRoadEdge1.vectorId;
+    curveRoadEdgeInfo.start = {
+      x: curveRoadEdge2.start.x,
+      y: curveRoadEdge2.start.y,
+    };
+    curveRoadEdgeInfo.end = {
+      x: curveRoadEdge2.end.x,
+      y: curveRoadEdge2.end.y,
+    };
+    curveRoadEdgeInfo.points = JSON.parse(
+      JSON.stringify(curveRoadEdge2.points)
+    );
+    curveRoadEdgeInfo.curves = JSON.parse(
+      JSON.stringify(curveRoadEdge2.curves)
+    );
+    curveRoadEdgeInfo.parent = curveRoadEdge2.parent;
+    this.setCurveRoadEdgeInfo(curveRoadEdgeInfo);
+  }
+
+  assignCurveRoadFromCurveRoad(curveRoad1, curveRoad2) {
+    const curveRoadInfo = {};
+    curveRoadInfo.vectorId = curveRoad1.vectorId;
+    curveRoadInfo.startId = curveRoad2.startId;
+    curveRoadInfo.endId = curveRoad2.endId;
+    curveRoadInfo.leftEdgeId = curveRoad2.leftEdgeId;
+    curveRoadInfo.rightEdgeId = curveRoad2.rightEdgeId;
+    curveRoadInfo.points = JSON.parse(JSON.stringify(curveRoad2.points));
+    curveRoadInfo.curves = JSON.parse(JSON.stringify(curveRoad2.curves));
+    curveRoadInfo.way = curveRoad2.way;
+    if (curveRoad2.way == Constant.oneWay) {
+      curveRoadInfo.singleCurveRoadWidth = curveRoad2.singleCurveRoadWidth;
+      curveRoadInfo.singleCurveRoadDrivewayCount =
+        curveRoad2.singleCurveRoadDrivewayCount;
+      curveRoadInfo.singleLanesCurves = JSON.parse(
+        JSON.stringify(curveRoad2.singleLanesCurves)
+      );
+    } else if (curveRoad2.way == Constant.twoWay) {
+      curveRoadInfo.leftWidth = curveRoad2.leftWidth;
+      curveRoadInfo.rightWidth = curveRoad2.rightWidth;
+      curveRoadInfo.leftDrivewayCount = curveRoad2.leftDrivewayCount;
+      curveRoadInfo.rightDrivewayCount = curveRoad2.rightDrivewayCount;
+      curveRoadInfo.midDivide = JSON.parse(
+        JSON.stringify(curveRoad2.midDivide)
+      );
+      curveRoadInfo.leftLanesCurves = JSON.parse(
+        JSON.stringify(curveRoad2.leftLanesCurves)
+      );
+      curveRoadInfo.rightLanesCurves = JSON.parse(
+        JSON.stringify(curveRoad2.rightLanesCurves)
+      );
+    }
+    curveRoadInfo.points = [];
+    for (let i = 0; i < curveRoad2.points.length; ++i) {
+      curveRoadInfo.points[i] = {};
+      curveRoadInfo.points[i].vectorId = curveRoad2.points[i].vectorId;
+    }
+    this.setCurveRoadInfo(curveRoadInfo);
+  }
+
   assignCrossPointFromCrossPoint(crossPoint1, crossPoint2) {
     const crossPointInfo = {};
     crossPointInfo.vectorId = crossPoint1.vectorId;
@@ -402,6 +535,63 @@ export default class HistoryUtil {
     return data;
   }
 
+  getDataForCurveRoadPoint(curveRoadPoint) {
+    const data = {};
+    data.id = curveRoadPoint.vectorId;
+    data.type = curveRoadPoint.geoType;
+    data.position = {};
+    mathUtil.clonePoint(data.position, curveRoadPoint);
+    data.parent = curveRoadPoint.parent;
+    data.index = curveRoadPoint.index;
+    return data;
+  }
+
+  getDataForCurveRoadEdge(curveRoadEdge) {
+    const data = {};
+    data.id = curveRoadEdge.vectorId;
+    data.type = curveRoadEdge.geoType;
+    data.parent = curveRoadEdge.parent;
+    data.start = JSON.parse(JSON.stringify(curveRoadEdge.start));
+    data.end = JSON.parse(JSON.stringify(curveRoadEdge.end));
+    data.points = JSON.parse(JSON.stringify(curveRoadEdge.points));
+    data.curves = JSON.parse(JSON.stringify(curveRoadEdge.curves));
+    return data;
+  }
+
+  getDataForCurveRoad(curveRoad) {
+    const data = {};
+    data.id = curveRoad.vectorId;
+    data.type = curveRoad.geoType;
+    data.startId = curveRoad.startId;
+    data.endId = curveRoad.endId;
+    data.leftEdgeId = curveRoad.leftEdgeId;
+    data.rightEdgeId = curveRoad.rightEdgeId;
+    data.points = JSON.parse(JSON.stringify(curveRoad.points));
+    data.curves = JSON.parse(JSON.stringify(curveRoad.curves));
+
+    data.way = curveRoad.way;
+    if (curveRoad.way == Constant.oneWay) {
+      data.singleCurveRoadWidth = curveRoad.singleRoadWidth;
+      data.singleCurveRoadDrivewayCount = curveRoad.singleRoadDrivewayCount;
+      data.singleLanesCurves = JSON.parse(
+        JSON.stringify(curveRoad.singleLanesCurves)
+      );
+    } else if (curveRoad.way == Constant.twoWay) {
+      data.leftWidth = curveRoad.leftWidth;
+      data.rightWidth = curveRoad.rightWidth;
+      data.leftDrivewayCount = curveRoad.leftDrivewayCount;
+      data.rightDrivewayCount = curveRoad.rightDrivewayCount;
+      data.midDivide = JSON.parse(JSON.stringify(curveRoad.midDivide));
+      data.leftLanesCurves = JSON.parse(
+        JSON.stringify(curveRoad.leftLanesCurves)
+      );
+      data.rightLanesCurves = JSON.parse(
+        JSON.stringify(curveRoad.rightLanesCurves)
+      );
+    }
+    return data;
+  }
+
   getDataForCrossPoint(crossPoint) {
     const data = {};
     data.id = crossPoint.vectorId;
@@ -433,6 +623,7 @@ export default class HistoryUtil {
     line.startId = lineInfo.start;
     line.endId = lineInfo.end;
     line.category = lineInfo.category;
+    line.value = lineInfo.value;
     return line;
   }
 
@@ -507,6 +698,67 @@ export default class HistoryUtil {
     }
   }
 
+  setCurveRoadPointInfo(curveRoadPointInfo) {
+    let curveRoadPoint = dataService.getCurveRoadPoint(
+      curveRoadPointInfo.vectorId
+    );
+    curveRoadPoint.vectorId = curveRoadPointInfo.vectorId;
+    mathUtil.clonePoint(curveRoadPoint, curveRoadPointInfo.position);
+    curveRoadPoint.parent = JSON.parse(
+      JSON.stringify(curveRoadPointInfo.parent)
+    );
+    curveRoadPoint.index = curveRoadPointInfo.index;
+  }
+
+  setCurveRoadEdgeInfo(curveRoadEdgeInfo) {
+    let curveRoadEdge = dataService.getCurveRoadEdge(
+      curveRoadEdgeInfo.vectorId
+    );
+    curveRoadEdge.vectorId = curveRoadEdgeInfo.vectorId;
+    mathUtil.clonePoint(curveRoadEdge.start, curveRoadEdgeInfo.start);
+    mathUtil.clonePoint(curveRoadEdge.end, curveRoadEdgeInfo.end);
+    mathUtil.clonePoints(curveRoadEdge.points, curveRoadEdgeInfo.points);
+    curveRoadEdge.curves = JSON.parse(JSON.stringify(curveRoadEdgeInfo.curves));
+    curveRoadEdge.name = curveRoadEdgeInfo.name;
+  }
+
+  setCurveRoadInfo(curveRoadInfo) {
+    let curveRoad = dataService.getCurveRoad(curveRoadInfo.vectorId);
+    curveRoad.vectorId = curveRoadInfo.vectorId;
+    curveRoad.startId = curveRoadInfo.startId;
+    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));
+    curveRoad.curves = JSON.parse(JSON.stringify(curveRoadInfo.midDivide));
+
+    if (curveRoad.way == Constant.oneWay) {
+      curveRoad.singleCurveRoadWidth = curveRoadInfo.singleCurveRoadWidth;
+      curveRoad.singleCurveRoadDrivewayCount =
+        curveRoadInfo.singleCurveRoadDrivewayCount;
+      curveRoad.singleLanesCurves = JSON.parse(
+        JSON.stringify(curveRoadInfo.singleLanesCurves)
+      );
+    } else if (curveRoad.way == Constant.twoWay) {
+      curveRoad.leftWidth = curveRoadInfo.leftWidth;
+      curveRoad.rightWidth = curveRoadInfo.rightWidth;
+      curveRoad.leftDrivewayCount = curveRoadInfo.leftDrivewayCount;
+      curveRoad.rightDrivewayCount = curveRoadInfo.rightDrivewayCount;
+      curveRoad.midDivide = JSON.parse(JSON.stringify(curveRoadInfo.midDivide));
+      curveRoad.leftLanesCurves = JSON.parse(
+        JSON.stringify(curveRoadInfo.leftLanesCurves)
+      );
+      curveRoad.rightLanesCurves = JSON.parse(
+        JSON.stringify(curveRoadInfo.rightLanesCurves)
+      );
+    }
+  }
+
   setCrossPointInfo(crossPointInfo) {
     let crossPoint = dataService.getCrossPoint3(crossPointInfo.vectorId);
     crossPoint.vectorId = crossPointInfo.vectorId;

+ 33 - 6
src/graphic/Layer.js

@@ -138,6 +138,10 @@ export default class Layer {
         stateService.setEventName(LayerEvents.AddingLine);
         addLine.setNewLinePoint(position);
         break;
+      case LayerEvents.AddCurveLine:
+        stateService.setEventName(LayerEvents.AddCurveLine);
+        addLine.setNewLinePoint(position);
+        break;
       case LayerEvents.AddPoint:
         stateService.setEventName(LayerEvents.MovePoint);
         const newPoint = addPoint.buildPoint(position);
@@ -147,8 +151,9 @@ export default class Layer {
             VectorType.Point,
             SelectState.Select
           );
+        } else {
+          this.uiControl.prompt({ msg: "请先添加基准点", time: 1000 });
         }
-
         break;
       case LayerEvents.AddCircle:
         stateService.setEventName(LayerEvents.AddingCircle);
@@ -234,6 +239,8 @@ export default class Layer {
 
     let dx = X - this.lastX;
     let dy = Y - this.lastY;
+    dx = dx * coordinate.ratio;
+    dy = dy * coordinate.ratio;
 
     let position = coordinate.getXYFromScreen({
       x: X,
@@ -274,8 +281,10 @@ export default class Layer {
         break;
       case LayerEvents.PanBackGround:
         stateService.clearItems();
-        coordinate.center.x = coordinate.center.x - dx;
-        coordinate.center.y = coordinate.center.y + dy;
+        coordinate.center.x =
+          coordinate.center.x - (dx * coordinate.defaultZoom) / coordinate.zoom;
+        coordinate.center.y =
+          coordinate.center.y + (dy * coordinate.defaultZoom) / coordinate.zoom;
 
         dataService.setGridForPan();
         needAutoRedraw = true;
@@ -314,6 +323,23 @@ export default class Layer {
           elementService.execute(listenLayer.modifyPoint, position);
         }
         break;
+      case LayerEvents.AddCurveLine:
+        needAutoRedraw = true;
+        listenLayer.start(position);
+        if (listenLayer.modifyPoint) {
+          position = {
+            x: listenLayer.modifyPoint.x,
+            y: listenLayer.modifyPoint.y,
+          };
+        }
+
+        elementService.hideAll();
+        elementService.setPoint(position);
+        elementService.showPoint();
+        if (listenLayer.modifyPoint) {
+          elementService.execute(listenLayer.modifyPoint, position);
+        }
+        break;
       case LayerEvents.AddCircle:
         needAutoRedraw = true;
         listenLayer.start(position);
@@ -670,6 +696,8 @@ export default class Layer {
       stateService.setFocusItem(focusItem);
       this.uiControl.focusVector = focusItem;
       stateService.clearDraggingItem();
+    } else {
+      this.uiControl.focusVector = null;
     }
 
     let position = coordinate.getXYFromScreen({
@@ -824,6 +852,7 @@ export default class Layer {
         needAutoRedraw = true;
         if (draggingItem && draggingItem.vectorId) {
           movePoint.finish(draggingItem.vectorId);
+          uiService.setPointCategory(VectorCategory.Point.NormalPoint);
         }
         this.history.save();
         break;
@@ -1093,6 +1122,7 @@ export default class Layer {
         if (Settings.isMobile) {
           stateService.clearEventName();
           this.exit();
+          uiService.setLineCategory(VectorCategory.Line.NormalLine);
         } else {
           stateService.setEventName(LayerEvents.AddLine);
         }
@@ -1114,9 +1144,6 @@ export default class Layer {
   exit() {
     stateService.clear();
     this.uiControl.clearUI();
-    this.uiControl.focusVector = null;
-    uiService.setPointCategory(VectorCategory.Point.NormalPoint);
-    uiService.setLineCategory(VectorCategory.Line.NormalLine);
   }
 
   stopAddVector() {

+ 24 - 4
src/graphic/ListenLayer.js

@@ -125,7 +125,8 @@ export default class ListenLayer {
         if (Math.abs(position.x - point.x) < Constant.minAdsorbPix) {
           seqInfo.linkedPointIdX = pointId;
           seqInfo.x = point.x;
-        } else if (Math.abs(position.y - point.y) < Constant.minAdsorbPix) {
+        }
+        if (Math.abs(position.y - point.y) < Constant.minAdsorbPix) {
           seqInfo.linkedPointIdY = pointId;
           seqInfo.y = point.y;
         }
@@ -141,7 +142,8 @@ export default class ListenLayer {
       if (seqInfo.hasOwnProperty("linkedPointIdX")) {
         pointInfo.linkedPointIdX = seqInfo.linkedPointIdX;
         pointInfo.x = seqInfo.x;
-      } else if (seqInfo.hasOwnProperty("linkedPointIdY")) {
+      }
+      if (seqInfo.hasOwnProperty("linkedPointIdY")) {
         pointInfo.linkedPointIdY = seqInfo.linkedPointIdY;
         pointInfo.y = seqInfo.y;
       }
@@ -990,13 +992,31 @@ export default class ListenLayer {
         info.curvePointInfo.linkedRoadPointIdY;
       this.modifyPoint.y = info.curvePointInfo.y;
       this.modifyPoint.x = position.x;
-    } else if (info && info.pointInfo.linkedPointIdX) {
+    } else if (
+      info &&
+      info.pointInfo.linkedPointIdX &&
+      !info.pointInfo.linkedPointIdY
+    ) {
       this.modifyPoint = {};
       this.modifyPoint.linkedPointIdX = info.pointInfo.linkedPointIdX;
       this.modifyPoint.x = info.pointInfo.x;
       this.modifyPoint.y = info.pointInfo.y;
-    } else if (info && info.pointInfo.linkedPointIdY) {
+    } else if (
+      info &&
+      info.pointInfo.linkedPointIdY &&
+      !info.pointInfo.linkedPointIdX
+    ) {
+      this.modifyPoint = {};
+      this.modifyPoint.linkedPointIdY = info.pointInfo.linkedPointIdY;
+      this.modifyPoint.y = info.pointInfo.y;
+      this.modifyPoint.x = info.pointInfo.x;
+    } else if (
+      info &&
+      info.pointInfo.linkedPointIdY &&
+      info.pointInfo.linkedPointIdX
+    ) {
       this.modifyPoint = {};
+      this.modifyPoint.linkedPointIdX = info.pointInfo.linkedPointIdX;
       this.modifyPoint.linkedPointIdY = info.pointInfo.linkedPointIdY;
       this.modifyPoint.y = info.pointInfo.y;
       this.modifyPoint.x = info.pointInfo.x;

+ 48 - 38
src/graphic/Load.js

@@ -88,8 +88,11 @@ export default class Load {
             dataLocal.lines[key].category,
             key
           );
-          if (dataLocal.lines[key].arrowColor) {
-            line.setArrowColor(dataLocal.lines[key].arrowColor);
+          if (dataLocal.lines[key].color) {
+            line.setColor(dataLocal.lines[key].color);
+          }
+          if (dataLocal.lines[key].value) {
+            line.setValue(dataLocal.lines[key].value);
           }
           line.setDisplay(dataLocal.lines[key].display);
           if (line.getCategory() == VectorCategory.Line.BaseLine) {
@@ -113,45 +116,48 @@ export default class Load {
           }
         } catch (e) {}
         if (data3d.meterPerPixel) {
-          const width = bgImg.imageData.width;
-          const height = bgImg.imageData.height;
           coordinate.setRes(data3d.meterPerPixel);
-          if (data3d.baseLines) {
-            for (let i = 0; i < data3d.baseLines.length; ++i) {
-              //理论上基准线只能有一条
-              let baseLine = lineService.create(
-                this.getXY(width, height, data3d.baseLines[i][0]),
-                this.getXY(width, height, data3d.baseLines[i][1]),
-                VectorCategory.Line.BaseLine
-              );
-              Settings.baseLineId = baseLine.vectorId;
-            }
+        }
+        const width = bgImg.imageData.width;
+        const height = bgImg.imageData.height;
+
+        if (data3d.baseLines) {
+          for (let i = 0; i < data3d.baseLines.length; ++i) {
+            //理论上基准线只能有一条
+            let baseLine = lineService.create(
+              this.getXY(width, height, data3d.baseLines[i][0]),
+              this.getXY(width, height, data3d.baseLines[i][1]),
+              VectorCategory.Line.BaseLine
+            );
+            Settings.baseLineId = baseLine.vectorId;
           }
-          if (data3d.measures) {
-            for (let i = 0; i < data3d.measures.length; ++i) {
-              //理论上基准线只能有一条
-              lineService.create(
-                this.getXY(width, height, data3d.measures[i][0]),
-                this.getXY(width, height, data3d.measures[i][1]),
-                VectorCategory.Line.MeasureLine
-              );
-            }
+        }
+        if (data3d.measures) {
+          for (let i = 0; i < data3d.measures.length; ++i) {
+            //理论上基准线只能有一条
+            //
+            const line = lineService.create(
+              this.getXY(width, height, data3d.measures[i].pos[0]),
+              this.getXY(width, height, data3d.measures[i].pos[1]),
+              VectorCategory.Line.MeasureLine
+            );
+            line.value = data3d.measures[i].dis;
           }
-          if (data3d.basePoints) {
-            for (let i = 0; i < data3d.basePoints.length; ++i) {
-              let point = pointService.create(
-                this.getXY(width, height, data3d.basePoints[i])
-              );
-              point.setCategory(VectorCategory.Point.BasePoint);
-            }
+        }
+        if (data3d.basePoints) {
+          for (let i = 0; i < data3d.basePoints.length; ++i) {
+            let point = pointService.create(
+              this.getXY(width, height, data3d.basePoints[i])
+            );
+            point.setCategory(VectorCategory.Point.BasePoint);
           }
-          if (data3d.fixPoints) {
-            for (let i = 0; i < data3d.fixPoints.length; ++i) {
-              let point = pointService.create(
-                this.getXY(width, height, data3d.fixPoints[i])
-              );
-              point.setCategory(VectorCategory.Point.FixPoint);
-            }
+        }
+        if (data3d.fixPoints) {
+          for (let i = 0; i < data3d.fixPoints.length; ++i) {
+            let point = pointService.create(
+              this.getXY(width, height, data3d.fixPoints[i])
+            );
+            point.setCategory(VectorCategory.Point.FixPoint);
           }
         }
       }
@@ -171,7 +177,11 @@ export default class Load {
   }
 
   save() {
-    dataService.vectorData.res = coordinate.getRes();
+    const res = coordinate.getRes();
+    dataService.setRes(res);
+
+    const scale = res / (coordinate.zoom / coordinate.defaultZoom);
+    dataService.setScale(scale);
     return dataService.vectorData;
   }
 

+ 83 - 66
src/graphic/Renderer/Draw.js

@@ -27,12 +27,12 @@ const help = {
 
     return [
       itemsEntry.reduce((prev, [item, attr]) => {
-        if (!item) return prev
-        const selected = geoId === item.vectorId || (
-          item.parent && Object.keys(item.parent).some(id => id === geoId)
-        );
+        if (!item) return prev;
+        const selected =
+          geoId === item.vectorId ||
+          (item.parent && Object.keys(item.parent).some((id) => id === geoId));
         if (selected && Style[attr]) {
-          const style = Style[attr][geoType] || Style[attr][vector.category]
+          const style = Style[attr][geoType] || Style[attr][vector.category];
           if (style) {
             currentAttr = attr;
             return style;
@@ -54,7 +54,7 @@ const help = {
     }
   },
   setVectorStyle(ctx, vector, geoType = vector.geoType) {
-    let styles, attr
+    let styles, attr;
     if (Array.isArray(geoType)) {
       for (const type of geoType) {
         [styles, attr] = help.getVectorStyle(vector, type);
@@ -65,7 +65,7 @@ const help = {
     } else {
       [styles, attr] = help.getVectorStyle(vector, geoType);
     }
-    help.setStyle(ctx, styles)
+    help.setStyle(ctx, styles);
     return [styles, attr];
   },
   transformCoves(lines) {
@@ -118,13 +118,13 @@ const help = {
   },
   getTextCenter(ctx, txt) {
     const text = ctx.measureText(txt);
-    const height = text.actualBoundingBoxAscent + text.actualBoundingBoxDescent
+    const height = text.actualBoundingBoxAscent + text.actualBoundingBoxDescent;
     return {
       width: text.width,
       height,
       x: text.width / 2,
-      y: -height / 2
-    }
+      y: -height / 2,
+    };
   },
   // 绘制圆角矩形
   roundRect(ctx, x, y, width, height, radius) {
@@ -141,13 +141,15 @@ const help = {
     ctx.closePath();
   },
   getRealDistance(p1, p2) {
-    return Math.round(mathUtil.getDistance(p1, p2) * coordinate.res * 100) / 100
+    return (
+      Math.round(mathUtil.getDistance(p1, p2) * coordinate.res * 100) / 100
+    );
   },
   getPerpendicularPoint(p1, p2, p3, d) {
     if (p1.x === p2.x) {
-      return {x: p3.x + d, y: p3.y}
+      return { x: p3.x + d, y: p3.y };
     } else if (p1.y === p2.y) {
-      return {x: p3.x, y: p3.y + d}
+      return { x: p3.x, y: p3.y + d };
     }
 
     // 计算通过 p1 和 p2 的直线的斜率和截距
@@ -159,11 +161,12 @@ const help = {
     const perpendicularIntercept = p3.y - perpendicularSlope * p3.x;
 
     // 计算垂足点 p0
-    const x = (perpendicularIntercept - intercept) / (slope - perpendicularSlope);
+    const x =
+      (perpendicularIntercept - intercept) / (slope - perpendicularSlope);
     const y = slope * x + intercept;
     const p0 = { x, y };
 
-// 计算点 p4
+    // 计算点 p4
     const distance = d; // 指定距离
     const dx = distance / Math.sqrt(1 + perpendicularSlope ** 2);
     const dy = perpendicularSlope * dx;
@@ -171,16 +174,17 @@ const help = {
   },
   drawLineText(ctx, start, end, text, style) {
     if (start.x > end.x) {
-      [start, end] = [end, start]
+      [start, end] = [end, start];
     }
 
-    const angle = Math.atan2(end.y - start.y, end.x - start.x) * 180 / Math.PI;
-    const center = mathUtil.lineCenter(start, end)
+    const angle =
+      (Math.atan2(end.y - start.y, end.x - start.x) * 180) / Math.PI;
+    const center = mathUtil.lineCenter(start, end);
 
     ctx.save();
     ctx.translate(center.x, center.y);
-    ctx.rotate(angle * Math.PI / 180);
-    const textCenter = help.getTextCenter(ctx, text)
+    ctx.rotate((angle * Math.PI) / 180);
+    const textCenter = help.getTextCenter(ctx, text);
     const padding = style.padding;
     help.roundRect(
       ctx,
@@ -188,14 +192,14 @@ const help = {
       textCenter.y - padding,
       textCenter.width + 2 * padding,
       textCenter.height + 2 * padding,
-      (textCenter.height / 2) + padding
-    )
-    ctx.fillStyle = style.backColor
-    ctx.fill()
-    ctx.fillStyle = style.fillColor
+      textCenter.height / 2 + padding
+    );
+    ctx.fillStyle = style.backColor;
+    ctx.fill();
+    ctx.fillStyle = style.fillColor;
     ctx.fillText(text, -textCenter.x, -textCenter.y);
     ctx.restore();
-  }
+  },
 };
 
 export default class Draw {
@@ -505,8 +509,8 @@ export default class Draw {
     ctx.save();
 
     const [style] = help.setVectorStyle(this.context, vector);
-    if (vector.arrowColor) {
-      ctx.strokeStyle = vector.arrowColor;
+    if (vector.color) {
+      ctx.strokeStyle = vector.color;
     }
 
     const dires =
@@ -602,6 +606,7 @@ export default class Draw {
   drawCircle(element) {
     this.drawPoint({
       ...element,
+      radius: help.getReal(element.radius),
       geoType: "Circle",
       ...element.center,
     });
@@ -615,19 +620,18 @@ export default class Draw {
     }
     const pt = coordinate.getScreenXY({ x: vector.x, y: vector.y });
     const ctx = this.context;
-    let [style, attr] = help.setVectorStyle(
-      ctx,
-      vector,
-      [vector.category, vector.geoType, "Point"]
-
-    );
+    let [style, attr] = help.setVectorStyle(ctx, vector, [
+      vector.category,
+      vector.geoType,
+      "Point",
+    ]);
     if (vector.category === VectorCategory.Point.NormalPoint) {
-      const lineid = Object.keys(vector.parent)[0]
-      let line, style
+      const lineid = Object.keys(vector.parent)[0];
+      let line, style;
       if (!(lineid && (line = dataService.getLine(lineid)))) {
         return;
       }
-      const [_, attr] = help.getVectorStyle(line)
+      const [_, attr] = help.getVectorStyle(line);
       if (!attr) {
         return;
       }
@@ -641,11 +645,11 @@ export default class Draw {
       ctx.save();
       ctx.beginPath();
       ctx.arc(pt.x, pt.y, radius, 0, Math.PI * 2, true);
-      help.setStyle(ctx, style)
+      help.setStyle(ctx, style);
       ctx.stroke();
       ctx.fill();
       ctx.restore();
-    }
+    };
 
     if (Settings.selectBasePointId === vector.vectorId) {
       style = {
@@ -654,12 +658,12 @@ export default class Draw {
         out: style.out && {
           ...style.out,
           strokeStyle: "red",
-        }
-      }
+        },
+      };
     }
-    draw(style)
+    draw(style);
     if (style.out) {
-      draw(style.out)
+      draw(style.out);
     }
 
     if (import.meta.env.DEV) {
@@ -694,7 +698,9 @@ export default class Draw {
     help.setVectorStyle(this.context, vector);
     this.context.fillStyle = vector.color;
     const oldFont = this.context.font;
-    this.context.font = `${vector.fontSize * coordinate.ratio}px Microsoft YaHei`;
+    this.context.font = `${
+      vector.fontSize * coordinate.ratio
+    }px Microsoft YaHei`;
     this.drawTextByInfo(vector.center, vector.value, 0, false);
 
     const ctx = this.context;
@@ -713,9 +719,9 @@ export default class Draw {
       this.context,
       coordinate.getScreenXY(startReal),
       coordinate.getScreenXY(endReal),
-      help.getRealDistance(startReal, endReal) + "m",
+      (vector.value ? (Math.round(vector.value * 100) / 100) : help.getRealDistance(startReal, endReal)) + "m",
       style
-    )
+    );
   }
 
   drawBaseLineLabel(vector) {
@@ -724,10 +730,18 @@ export default class Draw {
     const endReal = dataService.getPoint(vector.endId);
     const end = coordinate.getScreenXY(endReal);
     const point = mathUtil.translate(
-      end, start, end, mathUtil.getDistance(start, end) / 3
-    )
-    const p4 = help.getPerpendicularPoint(start, end, point, 30 * coordinate.ratio)
-    const ctx = this.context
+      end,
+      start,
+      end,
+      mathUtil.getDistance(start, end) / 3
+    );
+    const p4 = help.getPerpendicularPoint(
+      start,
+      end,
+      point,
+      30 * coordinate.ratio
+    );
+    const ctx = this.context;
     ctx.beginPath();
     const [style] = help.setVectorStyle(
       this.context,
@@ -738,7 +752,12 @@ export default class Draw {
     ctx.lineTo(p4.x, p4.y);
     ctx.stroke();
 
-    const p5 = help.getPerpendicularPoint(start, end, point, 35 * coordinate.ratio)
+    const p5 = help.getPerpendicularPoint(
+      start,
+      end,
+      point,
+      35 * coordinate.ratio
+    );
     this.context.font = `${10 * coordinate.ratio}px Microsoft YaHei`;
     help.drawLineText(
       this.context,
@@ -748,9 +767,9 @@ export default class Draw {
       {
         padding: 6 * coordinate.ratio,
         backColor: "rgba(0,0,0,0)",
-        fillColor: style.strokeStyle
+        fillColor: style.strokeStyle,
       }
-    )
+    );
   }
 
   drawLine(vector) {
@@ -760,11 +779,11 @@ export default class Draw {
     const end = coordinate.getScreenXY(endReal);
 
     this.context.save();
-    const [style, attr] = help.setVectorStyle(
-      this.context,
-      vector,
-      [vector.category, vector.geoType, 'BaseLine']
-    );
+    const [style, attr] = help.setVectorStyle(this.context, vector, [
+      vector.category,
+      vector.geoType,
+      "BaseLine",
+    ]);
     if (style.dash) {
       this.context.setLineDash(style.dash);
     }
@@ -780,24 +799,22 @@ export default class Draw {
       //   this.drawPoint(dataService.getPoint(vector.startId))
       //   this.drawPoint(dataService.getPoint(vector.endId))
       // }
-    }
+    };
 
     switch (vector.category) {
       case VectorCategory.Line.ArrowLine:
         this.drawArrow(vector);
-        drawPoints()
-        break
+        drawPoints();
+        break;
       case VectorCategory.Line.BaseLine:
-        this.drawBaseLineLabel(vector)
-        drawPoints()
+        this.drawBaseLineLabel(vector);
+        drawPoints();
         break;
       case VectorCategory.Line.MeasureLine:
       case VectorCategory.Line.PositionLine:
-        this.drawLineText(vector, style.text)
+        this.drawLineText(vector, style.text);
         break;
-
     }
-
   }
 
   drawElementLine(element) {

+ 13 - 0
src/graphic/Service/CurveRoadService.js

@@ -82,6 +82,19 @@ export default class CurveRoadService extends RoadService {
     return curveRoad;
   }
 
+  //撤销恢复用的,edge这些会专门调用
+  createOnlyCurveRoad(startId, endId, vectorId) {
+    let curveRoad = new CurveRoad(startId, endId, vectorId);
+    dataService.addCurveRoad(curveRoad);
+
+    let startPoint = dataService.getCurveRoadPoint(startId);
+    startPoint.setPointParent(curveRoad.vectorId, "start");
+
+    let endPoint = dataService.getCurveRoadPoint(endId);
+    endPoint.setPointParent(curveRoad.vectorId, "end");
+    return curveRoad;
+  }
+
   //不能加首尾,只能加中间
   //完全不处理车道,都放在setLanes上处理
   addCPoint(curveRoad, position, startIndex) {

+ 16 - 0
src/graphic/Service/DataService.js

@@ -568,6 +568,22 @@ export class DataService {
     this.vectorData.svgs = {};
     this.vectorData.magnifiers = {};
   }
+
+  setRes(value) {
+    this.vectorData.res = value;
+  }
+
+  getRes() {
+    return this.vectorData.res;
+  }
+
+  setScale(value) {
+    this.vectorData.scale = value;
+  }
+
+  getScale() {
+    return this.vectorData.scale;
+  }
 }
 
 const dataService = new DataService();

+ 63 - 57
src/graphic/Service/EdgeService.js

@@ -133,16 +133,22 @@ export default class EdgeService {
       if (angle > Constant.maxAngle || angle < Constant.minAngle) {
         newEdgePoint1 = mathUtil.getJoinLinePoint(startPoint1, lineLeft1);
         newEdgePoint2 = mathUtil.getJoinLinePoint(startPoint1, lineRight1);
+        mathUtil.clonePoint(leftEdge1.start, newEdgePoint1);
+        mathUtil.clonePoint(rightEdge1.start, newEdgePoint2);
+
+        newEdgePoint1 = mathUtil.getJoinLinePoint(startPoint1, lineLeft2);
+        newEdgePoint2 = mathUtil.getJoinLinePoint(startPoint1, lineRight2);
+        mathUtil.clonePoint(rightEdge2.start, newEdgePoint1);
+        mathUtil.clonePoint(leftEdge2.start, newEdgePoint2);
       } else {
         newEdgePoint1 = mathUtil.getIntersectionPoint(lineLeft1, lineRight2);
         newEdgePoint2 = mathUtil.getIntersectionPoint(lineLeft2, lineRight1);
-      }
-
-      mathUtil.clonePoint(leftEdge1.start, newEdgePoint1);
-      mathUtil.clonePoint(rightEdge1.start, newEdgePoint2);
+        mathUtil.clonePoint(leftEdge1.start, newEdgePoint1);
+        mathUtil.clonePoint(rightEdge1.start, newEdgePoint2);
 
-      mathUtil.clonePoint(rightEdge2.start, newEdgePoint1);
-      mathUtil.clonePoint(leftEdge2.start, newEdgePoint2);
+        mathUtil.clonePoint(rightEdge2.start, newEdgePoint1);
+        mathUtil.clonePoint(leftEdge2.start, newEdgePoint2);
+      }
 
       if (angle > Constant.maxAngle || angle < Constant.minAngle) {
         //要删除控制点
@@ -203,16 +209,22 @@ export default class EdgeService {
       if (angle > Constant.maxAngle || angle < Constant.minAngle) {
         newEdgePoint1 = mathUtil.getJoinLinePoint(startPoint1, lineLeft1);
         newEdgePoint2 = mathUtil.getJoinLinePoint(startPoint1, lineRight1);
+        mathUtil.clonePoint(leftEdge1.start, newEdgePoint1);
+        mathUtil.clonePoint(rightEdge1.start, newEdgePoint2);
+
+        newEdgePoint1 = mathUtil.getJoinLinePoint(startPoint1, lineLeft2);
+        newEdgePoint2 = mathUtil.getJoinLinePoint(startPoint1, lineRight2);
+        mathUtil.clonePoint(leftEdge2.end, newEdgePoint1);
+        mathUtil.clonePoint(rightEdge2.end, newEdgePoint2);
       } else {
         newEdgePoint1 = mathUtil.getIntersectionPoint(lineLeft1, lineLeft2);
         newEdgePoint2 = mathUtil.getIntersectionPoint(lineRight1, lineRight2);
-      }
-
-      mathUtil.clonePoint(leftEdge1.start, newEdgePoint1);
-      mathUtil.clonePoint(rightEdge1.start, newEdgePoint2);
+        mathUtil.clonePoint(leftEdge1.start, newEdgePoint1);
+        mathUtil.clonePoint(rightEdge1.start, newEdgePoint2);
 
-      mathUtil.clonePoint(leftEdge2.end, newEdgePoint1);
-      mathUtil.clonePoint(rightEdge2.end, newEdgePoint2);
+        mathUtil.clonePoint(leftEdge2.end, newEdgePoint1);
+        mathUtil.clonePoint(rightEdge2.end, newEdgePoint2);
+      }
 
       if (angle > Constant.maxAngle || angle < Constant.minAngle) {
         //要删除控制点
@@ -272,20 +284,31 @@ export default class EdgeService {
       if (angle > Constant.maxAngle || angle < Constant.minAngle) {
         newEdgePoint1 = mathUtil.getJoinLinePoint(endPoint1, lineLeft1);
         newEdgePoint2 = mathUtil.getJoinLinePoint(endPoint1, lineRight1);
+        mathUtil.clonePoint(leftEdge1.end, newEdgePoint1);
+        mathUtil.clonePoint(rightEdge1.end, newEdgePoint2);
+        newEdgePoint1 = mathUtil.getJoinLinePoint(endPoint1, lineLeft2);
+        newEdgePoint2 = mathUtil.getJoinLinePoint(endPoint1, lineRight2);
+        mathUtil.clonePoint(leftEdge2.start, newEdgePoint1);
+        mathUtil.clonePoint(rightEdge2.start, newEdgePoint2);
       } else {
         newEdgePoint1 = mathUtil.getIntersectionPoint(lineLeft1, lineLeft2);
         newEdgePoint2 = mathUtil.getIntersectionPoint(lineRight1, lineRight2);
-      }
+        mathUtil.clonePoint(leftEdge1.end, newEdgePoint1);
+        mathUtil.clonePoint(rightEdge1.end, newEdgePoint2);
 
-      if (newEdgePoint1 == null || newEdgePoint2 == null) {
-        debugger;
+        mathUtil.clonePoint(leftEdge2.start, newEdgePoint1);
+        mathUtil.clonePoint(rightEdge2.start, newEdgePoint2);
       }
 
-      mathUtil.clonePoint(leftEdge1.end, newEdgePoint1);
-      mathUtil.clonePoint(rightEdge1.end, newEdgePoint2);
+      // if (newEdgePoint1 == null || newEdgePoint2 == null) {
+      //   debugger;
+      // }
 
-      mathUtil.clonePoint(leftEdge2.start, newEdgePoint1);
-      mathUtil.clonePoint(rightEdge2.start, newEdgePoint2);
+      // mathUtil.clonePoint(leftEdge1.end, newEdgePoint1);
+      // mathUtil.clonePoint(rightEdge1.end, newEdgePoint2);
+
+      // mathUtil.clonePoint(leftEdge2.start, newEdgePoint1);
+      // mathUtil.clonePoint(rightEdge2.start, newEdgePoint2);
       if (angle > Constant.maxAngle || angle < Constant.minAngle) {
         //要删除控制点
         dataService.deleteCrossPoint(leftEdge1.vectorId, leftEdge2.vectorId);
@@ -344,15 +367,23 @@ export default class EdgeService {
       if (angle > Constant.maxAngle || angle < Constant.minAngle) {
         newEdgePoint1 = mathUtil.getJoinLinePoint(endPoint1, lineLeft1);
         newEdgePoint2 = mathUtil.getJoinLinePoint(endPoint1, lineRight1);
+
+        mathUtil.clonePoint(leftEdge1.end, newEdgePoint1);
+        mathUtil.clonePoint(rightEdge1.end, newEdgePoint2);
+
+        newEdgePoint1 = mathUtil.getJoinLinePoint(endPoint1, lineLeft2);
+        newEdgePoint2 = mathUtil.getJoinLinePoint(endPoint1, lineRight2);
+        mathUtil.clonePoint(rightEdge2.end, newEdgePoint1);
+        mathUtil.clonePoint(leftEdge2.end, newEdgePoint2);
       } else {
         newEdgePoint1 = mathUtil.getIntersectionPoint(lineLeft1, lineRight2);
         newEdgePoint2 = mathUtil.getIntersectionPoint(lineLeft2, lineRight1);
-      }
-      mathUtil.clonePoint(leftEdge1.end, newEdgePoint1);
-      mathUtil.clonePoint(rightEdge1.end, newEdgePoint2);
+        mathUtil.clonePoint(leftEdge1.end, newEdgePoint1);
+        mathUtil.clonePoint(rightEdge1.end, newEdgePoint2);
 
-      mathUtil.clonePoint(rightEdge2.end, newEdgePoint1);
-      mathUtil.clonePoint(leftEdge2.end, newEdgePoint2);
+        mathUtil.clonePoint(rightEdge2.end, newEdgePoint1);
+        mathUtil.clonePoint(leftEdge2.end, newEdgePoint2);
+      }
 
       if (angle > Constant.maxAngle || angle < Constant.minAngle) {
         //要删除控制点
@@ -477,11 +508,7 @@ export default class EdgeService {
         // console.log("情况1");
         mathUtil.clonePoint(leftEdge1.start, newEdgePoint1);
         mathUtil.clonePoint(rightEdge2.start, newEdgePoint1);
-        //要删除控制点
-        dataService.deleteCrossPoint(leftEdge1.vectorId, rightEdge2.vectorId);
-        //不能按照下面的方式计算,因为一个edge可以属于两个控制点,毕竟有两个端点
-        // dataService.deleteCrossPointForEdge(leftEdge1.vectorId);
-        // dataService.deleteCrossPointForEdge(rightEdge2.vectorId);
+
         if (angle > Constant.maxAngle || angle < Constant.minAngle) {
           //要删除控制点
           dataService.deleteCrossPoint(leftEdge1.vectorId, rightEdge2.vectorId);
@@ -503,10 +530,7 @@ export default class EdgeService {
         // console.log("情况2");
         mathUtil.clonePoint(rightEdge1.start, newEdgePoint2);
         mathUtil.clonePoint(leftEdge2.start, newEdgePoint2);
-        //要删除控制点
-        dataService.deleteCrossPoint(leftEdge2.vectorId, rightEdge1.vectorId);
-        // dataService.deleteCrossPointForEdge(leftEdge2.vectorId);
-        // dataService.deleteCrossPointForEdge(rightEdge1.vectorId);
+
         if (angle > Constant.maxAngle || angle < Constant.minAngle) {
           //要删除控制点
           dataService.deleteCrossPoint(leftEdge2.vectorId, rightEdge1.vectorId);
@@ -548,10 +572,7 @@ export default class EdgeService {
         //console.log("情况3");
         mathUtil.clonePoint(leftEdge1.start, newEdgePoint1);
         mathUtil.clonePoint(leftEdge2.end, newEdgePoint1);
-        //要删除控制点
-        dataService.deleteCrossPoint(leftEdge1.vectorId, leftEdge2.vectorId);
-        // dataService.deleteCrossPointForEdge(leftEdge1.vectorId);
-        // dataService.deleteCrossPointForEdge(leftEdge2.vectorId);
+
         if (angle > Constant.maxAngle || angle < Constant.minAngle) {
           //要删除控制点
           dataService.deleteCrossPoint(leftEdge1.vectorId, leftEdge2.vectorId);
@@ -571,10 +592,7 @@ export default class EdgeService {
         //console.log("情况4");
         mathUtil.clonePoint(rightEdge1.start, newEdgePoint2);
         mathUtil.clonePoint(rightEdge2.end, newEdgePoint2);
-        //要删除控制点
-        dataService.deleteCrossPoint(rightEdge1.vectorId, rightEdge2.vectorId);
-        // dataService.deleteCrossPointForEdge(rightEdge1.vectorId);
-        // dataService.deleteCrossPointForEdge(rightEdge2.vectorId);
+
         if (angle > Constant.maxAngle || angle < Constant.minAngle) {
           //要删除控制点
           dataService.deleteCrossPoint(
@@ -619,10 +637,7 @@ export default class EdgeService {
         //console.log("情况5");
         mathUtil.clonePoint(leftEdge1.end, newEdgePoint1);
         mathUtil.clonePoint(leftEdge2.start, newEdgePoint1);
-        //要删除控制点
-        dataService.deleteCrossPoint(leftEdge1.vectorId, leftEdge2.vectorId);
-        // dataService.deleteCrossPointForEdge(leftEdge1.vectorId);
-        // dataService.deleteCrossPointForEdge(leftEdge2.vectorId);
+
         if (angle > Constant.maxAngle || angle < Constant.minAngle) {
           //要删除控制点
           dataService.deleteCrossPoint(leftEdge1.vectorId, leftEdge2.vectorId);
@@ -642,10 +657,7 @@ export default class EdgeService {
         //console.log("情况6");
         mathUtil.clonePoint(rightEdge1.end, newEdgePoint2);
         mathUtil.clonePoint(rightEdge2.start, newEdgePoint2);
-        //要删除控制点
-        dataService.deleteCrossPoint(rightEdge1.vectorId, rightEdge2.vectorId);
-        // dataService.deleteCrossPointForEdge(rightEdge1.vectorId);
-        // dataService.deleteCrossPointForEdge(rightEdge2.vectorId);
+
         if (angle > Constant.maxAngle || angle < Constant.minAngle) {
           //要删除控制点
           dataService.deleteCrossPoint(
@@ -690,10 +702,7 @@ export default class EdgeService {
         //console.log("情况7");
         mathUtil.clonePoint(leftEdge1.end, newEdgePoint1);
         mathUtil.clonePoint(rightEdge2.end, newEdgePoint1);
-        //要删除控制点
-        dataService.deleteCrossPoint(leftEdge1.vectorId, leftEdge2.vectorId);
-        // dataService.deleteCrossPointForEdge(leftEdge1.vectorId);
-        // dataService.deleteCrossPointForEdge(leftEdge2.vectorId);
+
         if (angle > Constant.maxAngle || angle < Constant.minAngle) {
           //要删除控制点
           dataService.deleteCrossPoint(leftEdge1.vectorId, leftEdge2.vectorId);
@@ -713,10 +722,7 @@ export default class EdgeService {
         //console.log("情况8");
         mathUtil.clonePoint(rightEdge1.end, newEdgePoint2);
         mathUtil.clonePoint(leftEdge2.end, newEdgePoint2);
-        //要删除控制点
-        dataService.deleteCrossPoint(rightEdge1.vectorId, leftEdge2.vectorId);
-        // dataService.deleteCrossPointForEdge(leftEdge2.vectorId);
-        // dataService.deleteCrossPointForEdge(rightEdge1.vectorId);
+
         if (angle > Constant.maxAngle || angle < Constant.minAngle) {
           //要删除控制点
           dataService.deleteCrossPoint(rightEdge1.vectorId, leftEdge2.vectorId);

+ 1 - 1
src/graphic/Service/LineService.js

@@ -68,7 +68,7 @@ export default class LineService {
     startPoint = uiService.getNewPositionForPop(startPoint);
     endPoint = uiService.getNewPositionForPop(endPoint);
     let newLine = this.create(startPoint, endPoint, line.category);
-    newLine.setArrowColor(line.arrowColor);
+    newLine.setColor(line.color);
     return newLine;
   }
 

+ 2 - 2
src/graphic/Service/RoadService.js

@@ -1330,12 +1330,12 @@ export default class RoadService {
     let rightEdge = dataService.getRoadEdge(road.rightEdgeId);
     let edgePoints;
     if (road.way == Constant.oneWay) {
-      edgePoints = mathUtil.RectangleVertex(startPoint, endPoint, newWidth);
+      edgePoints = mathUtil.RectangleVertex(startPoint, endPoint, newWidth * 2);
       mathUtil.clonePoint(leftEdge.start, edgePoints.leftEdgeStart);
       mathUtil.clonePoint(leftEdge.end, edgePoints.leftEdgeEnd);
       mathUtil.clonePoint(rightEdge.start, edgePoints.rightEdgeStart);
       mathUtil.clonePoint(rightEdge.end, edgePoints.rightEdgeEnd);
-      road.setWidth(newWidth);
+      road.setWidth(newWidth * 2);
     } else if (road.way == Constant.twoWay) {
       if (dir == "left") {
         edgePoints = mathUtil.RectangleVertex(

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

@@ -102,4 +102,5 @@ export default class StateService {
 }
 
 const stateService = new StateService();
+window.stateService = stateService;
 export { stateService };

+ 37 - 3
src/graphic/Util/MathUtil.js

@@ -596,6 +596,12 @@ export default class MathUtil {
     p1.y = p2.y;
   }
 
+  clonePoints(points1, points2) {
+    for (let i = 0; i < points1.length; ++i) {
+      this.clonePoint(points1[i], points2[i]);
+    }
+  }
+
   equalPoint(p1, p2) {
     if (p1.x == p2.x && p1.y == p2.y) {
       return true;
@@ -604,6 +610,34 @@ export default class MathUtil {
     }
   }
 
+  equalPoints(points1, points2) {
+    for (let i = 0; i < points1.length; ++i) {
+      let flag = this.equalPoint(points1[i], points2[i]);
+      if (!flag) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  equalJSON(json1, json2) {
+    for (let key in json1) {
+      if (json2.hasOwnProperty(key) && json1[key] == json2[key]) {
+        continue;
+      } else {
+        return false;
+      }
+    }
+    for (let key in json2) {
+      if (json1.hasOwnProperty(key) && json1[key] == json2[key]) {
+        continue;
+      } else {
+        return false;
+      }
+    }
+    return true;
+  }
+
   crossTwoLines(point1, point2, point3, point4, dis) {
     if (typeof dis == "undefined") {
       dis = Constant.minAdsorbPix;
@@ -1159,11 +1193,11 @@ export default class MathUtil {
   }
   // 中心点
   lineCenter(v1, v2) {
-    const point = this.pointPlus(v1, v2)
+    const point = this.pointPlus(v1, v2);
     return {
       x: point.x / 2,
-      y: point.y / 2
-    }
+      y: point.y / 2,
+    };
   }
   // 点放大
   pointScale(v, a) {

+ 2 - 1
src/graphic/enum/LayerEvents.js

@@ -27,8 +27,9 @@ const LayerEvents = {
   MoveEdge: "moveEdge",
   MoveCurveEdge: "moveCurveEdge",
 
+  AddCurveLine: "addCurveLine",
+  AddingCurveLine: "addingCurveLine",
   MoveCurveLine: "moveCurveLine",
-  MoveLine: "moveLine",
 
   AddText: "addText",
   MoveText: "moveText",

+ 2 - 0
src/graphic/enum/UIEvents.js

@@ -1,6 +1,8 @@
 const UIEvents = {
   // 画线
   Line: "line",
+  // 画曲线
+  CurveLine: "Curveline",
   // 画圆
   Circle: "Circle",
   // 图例

+ 1 - 0
src/hook/useParams.ts

@@ -8,6 +8,7 @@ export type Params = {
   lang?: langNameEum;
   test?: boolean;
   token?: string;
+  realPath?: string
   entry?: string;
   unit?: string;
   kankan?: boolean;

+ 2 - 2
src/main.ts

@@ -1,9 +1,9 @@
 import VConsole from 'vconsole';
-if (import.meta.env.DEV) {
+// if (import.meta.env.DEV) {
   if (!os.isPc) {
     new VConsole();
   }
-}
+// }
 
 import "@/assets/theme.editor.scss";
 import "@/assets/public.scss";

+ 1 - 1
src/store/photos.ts

@@ -6,7 +6,7 @@ export type PhotoRaw = {
   url: string
   meterPerPixel: number
   time: number,
-  measures: Array<Pos[]>,
+  measures: { pos: Pos[], dis: number}[],
   fixPoints: Array<Pos>,
   basePoints: Array<Pos>
   baseLines: Array<Pos[]>

+ 40 - 44
src/store/sync.ts

@@ -14,22 +14,7 @@ import {baseURL} from "@/dbo/local";
 
 const global = window as any;
 
-global.getImageCallback = () => {
-  console.log("原始getImageCallback");
-};
-global.getSceneStoreCallback = () => {
-  console.log("原始getSceneStoreCallback");
-};
-global.setSceneStoreCallback = () => {
-  console.log("原始setSceneStoreCallback");
-};
-global.uploadImageCallback = () => {
-  console.log("原始uploadImageCallback");
-};
-global.downloadImageCallback = () => {
-  console.log("原始downloadImageCallback");
-};
-
+let count = 0;
 export const api =
   import.meta.env.DEV && !global.android
     ? // const api = import.meta.env.DEV
@@ -52,15 +37,18 @@ export const api =
         },
         async downloadImage(file) {
           window.open(URL.createObjectURL(file));
+          return true;
         },
         async getFile(url) {
+          console.log(baseURL + url)
+          return baseURL + url.trim();
+
           if (url.includes(baseURL)) {
             url = url.substring(baseURL.length);
           }
           url = url.trim();
           const data = await axios.get(url, { responseType: "blob" });
           const base64 = await blobToBase64(data.data);
-          console.log("请求url:" + url, "返回:" + base64.substring(0, 20))
           return base64
         },
         async closePage() {
@@ -68,23 +56,18 @@ export const api =
         },
       }
     : {
-        // async setStore(data) {
-        //   return axios.post("sceneStore", data)
-        // },
-        // async getStore() {
-        //   return (await axios.get("/attach/sceneStore")).data
-        // },
         setStore(data) {
           return new Promise((resolve) => {
             console.log("调用setSceneStore参数", JSON.stringify(data));
-            global.android.setSceneStore(
-              params.m + "/store.json",
-              JSON.stringify(data)
-            );
             global.setSceneStoreCallback = (data) => {
               console.log("setSceneStoreCallback返回", data);
               resolve(data);
             };
+            global.android.setSceneStore(
+              params.m + "/store.json",
+              JSON.stringify(data),
+              "setSceneStoreCallback"
+            );
           });
         },
         getStore() {
@@ -94,53 +77,64 @@ export const api =
               console.log("getSceneStoreCallback返回", data);
               resolve(data);
             };
-            global.android.getSceneStore(params.m + "/store.json");
+            global.android.getSceneStore(params.m + "/store.json", "getSceneStoreCallback");
           });
         },
         getFile(fileUrl: string) {
           fileUrl = fileUrl.trim();
+          if (fileUrl.includes(params.m)) {
+            fileUrl = fileUrl.substring(fileUrl.indexOf(params.m) + params.m.length)
+          }
+          fileUrl = new URL(fileUrl, "http://www.a.com").pathname
+          fileUrl = (params.realPath || params.m) + fileUrl
+          console.error("处理后url:" + fileUrl)
+
           if (import.meta.env.DEV) {
             return new Promise<string>((resolve) => {
-              global.getImageCallback = (base64) => {
-                console.error("getImageCallback返回");
-                // console.error("getFile", fileUrl, base64)
+              const apiName = `getImageCallback${count++}`
+              global[apiName] = (base64) => {
+                console.error("请求url:" + fileUrl, "返回:" + base64.substring(0, 60))
                 resolve(base64);
+                delete global[apiName]
               };
-              if (fileUrl.includes(params.m)) {
-                fileUrl = fileUrl.substring(fileUrl.indexOf(params.m) + params.m.length)
-              }
-              fileUrl = new URL(fileUrl, "http://www.a.com").pathname
-              global.android.getImage(params.m + fileUrl);
-              console.log(global, global.getImageCallback);
+              global.android.getImage(fileUrl, apiName);
             });
           } else {
+            console.log("请求文件" + fileUrl)
             return Promise.resolve(fileUrl);
           }
         },
         uploadImage(file: File) {
           return new Promise<string>(async (resolve) => {
-            global.uploadImageCallback = (data) => {
+            const apiName = `uploadImageCallback${count++}`
+            global[apiName] = (data) => {
               console.log("上传图片成功,返回路径为:", data)
               resolve(data);
+              delete global[apiName]
             }
             const data = await blobToBase64(file);
             // console.log("上传图片", params.m + "/" + file.name, "参数:", data);
-            global.android.uploadImage(params.m + "/" + file.name, data);
+            global.android.uploadImage(params.m + "/attach/upload/" + file.name, data, apiName);
           });
         },
         downloadImage(file: File) {
-          return new Promise(async (resolve) => {
-            global.downloadImageCallback = resolve;
+          return new Promise<boolean>(async (resolve) => {
+            const apiName = `downloadImageCallback${count++}`
+            global[apiName] = () => {
+              console.log("已成功下载")
+              resolve(true);
+              delete global[apiName]
+            }
             const data = await blobToBase64(file);
             // file为base64
             console.log("下载图片", file.name);
-            global.android.downloadImage(file.name, data);
+            global.android.downloadImage(file.name, data, apiName);
           });
         },
         closePage() {
           return new Promise((resolve) => {
             global.closeWebViewCallback = resolve;
-            global.android.closeWebView();
+            global.android.closeWebView('closeWebViewCallback');
           });
         },
       };
@@ -182,7 +176,9 @@ export const downloadImage = async (
       ? (await axios.get(data, { responseType: "blob" })).data
       : data;
   const file = new File([blob], name, { type: "image/jpeg" });
-  await api.downloadImage(file);
+
+
+  return await api.downloadImage(file);
 };
 
 const syncSceneStore = () => {

+ 5 - 1
src/views/accidents/index.vue

@@ -81,12 +81,14 @@ const selects = ref<AccidentPhoto[]>([])
 const active = ref<AccidentPhoto>()
 const menus = [
   {
-    key: "road",
+    key: "edit",
+    icon: "edit",
     text: "修改",
     onClick: () => gotoDraw()
   },
   {
     key: "del",
+    icon: "del",
     text: "删除",
     onClick: () => delPhoto()
   }
@@ -95,6 +97,7 @@ const menus = [
 const selectMenus = reactive([
   {
     key: "gen",
+    icon: "photo",
     text: "生成A4",
     disabled: computed(() => selects.value.length > 2),
     onClick: () => {
@@ -108,6 +111,7 @@ const selectMenus = reactive([
   {
     key: "del",
     text: "删除",
+    icon: "del",
     onClick: () => delSelects()
   },
 ])

+ 2 - 2
src/views/accidents/print.vue

@@ -54,8 +54,8 @@ const saveHandler = async () => {
   const blob = await new Promise<Blob>(
     resolve => canvas.toBlob(resolve, "image/jpeg", 0.95)
   )
-  await downloadImage(blob)
-  const hide = Message.success({ msg: "照片已生成" })
+  const success = await downloadImage(blob)
+  const hide = Message.success({ msg: success  ? "照片已生成" : "照片生成失败" })
   setTimeout(() => {
     hide()
     back()

+ 1 - 1
src/views/graphic/geos/arrow.vue

@@ -27,7 +27,7 @@ const props = defineProps<{geo: FocusVector}>()
 const vector = computed(() => dataService.getLine(props.geo.vectorId))
 const color = ref("#000000")
 useChange(() => {
-  color.value = vector.value.arrowColor
+  color.value = vector.value.color
 })
 
 

+ 11 - 4
src/views/graphic/header.vue

@@ -12,7 +12,7 @@
           :class="{disabled: menu.disable}"
           @click="menu.onClick"
       >
-        <ui-icon type="close"  />
+        <ui-icon :type="menu.icon"  />
         <p>{{ menu.text }}</p>
       </div>
     </div>
@@ -58,6 +58,7 @@ const menus = computed<{disable?: boolean, text: string, onClick: () => void}[]>
   const menus = [
     {
       text: "回退",
+      icon: "backout",
       disable: !graphicState.value.canRevoke,
       onClick: () => {
         drawRef.value.uiControl.menu_revoke()
@@ -66,6 +67,7 @@ const menus = computed<{disable?: boolean, text: string, onClick: () => void}[]>
     },
     {
       text: "前进",
+      icon: "redo",
       disable: !graphicState.value.canRecovery,
       onClick: () => {
         drawRef.value.uiControl.menu_recovery()
@@ -74,12 +76,14 @@ const menus = computed<{disable?: boolean, text: string, onClick: () => void}[]>
     },
     {
       text: "清除",
+      icon: "reset",
       onClick: () => {
         drawRef.value.uiControl.menu_clear()
         changeStore()
       }
     },
     {
+      icon: "recover",
       text: "恢复",
       onClick: () => drawRef.value.uiControl.menu_view_reset()
     }
@@ -87,12 +91,15 @@ const menus = computed<{disable?: boolean, text: string, onClick: () => void}[]>
 
   if (isRoad.value) {
     menus.push({
+      icon: "map",
       text: `底图${graphicState.value.showBackImage ? '关' : '开'}`,
       onClick: () => drawRef.value.uiControl.menu_backgroundImg(!graphicState.value.showBackImage)
-    }, {
-      text: `保存`,
-      onClick: () => drawRef.value.uiControl.menu_backgroundImg(!graphicState.value.showBackImage)
     })
+    // , {
+    //   icon: "map",
+    //   text: `保存`,
+    //   onClick: () => drawRef.value.uiControl.menu_backgroundImg(!graphicState.value.showBackImage)
+    // }
   }
   return menus
 })

+ 2 - 2
src/views/graphic/index.vue

@@ -12,7 +12,7 @@
 
     <GraphicAction class="full-action">
       <ui-icon
-        :type="isFull ? 'lessen' : 'full'"
+        :type="isFull ? 'screen_c' : 'screen_f'"
         ctrl
         @click="customMap.sysView = isFull ? 'auto' : 'full'"
       />
@@ -50,7 +50,7 @@ const store = computed(() => generateMixMenus(
     title: mainMenuRaw.text,
     name: mainMenuRaw.key,
     isRoute: false,
-    icon: 'menu',
+    // icon: 'menu',
     bottom:  mainMenuRaw.key === UITypeExtend.setup
   }),
   menusRaws.value

+ 33 - 30
src/views/graphic/menus.ts

@@ -78,10 +78,11 @@ export const templateMenusRaw = [
 export const measureMenusRaw = [
   {
     key: UIType.BaseLine,
+    icon: "line",
     text: "基准线",
     disabled: computed(() => graphicState.value.existsBaseLine)
   },
-  { key: UIType.BasePoint, text: "基准点" },
+  { key: UIType.BasePoint, text: "基准点", icon: "point", },
   { key: UIType.NormalLocationMode, text: "自由测量" },
   {
     key: UIType.AngleLocationMode,
@@ -108,54 +109,56 @@ export const measureMenusRaw = [
 ]
 
 export const mainMenusRaw: MenusRaw = [
-  { key: UIType.Line, text: "画线" },
+  { key: UIType.Line, text: "画线", icon: "line_d" },
 
   // { key: UIType.Img, text: "图例" },
   {
     key: UITypeExtend.measure,
     text: "测量",
-    children: measureMenusRaw
+    children: measureMenusRaw,
+    icon: "measure"
   },
   // { key: UIType.MeasureLine, text: "测量" },
-  { key: UIType.Text, text: "文字" },
-  { key: UIType.Magnifier, text: "放大镜" },
+  { key: UIType.Text, text: "文字", icon: "text" },
+  { key: UIType.Magnifier, text: "放大镜", icon: "magnify_g" },
   // { key: UITypeExtend.photo, text: "照片库" },
   // { key: UITypeExtend.setup, text: "设置" },
 ];
 
 if (import.meta.env.DEV) {
-  // mainMenusRaw.unshift(
-  //   { key: UIType.CurveRoad, text: "弯路" }
-  // )
-  // mainMenusRaw.splice(1, 0, {
-  //   key: UITypeExtend.road,
-  //   text: "道路",
-  //   children: [
-  //     { key: UIType.OneEdgeOneLanRoad, text: "单向单车道直路" },
-  //     { key: UIType.OneEdgeTwoLanRoad, text: "单向双车道直路" },
-  //     { key: UIType.OneEdgeThreeLanRoad, text: "单向三车道直路" },
-  //     { key: UIType.TwoEdgeOneLanRoad, text: "双向单车道直路" },
-  //     { key: UIType.TwoEdgeTwoLanRoad, text: "双向双车道直路" },
-  //     { key: UIType.TwoEdgeThreeLanRoad, text: "双向三车道直路" },
-  //     { key: UITypeExtend.structure, text: "道路结构", extend: structureMenusRaw },
-  //     { key: UITypeExtend.template, text: "道路模板", extend: templateMenusRaw },
-  //   ]
-  // },)
+  mainMenusRaw.unshift(
+    { key: UIType.CurveRoad, text: "弯路", icon: "road", }
+  )
+  mainMenusRaw.splice(1, 0, {
+    key: UITypeExtend.road,
+    text: "道路",
+    icon: "road",
+    children: [
+      { key: UIType.OneEdgeOneLanRoad, text: "单向单车道直路" },
+      { key: UIType.OneEdgeTwoLanRoad, text: "单向双车道直路" },
+      { key: UIType.OneEdgeThreeLanRoad, text: "单向三车道直路" },
+      { key: UIType.TwoEdgeOneLanRoad, text: "双向单车道直路" },
+      { key: UIType.TwoEdgeTwoLanRoad, text: "双向双车道直路" },
+      { key: UIType.TwoEdgeThreeLanRoad, text: "双向三车道直路" },
+      { key: UITypeExtend.structure, text: "道路结构", extend: structureMenusRaw },
+      { key: UITypeExtend.template, text: "道路模板", extend: templateMenusRaw },
+    ]
+  },)
 }
 
 export const photoMenusRaw: MenusRaw = [
-  { key: UIType.Text, text: "文字" },
-  { key: UIType.Circle, text: "圈出" },
-  { key: UIType.Arrow, text: "箭头" },
-  { key: UIType.Magnifier, text: "放大镜" },
+  { key: UIType.Text, text: "文字", icon: "text" },
+  { key: UIType.Circle, text: "圈出", icon: "circle" },
+  { key: UIType.Arrow, text: "箭头", icon: "arrows" },
+  { key: UIType.Magnifier, text: "放大镜", icon: "magnify_g" },
 ]
 
 
 export const headActionMenuRaw = [
-  { key: UIType.GoBack, text: "回退" },
-  { key: UIType.GoAhead, text: "前进" },
-  { key: UIType.Clear, text: "清除" },
-  { key: UIType.BackImageChange, text: "底图开关" },
+  { key: UIType.GoBack, text: "回退", icon: "backout" },
+  { key: UIType.GoAhead, text: "前进", icon: "redo" },
+  { key: UIType.Clear, text: "清除", icon: "reset" },
+  { key: UIType.BackImageChange, text: "底图开关", icon: "map" },
 ]
 
 export const focusMenuRaw : { [key in string]: MenusRaw } = {

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

@@ -15,7 +15,7 @@
       :data="sortPhotos"
     />
     <ButtonPane class="back fun-ctrl" @click="router.push(writeRouteName.scene)" v-if="!selectMode">
-      <ui-icon type="close" class="icon" />
+      <ui-icon type="photo" class="icon" />
     </ButtonPane>
 
     <ActionMenus class="select-menus" :menus="selectMenus" dire="row" v-if="selects.length" />
@@ -50,15 +50,18 @@ const menus = [
   {
     key: "road",
     text: "现场绘图",
+    icon: "draw_s",
     onClick: () => gotoDraw(Mode.Road)
   },
   {
     key: "accident",
+    icon: "label",
     text: "照片标注",
     onClick: () => gotoDraw(Mode.Photo)
   },
   {
     key: "del",
+    icon: "del",
     text: "删除",
     onClick: () => delPhoto()
   }
@@ -67,6 +70,7 @@ const menus = [
 const selectMenus = [
   {
     key: "del",
+    icon: "del",
     text: "删除",
     onClick: () => delSelects()
   },

+ 3 - 0
src/views/roads/index.vue

@@ -72,11 +72,13 @@ const selects = ref<RoadPhoto[]>([])
 const menus = [
   {
     key: "road",
+    icon: "edit",
     text: "修改",
     onClick: () => gotoDraw()
   },
   {
     key: "del",
+    icon: "del",
     text: "删除",
     onClick: () => delPhoto()
   }
@@ -85,6 +87,7 @@ const menus = [
 const selectMenus = [
   {
     key: "del",
+    icon: "del",
     text: "删除",
     onClick: () => delSelects()
   },

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

@@ -91,6 +91,7 @@
                     :style="{transform: compassCSSMatrix}"
                     ref="compassRef"
                 />
+                <p class="compass-info">比例1 : {{ proportion }}</p>
               </div>
             </td>
           </tr>
@@ -126,7 +127,7 @@
 <script setup lang="ts">
 import { router, writeRouteName } from '@/router'
 import { formatDate } from "@/utils";
-import {computed, nextTick, ref} from "vue";
+import {computed, nextTick, ref, watchEffect} from "vue";
 import { useHistory } from '@/hook/useHistory'
 import {roadPhotos, RoadPhoto, getDefaultTable} from "@/store/roadPhotos";
 import {useStaticUrl} from "@/hook/useStaticUrl";
@@ -152,6 +153,7 @@ const roadPhoto = computed<RoadPhoto>(() => {
 const history = computed(
   () => roadPhoto.value && useHistory(getDefaultTable(roadPhoto.value))
 )
+
 const input = () => history.value.state.hasRedo = false
 
 const compassRef = ref<HTMLImageElement>()
@@ -175,8 +177,25 @@ const { cssMatrix: photoCSSMatrix, matrix: photoMatrix } = useHand(
   history.value.value.imageTransform
 )
 
+const photoWidth = ref(0)
+watchEffect(() => {
+  if (photoRef.value) {
+    photoRef.value.onload = () => {
+      photoWidth.value = photoRef.value.naturalWidth
+    }
+  }
+})
+const proportion = ref(1)
+watchEffect(() => {
+  if (!roadPhoto.value || !photoRef.value) {
+    return;
+  }
+  const prop = ((photoWidth.value / photoRef.value.width) * (roadPhoto.value.data.scale || 1)) / photoMatrix.value[0]
+  proportion.value = Math.ceil(prop * 100) / 100
+})
+
+
 const onBack = () => {
-  console.log("????")
   router.replace({
     name: writeRouteName.graphic,
     params: {mode: Mode.Road, id: roadPhoto.value.id, action: 'update'}
@@ -240,10 +259,23 @@ const saveHandler = async () => {
       align-items: center;
     }
     .compass {
+      top: 20px;
+    }
+    .compass,
+    .compass-info {
       position: absolute;
       right: 20px;
+      width: 128px;
+      height: 128px;
       top: 20px;
-      width: 60px;
+    }
+    .compass-info {
+      text-align: center;
+      color: #000;
+      font-size: 16px;
+      margin-top: 128px;
+      pointer-events: none;
+      white-space: nowrap;
     }
   }
 }

+ 3 - 2
src/views/scene/container.vue

@@ -88,7 +88,8 @@ onMounted(async () => {
     width: 20px !important;
     height: 20px !important;
     font-family: "iconfont" !important;
-    font-size: 16px;
+    font-size: 20px;
+    color: #fff;
     font-style: normal;
     -webkit-font-smoothing: antialiased;
     background: none !important;
@@ -96,7 +97,7 @@ onMounted(async () => {
     color: #fff;
 
     &:before {
-      content: "\e633";
+      content: "\e73e";
       pointer-events: none;
     }
   }

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

@@ -23,34 +23,34 @@ export enum menuEnum {
 
 export const menus: MenuRaw[] = [
   {
-    icon: "",
+    icon: "save",
     text: "保存",
     key: menuEnum.SAVE
   },
   {
-    icon: "",
+    icon: "clear",
     text: "清除",
     key: menuEnum.CLEAR
   },
   {
-    icon: "",
+    icon: "measure",
     text: "测量",
     key: "measure",
     children: [
       {
-        icon: "",
+        icon: "line_h",
         // continued: true,
         text: "水平",
         key: menuEnum.MEASURE_ROW
       },
       {
-        icon: "",
+        icon: "line_v",
         continued: true,
         text: "垂直",
         key: menuEnum.MEASURE_COLUMN
       },
       {
-        icon: "",
+        icon: "line_f",
         continued: true,
         text: "自由",
         key: menuEnum.MEASURE_FREE
@@ -58,29 +58,29 @@ export const menus: MenuRaw[] = [
     ]
   },
   {
-    icon: "",
+    icon: "point_f",
     text: "固定点",
     key: "fixPointMenu",
     children: [
       {
-        icon: "",
+        icon: "point_a",
         text: "固定点",
         key: menuEnum.FIX_POINT
       },
     ]
   },
   {
-    icon: "",
+    icon: "standard",
     text: "基准线/点",
     key: "baseLineOrPoint",
     children: [
       {
-        icon: "",
+        icon: "line",
         text: "基准线",
         key: menuEnum.BASE_LINE
       },
       {
-        icon: "",
+        icon: "point",
         text: "基准点",
         key: menuEnum.BASE_POINT
       },

+ 1 - 1
src/views/scene/menus/pane.vue

@@ -26,7 +26,7 @@ const props = withDefaults(
 )
 const emit = defineEmits<{ (e: 'back'): void }>();
 const backMenu = {
-  icon: "",
+  icon: "return",
   text: "返回",
   key: "back",
   onClick: () => emit("back")

+ 4 - 4
src/views/scene/mode.vue

@@ -15,13 +15,13 @@ import {customMap} from "@/hook";
 const tabs = [
   {
     mode: Mode.pano,
-    icon: "show_pic_n",
-    activeIcon: "show_pic_s",
+    icon: "point_c_f",
+    activeIcon: "point_c_t",
   },
   {
     mode: Mode.cloud,
-    icon: "show_dot_n",
-    activeIcon: "show_dot_s",
+    icon: "panorama_f",
+    activeIcon: "panorama_t",
   },
 ];
 

+ 14 - 4
src/views/scene/photo.vue

@@ -3,7 +3,7 @@
 
   <div class="photo-layout">
     <ButtonPane class="photo-btn fun-ctrl" size="80" @click="photo">
-      <ui-icon type="close" class="icon" />
+      <ui-icon type="photo" class="icon" />
     </ButtonPane>
 
     <img
@@ -58,7 +58,6 @@ const photo = genUseLoading(async () => {
     dom.offsetHeight
   )
   const {dataUrl: base64} = await data.finishPromise
-  console.log(data)
   const blob = base64ToBlob(base64)
   tempPhoto.value = URL.createObjectURL(blob)
 
@@ -79,8 +78,15 @@ const photo = genUseLoading(async () => {
       time: new Date().getTime(),
       meterPerPixel: data.meterPerPixel,
       measures: list.value
-        .map(data => getCurrentScreens(data.points))
-        .filter(poss => poss.length),
+        .map(data => {
+          const pos = getCurrentScreens(data.points)
+          if (pos.length) {
+            return { pos, dis: sdk.carry.measureMap.get(data).getDistance().value }
+          } else {
+            return null
+          }
+        })
+        .filter(poss => poss),
       baseLines: baseLines.value
         .map(data => getCurrentScreens(data.points))
         .filter(poss => poss.length),
@@ -117,6 +123,10 @@ const photo = genUseLoading(async () => {
 .photo-btn {
   position: static;
   margin-bottom: 16px;
+
+  .icon {
+    font-size: 28px;
+  }
 }
 
 .cover {

+ 1 - 0
vite.config.ts

@@ -28,6 +28,7 @@ export default async ({ mode }) => {
   }
 
   return defineConfig({
+    base: "./",
     mode,
     build: {
       sourcemap: true,