Browse Source

地图加入控件

李富豪 1 year ago
parent
commit
b0db96b587

+ 0 - 256
Web/package-lock.json

@@ -10,7 +10,6 @@
       "license": "ISC",
       "dependencies": {
         "@amap/amap-jsapi-loader": "^1.0.1",
-        "agora-rtc-sdk-ng": "^4.12.1",
         "ant-design-vue": "^2.2.8",
         "axios": "^0.21.1",
         "eventemitter3": "^5.0.0",
@@ -33,67 +32,6 @@
         "vite-plugin-vconsole": "^2.1.0"
       }
     },
-    "node_modules/@agora-js/media": {
-      "version": "4.21.0",
-      "resolved": "https://registry.npmmirror.com/@agora-js/media/-/media-4.21.0.tgz",
-      "integrity": "sha512-X4aV84/gB4O7GOOkwP3+NGTHtT2IVkpa4DFBTlBNl7hrkjDwUeanzCQZyva92Zyw59N0NI6dKh9CjJKoIL5Now==",
-      "dependencies": {
-        "@agora-js/report": "4.21.0",
-        "@agora-js/shared": "4.21.0",
-        "agora-rte-extension": "^1.2.4",
-        "axios": "^1.6.8",
-        "pako": "^2.1.0",
-        "webrtc-adapter": "8.2.0"
-      }
-    },
-    "node_modules/@agora-js/media/node_modules/axios": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.2.tgz",
-      "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
-      "dependencies": {
-        "follow-redirects": "^1.15.6",
-        "form-data": "^4.0.0",
-        "proxy-from-env": "^1.1.0"
-      }
-    },
-    "node_modules/@agora-js/report": {
-      "version": "4.21.0",
-      "resolved": "https://registry.npmmirror.com/@agora-js/report/-/report-4.21.0.tgz",
-      "integrity": "sha512-c8KIdomuPItwvri431z5CPT7L4m+jLJrwWWt/QS3JN+sp/t49NnoOIyKQf3y5xCbyNPCNNeGofrwkaIRu4YE8g==",
-      "dependencies": {
-        "@agora-js/shared": "4.21.0",
-        "axios": "^1.6.8"
-      }
-    },
-    "node_modules/@agora-js/report/node_modules/axios": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.2.tgz",
-      "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
-      "dependencies": {
-        "follow-redirects": "^1.15.6",
-        "form-data": "^4.0.0",
-        "proxy-from-env": "^1.1.0"
-      }
-    },
-    "node_modules/@agora-js/shared": {
-      "version": "4.21.0",
-      "resolved": "https://registry.npmmirror.com/@agora-js/shared/-/shared-4.21.0.tgz",
-      "integrity": "sha512-oqaiuIhG9ai/NXUDEmj9b3uGxxU9I0OZZszNaJexjakJuVZPM7ypzrCLUi5SzkTh++QOf68yuvD488fjq5WQsA==",
-      "dependencies": {
-        "axios": "^1.6.8",
-        "ua-parser-js": "^0.7.34"
-      }
-    },
-    "node_modules/@agora-js/shared/node_modules/axios": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.2.tgz",
-      "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
-      "dependencies": {
-        "follow-redirects": "^1.15.6",
-        "form-data": "^4.0.0",
-        "proxy-from-env": "^1.1.0"
-      }
-    },
     "node_modules/@amap/amap-jsapi-loader": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz",
@@ -958,36 +896,6 @@
       "integrity": "sha512-x5LmiRLpRsd9KTjAB8MPKf0CDPMcuItjP0gbNqFCIgL1I8iYp4zglhj9w9FPCdIbHG2M91RVeIbArFfFTz9I3A==",
       "peer": true
     },
-    "node_modules/agora-rtc-sdk-ng": {
-      "version": "4.21.0",
-      "resolved": "https://registry.npmmirror.com/agora-rtc-sdk-ng/-/agora-rtc-sdk-ng-4.21.0.tgz",
-      "integrity": "sha512-EAZMdhbqIXl/PtFqEQn0O5Pmj3Tt+4oTXtd76MK1CozgbcDsc0TmFZK3qM25eaKqhzTz1wiVCwzBCWs3pF5OpQ==",
-      "dependencies": {
-        "@agora-js/media": "4.21.0",
-        "@agora-js/report": "4.21.0",
-        "@agora-js/shared": "4.21.0",
-        "agora-rte-extension": "^1.2.4",
-        "axios": "^1.6.8",
-        "formdata-polyfill": "^4.0.7",
-        "ua-parser-js": "^0.7.34",
-        "webrtc-adapter": "8.2.0"
-      }
-    },
-    "node_modules/agora-rtc-sdk-ng/node_modules/axios": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.2.tgz",
-      "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
-      "dependencies": {
-        "follow-redirects": "^1.15.6",
-        "form-data": "^4.0.0",
-        "proxy-from-env": "^1.1.0"
-      }
-    },
-    "node_modules/agora-rte-extension": {
-      "version": "1.2.4",
-      "resolved": "https://registry.npmmirror.com/agora-rte-extension/-/agora-rte-extension-1.2.4.tgz",
-      "integrity": "sha512-0ovZz1lbe30QraG1cU+ji7EnQ8aUu+Hf3F+a8xPml3wPOyUQEK6CTdxV9kMecr9t+fIDrGeW7wgJTsM1DQE7Nw=="
-    },
     "node_modules/ant-design-vue": {
       "version": "2.2.8",
       "resolved": "https://registry.npmmirror.com/ant-design-vue/-/ant-design-vue-2.2.8.tgz",
@@ -1042,11 +950,6 @@
       "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-3.5.2.tgz",
       "integrity": "sha512-8eLCg00W9pIRZSB781UUX/H6Oskmm8xloZfr09lz5bikRpBVDlJ3hRVuxxP1SxcwsEYfJ4IU8Q19Y8/893r3rQ=="
     },
-    "node_modules/asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
-    },
     "node_modules/axios": {
       "version": "0.21.4",
       "resolved": "https://registry.npmmirror.com/axios/-/axios-0.21.4.tgz",
@@ -1174,17 +1077,6 @@
         "fsevents": "~2.3.2"
       }
     },
-    "node_modules/combined-stream": {
-      "version": "1.0.8",
-      "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
-      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
-      "dependencies": {
-        "delayed-stream": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
     "node_modules/commist": {
       "version": "1.1.0",
       "resolved": "https://registry.npmmirror.com/commist/-/commist-1.1.0.tgz",
@@ -1260,14 +1152,6 @@
         }
       }
     },
-    "node_modules/delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/dom-align": {
       "version": "1.12.4",
       "resolved": "https://registry.npmmirror.com/dom-align/-/dom-align-1.12.4.tgz",
@@ -1357,28 +1241,6 @@
       "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.1.tgz",
       "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="
     },
-    "node_modules/fetch-blob": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmmirror.com/fetch-blob/-/fetch-blob-3.2.0.tgz",
-      "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/jimmywarting"
-        },
-        {
-          "type": "paypal",
-          "url": "https://paypal.me/jimmywarting"
-        }
-      ],
-      "dependencies": {
-        "node-domexception": "^1.0.0",
-        "web-streams-polyfill": "^3.0.3"
-      },
-      "engines": {
-        "node": "^12.20 || >= 14.13"
-      }
-    },
     "node_modules/fill-range": {
       "version": "7.1.1",
       "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
@@ -1410,30 +1272,6 @@
         }
       }
     },
-    "node_modules/form-data": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz",
-      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.8",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/formdata-polyfill": {
-      "version": "4.0.10",
-      "resolved": "https://registry.npmmirror.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
-      "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
-      "dependencies": {
-        "fetch-blob": "^3.1.2"
-      },
-      "engines": {
-        "node": ">=12.20.0"
-      }
-    },
     "node_modules/fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -1647,25 +1485,6 @@
         "@jridgewell/sourcemap-codec": "^1.4.15"
       }
     },
-    "node_modules/mime-db": {
-      "version": "1.52.0",
-      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
-      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mime-types": {
-      "version": "2.1.35",
-      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
-      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
     "node_modules/minimatch": {
       "version": "3.1.2",
       "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
@@ -1772,24 +1591,6 @@
       "resolved": "https://registry.npmmirror.com/nanopop/-/nanopop-2.4.2.tgz",
       "integrity": "sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw=="
     },
-    "node_modules/node-domexception": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmmirror.com/node-domexception/-/node-domexception-1.0.0.tgz",
-      "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/jimmywarting"
-        },
-        {
-          "type": "github",
-          "url": "https://paypal.me/jimmywarting"
-        }
-      ],
-      "engines": {
-        "node": ">=10.5.0"
-      }
-    },
     "node_modules/normalize-path": {
       "version": "3.0.0",
       "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -1821,11 +1622,6 @@
         "wrappy": "1"
       }
     },
-    "node_modules/pako": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmmirror.com/pako/-/pako-2.1.0.tgz",
-      "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
-    },
     "node_modules/path-is-absolute": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
@@ -1893,11 +1689,6 @@
       "resolved": "https://registry.npmmirror.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
       "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
     },
-    "node_modules/proxy-from-env": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
-      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
-    },
     "node_modules/pump": {
       "version": "3.0.0",
       "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz",
@@ -2036,11 +1827,6 @@
         "compute-scroll-into-view": "^1.0.20"
       }
     },
-    "node_modules/sdp": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmmirror.com/sdp/-/sdp-3.2.0.tgz",
-      "integrity": "sha512-d7wDPgDV3DDiqulJjKiV2865wKsJ34YI+NDREbm+FySq6WuKOikwyNQcm+doLAZ1O6ltdO0SeKle2xMpN3Brgw=="
-    },
     "node_modules/shallow-equal": {
       "version": "1.2.1",
       "resolved": "https://registry.npmmirror.com/shallow-equal/-/shallow-equal-1.2.1.tgz",
@@ -2124,28 +1910,6 @@
         "node": ">=14.17"
       }
     },
-    "node_modules/ua-parser-js": {
-      "version": "0.7.38",
-      "resolved": "https://registry.npmmirror.com/ua-parser-js/-/ua-parser-js-0.7.38.tgz",
-      "integrity": "sha512-fYmIy7fKTSFAhG3fuPlubeGaMoAd6r0rSnfEsO5nEY55i26KSLt9EH7PLQiiqPUhNqYIJvSkTy1oArIcXAbPbA==",
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/ua-parser-js"
-        },
-        {
-          "type": "paypal",
-          "url": "https://paypal.me/faisalman"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/faisalman"
-        }
-      ],
-      "engines": {
-        "node": "*"
-      }
-    },
     "node_modules/uevent": {
       "version": "2.2.0",
       "resolved": "https://registry.npmmirror.com/uevent/-/uevent-2.2.0.tgz",
@@ -2352,26 +2116,6 @@
         "loose-envify": "^1.0.0"
       }
     },
-    "node_modules/web-streams-polyfill": {
-      "version": "3.3.3",
-      "resolved": "https://registry.npmmirror.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
-      "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
-      "engines": {
-        "node": ">= 8"
-      }
-    },
-    "node_modules/webrtc-adapter": {
-      "version": "8.2.0",
-      "resolved": "https://registry.npmmirror.com/webrtc-adapter/-/webrtc-adapter-8.2.0.tgz",
-      "integrity": "sha512-umxCMgedPAVq4Pe/jl3xmelLXLn4XZWFEMR5Iipb5wJ+k1xMX0yC4ZY9CueZUU1MjapFxai1tFGE7R/kotH6Ww==",
-      "dependencies": {
-        "sdp": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=6.0.0",
-        "npm": ">=3.10.0"
-      }
-    },
     "node_modules/wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",

+ 0 - 1
Web/package.json

@@ -12,7 +12,6 @@
   },
   "dependencies": {
     "@amap/amap-jsapi-loader": "^1.0.1",
-    "agora-rtc-sdk-ng": "^4.12.1",
     "ant-design-vue": "^2.2.8",
     "axios": "^0.21.1",
     "eventemitter3": "^5.0.0",

+ 1 - 1
Web/src/api/pilot-bridge.ts

@@ -280,4 +280,4 @@ export default {
       localStorage.clear()
     }
   }
-}
+}

File diff suppressed because it is too large
+ 0 - 0
Web/src/assets/icons/end.svg


BIN
Web/src/assets/icons/hardstand.png


BIN
Web/src/assets/icons/plane.png


BIN
Web/src/assets/icons/satellite.png


File diff suppressed because it is too large
+ 0 - 0
Web/src/assets/icons/start.svg


+ 72 - 3
Web/src/components/GMap.vue

@@ -27,6 +27,18 @@
         </a>
       </div>
     </div>
+    <!-- 地图类型切换控件 -->
+    <div class="g-mapType" :style="{ right: drawVisible ? '316px' : '16px' }">
+      <img :src="planeSrc" v-if="state.mapType === 0" @click="onClickSwitchMapType" />
+      <img :src="satelliteSrc" v-else @click="onClickSwitchMapType" />
+    </div>
+    <!-- 最下方信息区域 -->
+    <div class="g-info">
+      <AimOutlined style="margin-right: 10px;" />
+      <div>
+        WGS 84
+      </div>
+    </div>
     <!-- 飞机OSD -->
     <div v-if="osdVisible.visible && !osdVisible.is_dock" v-drag-window class="osd-panel fz12">
       <div class="pl5 pr5 flex-align-center flex-row flex-justify-between"
@@ -534,8 +546,10 @@ import {
 } from '/@/types/device'
 import pin from '/@/assets/icons/pin-2d8cf0.svg'
 import M30 from '/@/assets/icons/m30.png'
+import planeSrc from '/@/assets/icons/plane.png'
+import satelliteSrc from '/@/assets/icons/satellite.png'
 import {
-  BorderOutlined, LineOutlined, CloseOutlined, ControlOutlined, TrademarkOutlined, ArrowDownOutlined,
+  BorderOutlined, LineOutlined, CloseOutlined, AimOutlined, ControlOutlined, TrademarkOutlined, ArrowDownOutlined,
   ThunderboltOutlined, SignalFilled, GlobalOutlined, HistoryOutlined, CloudUploadOutlined, RocketOutlined,
   FieldTimeOutlined, CloudOutlined, CloudFilled, FolderOpenOutlined, RobotFilled, ArrowUpOutlined, CarryOutOutlined
 } from '@ant-design/icons-vue'
@@ -546,7 +560,6 @@ import { useDockControl } from './g-map/use-dock-control'
 import DroneControlPanel from './g-map/DroneControlPanel.vue'
 import { useConnectMqtt } from './g-map/use-connect-mqtt'
 import LivestreamOthers from './livestream-others.vue'
-import LivestreamAgora from './livestream-agora.vue'
 import FlightAreaActionIcon from './flight-area/FlightAreaActionIcon.vue'
 import { EFlightAreaType } from '../types/flight-area'
 import { useFlightArea } from './flight-area/use-flight-area'
@@ -557,6 +570,7 @@ export default defineComponent({
     BorderOutlined,
     LineOutlined,
     CloseOutlined,
+    AimOutlined,
     ControlOutlined,
     TrademarkOutlined,
     ThunderboltOutlined,
@@ -577,7 +591,6 @@ export default defineComponent({
     CarryOutOutlined,
     RocketOutlined,
     LivestreamOthers,
-    LivestreamAgora,
     FlightAreaActionIcon,
   },
   name: 'GMap',
@@ -592,11 +605,20 @@ export default defineComponent({
     const mouseMode = ref(false)
     const store = useMyStore()
     const state = reactive({
+      mapType: 0,// 地图类型 0-普通 1-卫星
       currentType: '',
       coverIndex: 0,
       isFlightArea: false,
       deviceLiveStatus: false,// 设备直播状态
     })
+
+    // 点击切换地图类型
+    const onClickSwitchMapType = () => {
+      const mapType = state.mapType === 0 ? 1 : 0;
+      state.mapType = mapType;
+      useMouseToolHook.onChangeMapType(mapType);
+    }
+
     const str: string = '--'
     const deviceInfo: any = reactive({
       gateway: {
@@ -1051,7 +1073,10 @@ export default defineComponent({
       pin,
       state,
       M30,
+      planeSrc,
+      satelliteSrc,
       deviceInfo,
+      onClickSwitchMapType,
       EGear,
       EModeCode,
       str,
@@ -1112,6 +1137,40 @@ export default defineComponent({
   }
 }
 
+.g-mapType {
+  width: 28px;
+  height: 28px;
+  background: white;
+  border-radius: 2px;
+  line-height: 28px;
+  text-align: center;
+  position: absolute;
+  bottom: 50px;
+  right: 16px;
+  cursor: pointer;
+
+  img {
+    width: 18px;
+    height: 18px;
+  }
+}
+
+.g-info {
+  width: 100%;
+  height: 26px;
+  padding: 0 16px;
+  background: rgba(255, 255, 255, 0.7);
+  border-radius: 2px;
+  line-height: 28px;
+  text-align: center;
+  position: absolute;
+  bottom: 0;
+  right: 0;
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+}
+
 .osd-panel {
   position: absolute;
   margin-left: 10px;
@@ -1191,4 +1250,14 @@ export default defineComponent({
   height: 660px;
   background: #232323;
 }
+</style>
+
+<style lang="scss">
+.amap-logo {
+  display: none !important;
+}
+
+.amap-copyright {
+  display: none !important;
+}
 </style>

+ 7 - 1
Web/src/components/common/nav.vue

@@ -7,6 +7,12 @@
           设备管理
         </span>
       </a-menu-item>
+      <a-menu-item :key="'/' + ERouterName.WORKSPACE">
+        <CodepenOutlined />
+        <span>
+          项目工作空间
+        </span>
+      </a-menu-item>
       <a-menu-item :key="'/' + ERouterName.TASK">
         <ContainerOutlined />
         <span>
@@ -36,7 +42,7 @@
 </template>
 <script lang="ts" setup>
 import { reactive, watchEffect } from 'vue';
-import { GatewayOutlined, ContainerOutlined, HddOutlined, PictureOutlined, VideoCameraOutlined, TeamOutlined } from '@ant-design/icons-vue';
+import { GatewayOutlined, CodepenOutlined, ContainerOutlined, HddOutlined, PictureOutlined, VideoCameraOutlined, TeamOutlined } from '@ant-design/icons-vue';
 import { ERouterName } from '/@/types/enums';
 import router from '/@/router';
 

+ 3 - 4
Web/src/components/common/topbar.vue

@@ -2,9 +2,7 @@
   <div class="width-100 flex-row flex-justify-between flex-align-center"
     style="height: 60px;border-bottom: 1px solid #F0F2F5;">
     <div>
-      <a-button type="primary" @click="onClickToWorkspace">
-        项目工作空间
-      </a-button>
+      <img :src="logoSrc" style="width: 30px;height: 30px;">
     </div>
     <div style="cursor: pointer;" class="height-100 fz16 flex-row flex-justify-between flex-align-center">
       <a-dropdown>
@@ -31,10 +29,11 @@
 
 <script lang="ts" setup>
 import { onMounted, ref } from 'vue'
+import { UserOutlined, PoweroffOutlined } from '@ant-design/icons-vue'
+import logoSrc from '/@/assets/icons/cloudapi.png'
 import { getRoot } from '/@/root'
 import { getPlatformInfo } from '/@/api/manage'
 import { ELocalStorageKey, ERouterName } from '/@/types'
-import { UserOutlined, PoweroffOutlined } from '@ant-design/icons-vue'
 
 const root = getRoot()
 

+ 0 - 398
Web/src/components/livestream-agora.vue

@@ -1,398 +0,0 @@
-<template>
-  <div class="flex-column flex-justify-start flex-align-center">
-    <div id="player" style="width: 720px; height: 420px; border: 1px solid"></div>
-    <p class="fz24">Live streaming source selection</p>
-    <div class="flex-row flex-justify-center flex-align-center mt10">
-      <template v-if="livePara.liveState && dronePara.isDockLive">
-        <span class="mr10">Lens:</span>
-        <a-radio-group v-model:value="dronePara.lensSelected" button-style="solid">
-          <a-radio-button v-for="lens in dronePara.lensList" :key="lens" :value="lens">{{lens}}</a-radio-button>
-        </a-radio-group>
-      </template>
-      <template v-else>
-      <a-select
-        style="width:150px"
-        placeholder="Select Drone"
-        v-model:value="dronePara.droneSelected"
-      >
-        <a-select-option
-          v-for="item in dronePara.droneList"
-          :key="item.value"
-          :value="item.value"
-          @click="onDroneSelect(item)"
-          >{{ item.label }}</a-select-option
-        >
-      </a-select>
-      <a-select
-        class="ml10"
-        style="width:150px"
-        placeholder="Select Camera"
-        v-model:value="dronePara.cameraSelected"
-      >
-        <a-select-option
-          v-for="item in dronePara.cameraList"
-          :key="item.value"
-          :value="item.value"
-          @click="onCameraSelect(item)"
-          >{{ item.label }}</a-select-option
-        >
-      </a-select>
-      <!-- <a-select
-        class="ml10"
-        style="width:150px"
-        placeholder="Select Lens"
-        @select="onVideoSelect"
-      >
-        <a-select-option
-          v-for="item in dronePara.videoList"
-          :key="item.value"
-          :value="item.value"
-          >{{ item.label }}</a-select-option
-        >
-      </a-select> -->
-      </template>
-      <a-select
-        class="ml10"
-        style="width:150px"
-        placeholder="Select Clarity"
-        @select="onClaritySelect"
-      >
-        <a-select-option
-          v-for="item in clarityList"
-          :key="item.value"
-          :value="item.value"
-          >{{ item.label }}</a-select-option
-        >
-      </a-select>
-    </div>
-    <p class="fz16 mt10">
-      Note: Obtain The Following Parameters From https://console.agora.io
-    </p>
-    <div class="flex-row flex-justify-center flex-align-center">
-      <span class="mr10">AppId:</span>
-      <a-input v-model:value="agoraPara.appid" placeholder="APP ID"></a-input>
-      <span class="ml10">Token:</span>
-      <a-input
-        class="ml10"
-        v-model:value="agoraPara.token"
-        placeholder="Token"
-      ></a-input>
-      <span class="ml10">Channel:</span>
-      <a-input
-        class="ml10"
-        v-model:value="agoraPara.channel"
-        placeholder="Channel"
-      ></a-input>
-    </div>
-    <div class="mt20 flex-row flex-justify-center flex-align-center">
-      <a-button v-if="livePara.liveState && dronePara.isDockLive" type="primary" large @click="onSwitch">Switch Lens</a-button>
-      <a-button v-else type="primary" large @click="onStart">Play</a-button>
-      <a-button class="ml20" type="primary" large @click="onStop"
-        >Stop</a-button
-      >
-      <a-button class="ml20" type="primary" large @click="onUpdateQuality"
-        >Update Clarity</a-button
-      >
-      <a-button v-if="!livePara.liveState || !dronePara.isDockLive" class="ml20" type="primary" large @click="onRefresh"
-        >Refresh Live Capacity</a-button
-      >
-    </div>
-  </div>
-</template>
-
-<script lang="ts" setup>
-import AgoraRTC, { IAgoraRTCClient, IAgoraRTCRemoteUser } from 'agora-rtc-sdk-ng'
-import { message } from 'ant-design-vue'
-import { onMounted, reactive } from 'vue'
-import { uuidv4 } from '../utils/uuid'
-import { CURRENT_CONFIG as config } from '/@/api/http/config'
-import { changeLivestreamLens, getLiveCapacity, setLivestreamQuality, startLivestream, stopLivestream } from '/@/api/manage'
-import { getRoot } from '/@/root'
-
-const root = getRoot()
-
-const clarityList = [
-  {
-    value: 0,
-    label: 'Adaptive'
-  },
-  {
-    value: 1,
-    label: 'Smooth'
-  },
-  {
-    value: 2,
-    label: 'Standard'
-  },
-  {
-    value: 3,
-    label: 'HD'
-  },
-  {
-    value: 4,
-    label: 'Super Clear'
-  }
-]
-
-interface SelectOption {
-  value: any,
-  label: string,
-  more?: any
-}
-
-let agoraClient = {} as IAgoraRTCClient
-const agoraPara = reactive({
-  appid: config.agoraAPPID,
-  token: config.agoraToken,
-  channel: config.agoraChannel,
-  uid: 123456,
-  stream: {}
-})
-const dronePara = reactive({
-  livestreamSource: [],
-  droneList: [] as SelectOption[],
-  cameraList: [] as SelectOption[],
-  videoList: [] as SelectOption[],
-  droneSelected: undefined as string | undefined,
-  cameraSelected: undefined as string | undefined,
-  videoSelected: undefined as string | undefined,
-  claritySelected: 0,
-  lensList: [] as string[],
-  lensSelected: undefined as string | undefined,
-  isDockLive: false
-})
-const livePara = reactive({
-  url: '',
-  webrtc: {} as any,
-  videoId: '',
-  liveState: false
-})
-const nonSwitchable = 'normal'
-const onRefresh = async () => {
-  dronePara.droneList = []
-  dronePara.cameraList = []
-  dronePara.videoList = []
-  dronePara.droneSelected = undefined
-  dronePara.cameraSelected = undefined
-  dronePara.videoSelected = undefined
-  await getLiveCapacity({})
-    .then(res => {
-      if (res.code === 0) {
-        if (res.data === null) {
-          console.warn('warning: get live capacity is null!!!')
-          return
-        }
-        dronePara.livestreamSource = res.data
-        dronePara.droneList = []
-
-        console.log('live_capacity:', dronePara.livestreamSource)
-
-        if (dronePara.livestreamSource) {
-          dronePara.livestreamSource.forEach((ele: any) => {
-            dronePara.droneList.push({ label: ele.name + '-' + ele.sn, value: ele.sn, more: ele.cameras_list })
-          })
-        }
-      }
-    })
-    .catch(error => {
-      message.error(error)
-      console.error(error)
-    })
-}
-
-onMounted(() => {
-  onRefresh()
-  agoraClient = AgoraRTC.createClient({ mode: 'live', codec: 'vp8' })
-  agoraClient.setClientRole('audience', { level: 2 })
-  if (agoraClient.connectionState === 'DISCONNECTED') {
-    agoraClient.join(agoraPara.appid, agoraPara.channel, agoraPara.token)
-  }
-  // Subscribe when a remote user publishes a stream
-  agoraClient.on('user-joined', async (user: IAgoraRTCRemoteUser) => {
-    message.info('user[' + user.uid + '] join')
-  })
-  agoraClient.on('user-published', async (user: IAgoraRTCRemoteUser, mediaType: 'audio' | 'video') => {
-    await agoraClient.subscribe(user, mediaType)
-    if (mediaType === 'video') {
-      console.log('subscribe success')
-      // Get `RemoteVideoTrack` in the `user` object.
-      const remoteVideoTrack = user.videoTrack!
-      // Dynamically create a container in the form of a DIV element for playing the remote video track.
-      remoteVideoTrack.play(document.getElementById('player') as HTMLElement)
-    }
-  })
-  agoraClient.on('user-unpublished', async (user: any) => {
-    console.log('unpublish live:', user)
-    message.info('unpublish live')
-  })
-  agoraClient.on('exception', async (e: any) => {
-    console.log(e)
-    message.error(e.msg)
-  })
-})
-const handleError = (err: any) => {
-  console.error(err)
-}
-const handleJoinChannel = (uid: any) => {
-  agoraPara.uid = uid
-}
-const onStart = async () => {
-  const that = this
-  console.log(
-    'drone parameter:',
-    dronePara.droneSelected,
-    dronePara.cameraSelected,
-    dronePara.videoSelected,
-    dronePara.claritySelected
-  )
-  const timestamp = new Date().getTime().toString()
-  const liveTimestamp = timestamp
-  if (
-    dronePara.droneSelected == null ||
-    dronePara.cameraSelected == null ||
-    dronePara.claritySelected == null
-  ) {
-    message.warn('waring: not select live para!!!')
-    return
-  }
-  agoraClient.setClientRole('audience', { level: 2 })
-  if (agoraClient.connectionState === 'DISCONNECTED') {
-    await agoraClient.join(agoraPara.appid, agoraPara.channel, agoraPara.token)
-  }
-  livePara.videoId =
-    dronePara.droneSelected +
-    '/' +
-    dronePara.cameraSelected + '/' + (dronePara.videoSelected || nonSwitchable + '-0')
-  console.log(agoraPara)
-
-  livePara.url =
-    'channel=' +
-    agoraPara.channel +
-    '&sn=' +
-    dronePara.droneSelected +
-    '&token=' +
-    encodeURIComponent(agoraPara.token) +
-    '&uid=' +
-    agoraPara.uid
-
-  startLivestream({
-    url: livePara.url,
-    video_id: livePara.videoId,
-    url_type: 0,
-    video_quality: dronePara.claritySelected
-  })
-    .then(res => {
-      if (res.code !== 0) {
-        return
-      }
-      livePara.liveState = true
-    })
-    .catch(err => {
-      console.error(err)
-    })
-}
-const onStop = async () => {
-  if (
-    dronePara.droneSelected == null ||
-    dronePara.cameraSelected == null ||
-    dronePara.claritySelected == null
-  ) {
-    message.warn('waring: not select live para!!!')
-    return
-  }
-  livePara.videoId =
-    dronePara.droneSelected +
-    '/' +
-    dronePara.cameraSelected + '/' + (dronePara.videoSelected || nonSwitchable + '-0')
-
-  stopLivestream({
-    video_id: livePara.videoId
-  }).then(res => {
-    if (res.code === 0) {
-      message.success(res.message)
-      livePara.liveState = false
-      dronePara.lensSelected = ''
-      console.log('stop play livestream')
-    }
-  })
-}
-const onDroneSelect = (val: SelectOption) => {
-  dronePara.cameraList = []
-  dronePara.videoList = []
-  dronePara.lensList = []
-
-  dronePara.cameraSelected = undefined
-  dronePara.videoSelected = undefined
-  dronePara.lensSelected = undefined
-  dronePara.droneSelected = val.value
-  if (!val.more) {
-    return
-  }
-  val.more.forEach((ele: any) => {
-    dronePara.cameraList.push({ label: ele.name, value: ele.index, more: ele.videos_list })
-  })
-}
-const onCameraSelect = (val: SelectOption) => {
-  dronePara.cameraSelected = val.value
-  dronePara.videoSelected = undefined
-  dronePara.lensSelected = undefined
-  dronePara.videoList = []
-  dronePara.lensList = []
-  if (!val.more) {
-    return
-  }
-
-  val.more.forEach((ele: any) => {
-    dronePara.videoList.push({ label: ele.type, value: ele.index, more: ele.switch_video_types })
-  })
-  if (dronePara.videoList.length === 0) {
-    return
-  }
-  const firstVideo: SelectOption = dronePara.videoList[0]
-  dronePara.videoSelected = firstVideo.value
-  dronePara.lensList = firstVideo.more
-  dronePara.lensSelected = firstVideo.label
-  dronePara.isDockLive = dronePara.lensList?.length > 0
-}
-const onVideoSelect = (val: SelectOption) => {
-  dronePara.videoSelected = val.value
-  dronePara.lensList = val.more
-  dronePara.lensSelected = val.label
-}
-const onClaritySelect = (val: any) => {
-  dronePara.claritySelected = val
-}
-const onUpdateQuality = () => {
-  if (!livePara.liveState) {
-    message.info('Please turn on the livestream first.')
-    return
-  }
-  setLivestreamQuality({
-    video_id: livePara.videoId,
-    video_quality: dronePara.claritySelected
-  }).then(res => {
-    if (res.code === 0) {
-      message.success('Set the clarity to ' + clarityList[dronePara.claritySelected].label)
-    }
-  })
-}
-
-const onSwitch = () => {
-  if (dronePara.lensSelected === undefined || dronePara.lensSelected === nonSwitchable) {
-    message.info('The ' + nonSwitchable + ' lens cannot be switched, please select the lens to be switched.', 8)
-    return
-  }
-  changeLivestreamLens({
-    video_id: livePara.videoId,
-    video_type: dronePara.lensSelected
-  }).then(res => {
-    if (res.code === 0) {
-      message.success('Switching live camera successfully.')
-    }
-  })
-}
-</script>
-
-<style lang="scss" scoped>
-@import '/@/styles/index.scss';
-</style>

+ 1 - 1
Web/src/constants/index.ts

@@ -19,4 +19,4 @@ export const AMapConfig = {
     'AMap.MouseTool',
     'AMap.MoveAnimation'
   ]
-}
+}

+ 10 - 22
Web/src/hooks/use-g-map-trajectory.ts

@@ -1,6 +1,5 @@
 import { getRoot } from '/@/root'
-import startSrc from '/@/assets/icons/start.svg'
-import endSrc from '/@/assets/icons/end.svg'
+import hardstandSrc from '/@/assets/icons/hardstand.png'
 
 export function useGMapTrajectory() {
   const root = getRoot();
@@ -11,38 +10,27 @@ export function useGMapTrajectory() {
     // 绘制起点图标
     const startPosition = paths[0];
     const startIcon = new AMap.Icon({
-      size: new AMap.Size(40, 40),
-      image: startSrc,
-      imageSize: new AMap.Size(40, 40)
+      size: new AMap.Size(30, 30),
+      image: hardstandSrc,
+      imageSize: new AMap.Size(30, 30)
     })
     const startMarker = new AMap.Marker({
       position: new AMap.LngLat(startPosition[0], startPosition[startPosition.length - 1]),
       icon: startIcon,
-      offset: new AMap.Pixel(-20, -35)
-    })
-    // 绘制终点图标
-    const endPosition = paths[paths.length - 1];
-    const endIcon = new AMap.Icon({
-      size: new AMap.Size(40, 40),
-      image: endSrc,
-      imageSize: new AMap.Size(40, 40)
-    })
-    const endMarker = new AMap.Marker({
-      position: new AMap.LngLat(endPosition[0], endPosition[endPosition.length - 1]),
-      icon: endIcon,
-      offset: new AMap.Pixel(-20, -35)
+      offset: new AMap.Pixel(-20, -35),// 位置偏移
     })
     // 绘制轨迹折线
     const polyline = new AMap.Polyline({
       path: paths,
       strokeColor: '#2D8CF0',
-      strokeOpacity: 1,
-      strokeWeight: 2,
+      showDir: true,// 显示路线白色方向箭头
+      strokeOpacity: 1,// 轮廓线透明度
+      strokeWeight: 6,//线宽
       strokeStyle: 'solid',
     })
-    root.$map.add([startMarker, endMarker, polyline]);
+    root.$map.add([startMarker, polyline]);
     // 自动缩放地图到合适的视野级别
-    root.$map.setFitView([startMarker, endMarker, polyline]);
+    root.$map.setFitView([startMarker, polyline]);
   }
 
   return {

+ 4 - 1
Web/src/hooks/use-g-map.ts

@@ -14,10 +14,13 @@ export function useGMapManage() {
       ...AMapConfig
     }).then((AMap) => {
       state.aMap = AMap
-      state.map = new AMap.Map(container, {
+      const map = new AMap.Map(container, {
         center: [121.48, 31.22],
         zoom: 12
       })
+      const sale = new AMap.Scale();// 比例尺控件
+      map.addControl(sale);// 添加比例尺控件
+      state.map = map;
       state.mouseTool = new AMap.MouseTool(state.map)
       // 挂在到全局
       app.config.globalProperties.$aMap = state.aMap

+ 17 - 1
Web/src/hooks/use-mouse-tool.ts

@@ -131,7 +131,23 @@ export function useMouseTool() {
     }
   }
 
+  // 切换地图类型
+  const onChangeMapType = (type: number) => {
+    const AMap = root.$aMap;
+    const map = root.$map
+
+    map.remove(map.getLayers());
+    if (type === 0) {
+      // 标准图层
+      map.add(new AMap.createDefaultLayer());
+    } else if (type === 1) {
+      // 卫星图层
+      map.add(new AMap.TileLayer.Satellite());
+    }
+  }
+
   return {
-    mouseTool
+    mouseTool,
+    onChangeMapType
   }
 }

+ 2 - 0
Web/src/pages/page-pilot/pilot-home.vue

@@ -343,6 +343,7 @@ const connectCallback = async (arg: any) => {
     const wsParam: WsParam = components.get(EComponentName.Ws)
     wsParam.token = apiPilot.getToken()
     apiPilot.loadComponent(EComponentName.Ws, components.get(EComponentName.Ws))
+    console.log(wsParam, 'wsParam');
 
     // map
     const mapParam: MapParam = components.get(EComponentName.Map)
@@ -465,6 +466,7 @@ function refreshStatus() {
   wsState.value = apiPilot.isComponentLoaded(EComponentName.Ws) && apiPilot.wsGetConnectState()
     ? EStatusValue.CONNECTED
     : EStatusValue.DISCONNECT
+  console.log(wsState.value, 'wsState.value');
   mapState.value = apiPilot.isComponentLoaded(EComponentName.Map) ? EStatusValue.CONNECTED : EStatusValue.DISCONNECT
   tsaState.value = apiPilot.isComponentLoaded(EComponentName.Tsa) ? EStatusValue.CONNECTED : EStatusValue.DISCONNECT
   mediaState.value = apiPilot.isComponentLoaded(EComponentName.Media) ? EStatusValue.CONNECTED : EStatusValue.DISCONNECT

+ 2 - 1
Web/src/pages/page-web/projects/trajectory/index.vue

@@ -128,7 +128,8 @@ const columns = [
     title: '操作',
     dataIndex: 'actions',
     fixed: 'right',
-    width: 80,
+    align: 'center',
+    width: 50,
     slots: { customRender: 'action' },
   },
 ]

+ 1 - 3
Web/src/websocket/index.ts

@@ -1,6 +1,4 @@
-import { message } from 'ant-design-vue'
 import ReconnectingWebSocket from 'reconnecting-websocket'
-import { EBizCode } from '../types'
 
 interface WebSocketOptions {
   data: any
@@ -51,7 +49,7 @@ class ConnectWebSocket {
     })
 
     this._hasInit = true
-    
+
     this._socket.addEventListener('open', this._onOpen.bind(this))
     this._socket.addEventListener('close', this._onClose.bind(this))
     this._socket.addEventListener('error', this._onError.bind(this))

Some files were not shown because too many files changed in this diff