index.vue 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179
  1. <template>
  2. <div style="height: 100%">
  3. <el-popover width="400" placement="right-end" trigger="click" class="navCtrl">
  4. <el-button size="mini" type="success" @click="NavParamChange" style="float: right">变更</el-button>
  5. <el-table border fit size="mini" :data="navParams">
  6. <el-table-column min-width="40" prop="key" label="属性"></el-table-column>
  7. <el-table-column min-width="30" prop="value" label="值"></el-table-column>
  8. <el-table-column label="操作" min-width="60">
  9. <template slot-scope="scope">
  10. <!-- <el-switch v-if="scope.row.key == '开关机状态'" active-text="开" inactive-text="关"
  11. v-model="NavStartUpStatusBoolean" :change="NavSwitchChange()"></el-switch> -->
  12. <el-select v-if="scope.row.key == '导航模式'" style="width: 80%" v-model="NavCurrentParam.NavWorkMode"
  13. placeholder="选择模式" size="mini">
  14. <el-option v-for="item in NavWorkModels" :key="item.instanceID" :label="item.label" :value="item.value">
  15. </el-option>
  16. </el-select>
  17. <el-switch v-if="scope.row.key == '航迹规划'" active-text="自动" inactive-text="手动"
  18. v-model="PathPlanBoolean"></el-switch>
  19. <el-switch v-if="scope.row.key == '碰撞避免'" active-text="开" inactive-text="关"
  20. v-model="ColitionAvoidBoolean"></el-switch>
  21. </template>
  22. </el-table-column>
  23. </el-table>
  24. <div style="height: 10px"></div>
  25. <el-table border size="small" :data="navPos">
  26. <el-table-column prop="key" label="属性"></el-table-column>
  27. <el-table-column prop="value" label="值"></el-table-column>
  28. </el-table>
  29. <el-button slot="reference">导航和飞行控制</el-button>
  30. </el-popover>
  31. <el-row :gutter="10" style="height: 100%">
  32. <el-col style="height: 100%; position: relative" :span="19">
  33. <div class="main-layout" @mousemove="getMouseLocation">
  34. <div id="cesiumContainer" class="mapecharts"></div>
  35. </div>
  36. </el-col>
  37. <el-col :span="5" style="height: 100%">
  38. <el-switch v-model="isShow" active-color="#13ce66" active-text="显示轨迹" @change="showChange"
  39. inactive-color="#ff4949">
  40. </el-switch>
  41. <!-- <el-table height="49%" :data="map.data.friend">
  42. <el-table-column label="红方平台列表">
  43. <el-table-column width="60" prop="id" label="ID"></el-table-column>
  44. <el-table-column prop="name" label="名称"></el-table-column>
  45. </el-table-column>
  46. </el-table> -->
  47. <el-table v-loading="redloading" :data="redList" height="100%" @selection-change="handleRedSelectionChange"
  48. ref="redTable">
  49. <el-table-column label="平台列表">
  50. <el-table-column type="selection" width="40" v-if="!isShow"> </el-table-column>
  51. <el-table-column width="60" prop="id" label="ID"></el-table-column>
  52. <el-table-column prop="name" label="名称"></el-table-column>
  53. <el-table-column prop="prop" label="属性"></el-table-column>
  54. </el-table-column>
  55. </el-table>
  56. <!-- <div style="height: 2%"></div> -->
  57. <!-- <el-table v-loading="blueloading" :data="blueList" height="49%" @selection-change="handleBlueSelectionChange"
  58. ref="blueTable">
  59. <el-table-column label="蓝方平台列表">
  60. <el-table-column type="selection" width="40" v-if="!isShow"> </el-table-column>
  61. <el-table-column width="60" prop="id" label="ID"></el-table-column>
  62. <el-table-column prop="name" label="名称"></el-table-column>
  63. </el-table-column>
  64. </el-table> -->
  65. </el-col>
  66. </el-row>
  67. <div class="situationButtons">
  68. <el-switch v-model="FusionSituationBoolean" active-text="融合" inactive-text="本地"></el-switch>
  69. <!-- <el-button :type="situation == 'local' ? 'success' : 'danger'" size="mini" @click="situationswitch('local')"
  70. round>本地</el-button>
  71. <el-button :type="situation == 'remote' ? 'success' : 'danger'" size="mini" @click="situationswitch('remote')"
  72. round>远端</el-button>
  73. <el-button :type="situation == 'combine' ? 'success' : 'danger'" size="mini" @click="situationswitch('combine')"
  74. round>融合</el-button>
  75. <el-button :type="situation == 'global' ? 'success' : 'danger'" size="mini" @click="situationswitch('global')"
  76. round>全局</el-button> -->
  77. </div>
  78. <div class="buttons">
  79. <el-button icon="el-icon-house" circle @click="home()"></el-button>
  80. <el-button icon="el-icon-plus" circle @click="big()"></el-button>
  81. <el-button icon="el-icon-minus" circle @click="small()"></el-button>
  82. </div>
  83. </div>
  84. </template>
  85. <script>
  86. import { mapGetters } from "vuex";
  87. // import friendplane from "../../../public/static/friend.glb";
  88. // import enemyplane from "../../../public/static/enemy.glb";
  89. export default {
  90. computed: {
  91. ...mapGetters([
  92. "platformID",
  93. "navStatus",
  94. "navParams",
  95. "navPos",
  96. "mouseLocation",
  97. "cameraLocation",
  98. "map",
  99. ]),
  100. },
  101. data() {
  102. return {
  103. // ---------导航--------------
  104. NavInstance: null,
  105. //轨迹实体id
  106. poly: 10000,
  107. //轨迹是否显示
  108. isShow: true,
  109. //保存轨迹实体信息
  110. polyLineList: [],
  111. //保存友方实体信息
  112. friendIdList: [],
  113. //保存敌方实体信息
  114. enemyIdList: [],
  115. //红方勾选数据
  116. redSelection: [],
  117. //蓝方勾选数据
  118. blueSelection: [],
  119. FusionSituationBoolean: false,
  120. NavStartUpStatusBoolean: null,
  121. PathPlanBoolean: true,
  122. ColitionAvoidBoolean: true,
  123. NavCurrentParam: {
  124. StartUpStatus: null,
  125. NavWorkMode: 0,
  126. },
  127. NavWorkModels: [
  128. {
  129. value: 0,
  130. label: "卫星导航",
  131. },
  132. {
  133. value: 1,
  134. label: "惯性导航",
  135. },
  136. {
  137. value: 2,
  138. label: "融合导航",
  139. },
  140. ],
  141. timer: null,
  142. _viewer: null,
  143. situation: "local", //当前态势
  144. maptype: null,
  145. //红方平台列表
  146. redList: [
  147. { id: 1, name: "干扰模型-101", prop: "协同干扰模型" },
  148. { id: 2, name: "干扰模型-102", prop: "协同干扰模型" },
  149. { id: 3, name: "干扰模型-103", prop: "协同干扰模型" },
  150. { id: 4, name: "干扰模型-104", prop: "协同干扰模型" },
  151. { id: 5, name: "干扰模型-105", prop: "协同干扰模型" },
  152. { id: 6, name: "干扰模型-106", prop: "本机" },
  153. { id: 7, name: "干扰模型-107", prop: "协同干扰模型" },
  154. { id: 8, name: "干扰模型-108", prop: "协同干扰模型" },
  155. { id: 9, name: "干扰模型-109", prop: "协同干扰模型" },
  156. { id: 10, name: "干扰模型-110", prop: "协同干扰模型" },
  157. { id: 11, name: "地面控制站", prop: "控制中心" },
  158. { id: 12, name: "雷达目标-3", prop: "可疑目标" },
  159. { id: 13, name: "雷达目标-4", prop: "可疑目标" },
  160. ],
  161. //蓝方平台列表
  162. blueList: [],
  163. //红方数据加载标识
  164. redloading: false,
  165. //蓝方数据加载标识
  166. blueloading: false
  167. };
  168. },
  169. mounted() {
  170. //初始化cesium
  171. this.cesiumInit();
  172. },
  173. activated() {
  174. this.$wst.send({
  175. url: "getNavStatus",
  176. data: {
  177. PlatformID: this.platformID,
  178. },
  179. });
  180. this.$wst.send({
  181. url: "getNavParams",
  182. data: {
  183. PlatformID: this.platformID,
  184. },
  185. });
  186. this.$wst.send({
  187. url: "getNavPos",
  188. data: {
  189. PlatformID: this.platformID,
  190. },
  191. });
  192. this.setTimer();
  193. },
  194. deactivated() {
  195. this.timerDestory();
  196. },
  197. timerDestory() {
  198. if (this.timer) {
  199. clearInterval(this.timer);
  200. this.timer = null;
  201. }
  202. },
  203. watch: {
  204. init: {
  205. handler: function (val, oldVal) {
  206. this.setTimer();
  207. },
  208. },
  209. map: {
  210. handler: function (val, oldVal) {
  211. //处理友方平台信息
  212. for (let i = 0; i < val.data.friend.length; i++) {
  213. let flag = 0;
  214. //判断友方平台列表是否已存在相关信息
  215. for (let j = 0; j < this.redList.length; j++) {
  216. if (val.data.friend[i].id == this.redList[j].id) {
  217. flag++;
  218. break;
  219. }
  220. }
  221. //若为新增信息,加入到友方列表中
  222. if (flag == 0) {
  223. this.redList.push(val.data.friend[i])
  224. }
  225. }
  226. //处理敌方平台信息
  227. for (let i = 0; i < val.data.enemy.length; i++) {
  228. let flag = 0;
  229. //判断敌方平台列表是否已存在相关信息
  230. for (let j = 0; j < this.blueList.length; j++) {
  231. if (val.data.enemy[i].id == this.blueList[j].id) {
  232. flag++;
  233. break;
  234. }
  235. }
  236. //若为新增信息,加入到敌方列表中
  237. if (flag == 0) {
  238. this.blueList.push(val.data.enemy[i])
  239. }
  240. }
  241. if (this.maptype !== val.type) {
  242. //切换模式 重置所有
  243. this.maptype = val.type;
  244. this.removeAllModel();
  245. this.dataRefresh();
  246. //类型判断
  247. if (val.type !== "global") {
  248. //全局不需要本地导航
  249. this.initNavModel();
  250. }
  251. this.initFriendModel();
  252. this.initEnemyModel();
  253. } else if (val.type !== "global") {
  254. this.initNavModel();
  255. this.initFriendModel();
  256. this.initEnemyModel();
  257. } else {
  258. //移动全局模型
  259. this.moveFriendModel();
  260. this.moveEnemyModel();
  261. }
  262. },
  263. },
  264. navParams: {
  265. handler: function (val, oldVal) {
  266. if (this.getValue(val, "开关机状态") == "开") {
  267. this.NavCurrentParam.StartUpStatus = 1;
  268. } else {
  269. this.NavCurrentParam.StartUpStatus = 0;
  270. }
  271. if (this.getValue(val, "工作模式") == "北斗") {
  272. this.NavCurrentParam.NavWorkMode = 0;
  273. } else if (this.getValue(val, "工作模式") == "惯导") {
  274. this.NavCurrentParam.NavWorkMode = 1;
  275. } else if (this.getValue(val, "工作模式") == "组合导航") {
  276. this.NavCurrentParam.NavWorkMode = 2;
  277. }
  278. this.NavStartUpStatusBoolean =
  279. this.NavCurrentParam.StartUpStatus == 1 ? true : false;
  280. }
  281. },
  282. redList: {
  283. handler: function (val, oldVal) {
  284. //判断是否处于数据加载状态
  285. if (val.length == 0 && this.map.data.friend.length != 0) this.redloading = true
  286. else this.redloading = false
  287. },
  288. },
  289. blueList: {
  290. handler: function (val, oldVal) {
  291. //判断是否处于数据加载状态
  292. if (val.length == 0 && this.map.data.enemy.length != 0) this.blueloading = true
  293. else this.blueloading = false
  294. },
  295. },
  296. },
  297. methods: {
  298. getValue(params, key) {
  299. let value = null;
  300. params.forEach((element) => {
  301. if (element.key == key) {
  302. value = element.value;
  303. }
  304. });
  305. return value;
  306. },
  307. //平台信息刷新方法
  308. MapRefresh() {
  309. if (this.situation == "local") {
  310. this.$wst.send({
  311. url: "getLocalMap",
  312. data: {
  313. PlatformID: this.platformID,
  314. },
  315. });
  316. } else if (this.situation == "remote") {
  317. this.$wst.send({
  318. url: "getRemoteMap",
  319. data: {
  320. PlatformID: this.platformID,
  321. },
  322. });
  323. } else if (this.situation == "combine") {
  324. this.$wst.send({
  325. url: "getRemoteMap",
  326. data: {
  327. PlatformID: this.platformID,
  328. },
  329. });
  330. } else if (this.situation == "global") {
  331. this.$wst.send({
  332. url: "getGlobalMap",
  333. });
  334. }
  335. },
  336. //导航信息刷新方法
  337. NavRefresh() {
  338. this.$wst.send({
  339. url: "getNavParams",
  340. data: {
  341. PlatformID: this.platformID,
  342. },
  343. });
  344. this.$wst.send({
  345. url: "getNavStatus",
  346. data: {
  347. PlatformID: this.platformID,
  348. },
  349. });
  350. this.$wst.send({
  351. url: "getNavPos",
  352. data: {
  353. PlatformID: this.platformID,
  354. },
  355. });
  356. },
  357. //导航参数修改方法
  358. NavParamChange() {
  359. this.$wst.send({
  360. url: "setNavParams",
  361. data: {
  362. PlatformID: this.platformID,
  363. StartUpStatus: this.NavCurrentParam.StartUpStatus,
  364. uWorkMode: this.NavCurrentParam.NavWorkMode,
  365. },
  366. });
  367. this.$wst.send({
  368. url: "getNavParams",
  369. data: {
  370. PlatformID: this.platformID,
  371. },
  372. });
  373. },
  374. NavSwitchChange() {
  375. this.NavCurrentParam.StartUpStatus =
  376. this.NavStartUpStatusBoolean == true ? 1 : 0;
  377. },
  378. setTimer() {
  379. if (this.timer == null) {
  380. this.timer = setInterval(() => {
  381. this.NavRefresh();
  382. this.MapRefresh();
  383. }, 3000);
  384. }
  385. },
  386. //初始化echarts
  387. cesiumInit() {
  388. this.$data._viewer = new this.Cesium.Viewer("cesiumContainer", {
  389. animation: false, // 是否显示时间轴动画
  390. baseLayerPicker: false,
  391. homeButton: false,
  392. geocoder: false,
  393. timeline: false,
  394. fullscreenButton: false,
  395. sceneModePicker: false,
  396. navigationHelpButton: false,
  397. selectionIndicator: false,
  398. imageryProvider: new this.Cesium.WebMapServiceImageryProvider({
  399. url: "http://192.168.5.22:8080/geoserver/map/wms",
  400. layers: 'map:map',
  401. proxy: new this.Cesium.DefaultProxy('/proxy/'),
  402. parameters: {
  403. // transparent: true, //是否透明
  404. format: 'image/png',
  405. // srs: 'EPSG:3857',
  406. }
  407. }),
  408. // imageryProvider: new this.Cesium.TileMapServiceImageryProvider({
  409. // url: "http://192.168.5.22:8080/geoserver/map/",
  410. // minimumLevel: 0,
  411. // maximumLevel: 20,
  412. // fileExtension: "jpg",
  413. // }),
  414. });
  415. this.$data._viewer._cesiumWidget._creditContainer.style.display = "none";
  416. this.$data._viewer.camera.setView({
  417. destination: new this.Cesium.Cartesian3.fromDegrees(
  418. 83.81,
  419. 25.48,
  420. 1500
  421. ),
  422. });
  423. // this.$data._viewer.scene.screenSpaceCameraController.maximumZoomDistance = 1500000; //相机高度的最大值
  424. this.$data._viewer.camera.moveEnd.addEventListener(
  425. this.getCameraHeightAndZoom
  426. ); //地图缩放事件
  427. },
  428. //态势切换
  429. situationswitch(val) {
  430. this.situation = val;
  431. this.removeAllModel();
  432. this.MapRefresh();
  433. },
  434. removeAllModel() {
  435. this.$data._viewer.entities.removeAll(); // 移除全部模型
  436. },
  437. //数据重置
  438. dataRefresh() {
  439. this.polyId = 10000;
  440. this.polyLineList = [];
  441. this.friendIdList = [];
  442. this.enemyIdList = [];
  443. this.redList = [];
  444. this.blueList = [];
  445. this.redSelection = [];
  446. this.blueList = [];
  447. },
  448. //初始化(移动)本平台方法
  449. initNavModel() {
  450. //如果本机平台还未实体化,则初始化本地平台
  451. if (
  452. this.$data._viewer.entities.getById(this.platformID) == null ||
  453. this.$data._viewer.entities.getById(this.platformID) == undefined
  454. ) {
  455. console.log("初始化本地平台");
  456. //加入友方列表
  457. this.redList.push(this.map.data.self);
  458. //新建实体
  459. this.$data._viewer.entities.add({
  460. name: "本平台" + this.platformID,
  461. id: this.platformID,
  462. position: this.Cesium.Cartesian3.fromDegrees(
  463. this.navPos[1].value,
  464. this.navPos[0].value,
  465. 0
  466. ),
  467. //待修改为军标贴图
  468. // point: {
  469. // show: true,
  470. // pixelSize: 14,
  471. // outlineWidth: 3,
  472. // color: this.Cesium.Color.RED,
  473. // outlineColor: this.Cesium.Color.WHITE
  474. // },
  475. billboard: {
  476. image: require("@/assets/image/redairplane.png"),
  477. width: 30,
  478. height: 30,
  479. show: true,
  480. },
  481. label: {
  482. text: "本平台" + this.platformID,
  483. show: true,
  484. font: "14px sans-serif",
  485. pixelOffset: new this.Cesium.Cartesian2(0, 20),
  486. fillColor: this.Cesium.Color.WHITE,
  487. },
  488. // model: {
  489. // uri: friendplane,
  490. // minimumPixelSize: 128,
  491. // maximumScale: 2000,
  492. // },
  493. });
  494. } else {
  495. //本地平台已经实体化 直接移动已有实体
  496. this.moveNavModel();
  497. }
  498. },
  499. //初始化/移动友方模型
  500. initFriendModel() {
  501. let oldList = this.friendIdList;
  502. this.map.data.friend.forEach((element) => {
  503. let outlineColor = null;
  504. let flag = 0;
  505. //检查该平台是否已经实体化
  506. for (let i = 0; i < oldList.length; i++) {
  507. if (element.id == oldList[i].id) {
  508. flag++;
  509. }
  510. }
  511. //如果已实体化,直接移动已有实体
  512. if (flag != 0) {
  513. console.log("移动友方模型" + element.id);
  514. this.moveSingleModel(
  515. element.id,
  516. this.Cesium.Cartesian3.fromDegrees(
  517. element.value[0],
  518. element.value[1],
  519. 0
  520. ),
  521. this.Cesium.Color.WHITE
  522. );
  523. } else {
  524. //尚未实体化
  525. let billboard = {
  526. image: require("@/assets/image/redairplane.png"),
  527. width: 30,
  528. height: 30,
  529. show: true,
  530. };
  531. console.log("初始化友方模型" + element.id);
  532. //新增友方实体
  533. //判断平台类型 对应不同军标贴图(imageUrl) 当前先用点轮廓颜色区分
  534. switch (element.type) {
  535. case 99:
  536. //巡航导弹
  537. outlineColor = this.Cesium.Color.BLACK;
  538. billboard = {
  539. image: require("@/assets/image/redmissile.png"),
  540. width: 30,
  541. height: 30,
  542. show: true,
  543. };
  544. break;
  545. case 7:
  546. //四代机
  547. outlineColor = this.Cesium.Color.GREEN;
  548. break;
  549. case 1:
  550. //三代半
  551. outlineColor = this.Cesium.Color.ORANGE;
  552. break;
  553. case 16:
  554. //预警机
  555. outlineColor = this.Cesium.Color.YELLOW;
  556. break;
  557. case 20:
  558. //驱逐舰 干扰机
  559. outlineColor = this.Cesium.Color.PINK;
  560. break;
  561. case 36:
  562. //运侦、侦察机
  563. outlineColor = this.Cesium.Color.WHITE;
  564. break;
  565. case 65:
  566. //侦察船
  567. outlineColor = this.Cesium.Color.GRAY;
  568. break;
  569. default:
  570. outlineColor = this.Cesium.Color.WHITE;
  571. break;
  572. }
  573. //新增实体
  574. this.$data._viewer.entities.add({
  575. name: element.name,
  576. id: element.id,
  577. position: this.Cesium.Cartesian3.fromDegrees(
  578. element.value[0],
  579. element.value[1],
  580. 0
  581. ),
  582. //待修改为军标贴图
  583. // point: {
  584. // show: true,
  585. // pixelSize: 14,
  586. // outlineWidth: 3,
  587. // color: this.Cesium.Color.RED,
  588. // outlineColor: outlineColor
  589. // },
  590. billboard: billboard,
  591. label: {
  592. text: element.name == null ? "友方" + element.id : element.name,
  593. show: true,
  594. font: "14px sans-serif",
  595. pixelOffset: new this.Cesium.Cartesian2(0, 20),
  596. fillColor: this.Cesium.Color.WHITE,
  597. },
  598. // model: {
  599. // uri: friendplane,
  600. // minimumPixelSize: 128,
  601. // maximumScale: 2000,
  602. // },
  603. });
  604. this.friendIdList.push({ id: element.id });
  605. }
  606. });
  607. },
  608. //初始化/移动敌方模型
  609. initEnemyModel() {
  610. let str = "敌方";
  611. let color = this.Cesium.Color.BLUE;
  612. if (this.map.type == "remote") {
  613. str = "未知";
  614. color = this.Cesium.Color.BLUE;
  615. }
  616. let oldList = this.enemyIdList;
  617. this.map.data.enemy.forEach((element) => {
  618. let flag = 0;
  619. //检查平台是否已经在地图中有对应实体
  620. for (let i = 0; i < oldList.length; i++) {
  621. if (element.id == oldList[i].id) {
  622. flag++;
  623. break;
  624. }
  625. }
  626. //若平台已经实体化,则直接移动已存在的实体
  627. if (flag != 0) {
  628. console.log("移动敌方模型" + element.id);
  629. this.moveSingleModel(
  630. element.id,
  631. this.Cesium.Cartesian3.fromDegrees(
  632. element.value[0],
  633. element.value[1],
  634. 0
  635. ),
  636. color
  637. );
  638. return;
  639. } else {
  640. console.log("初始化敌方模型" + element.id);
  641. let billboard = {
  642. image: require("@/assets/image/blueairplane.png"),
  643. width: 30,
  644. height: 30,
  645. show: true,
  646. };
  647. //平台未实体化,添加实体
  648. let outlineColor = null;
  649. // 判断平台类型 对应不同军标贴图 当前先用点轮廓颜色区分
  650. switch (element.type) {
  651. case 1:
  652. //F-16
  653. outlineColor = this.Cesium.Color.PINK;
  654. break;
  655. case 7:
  656. //F-35
  657. outlineColor = this.Cesium.Color.GREEN;
  658. break;
  659. case 36:
  660. //E-2D
  661. outlineColor = this.Cesium.Color.ORANGE;
  662. break;
  663. case 10:
  664. //航母舰
  665. outlineColor = this.Cesium.Color.YELLOW;
  666. billboard = {
  667. image: require("@/assets/image/blueradar.png"),
  668. width: 30,
  669. height: 30,
  670. show: true,
  671. };
  672. break;
  673. case 19:
  674. //???
  675. outlineColor = this.Cesium.Color.WHITE;
  676. break;
  677. default:
  678. outlineColor = this.Cesium.Color.BLACK;
  679. break;
  680. }
  681. this.$data._viewer.entities.add({
  682. name:
  683. element.name == null ? str + String(element.id) : element.name,
  684. id: element.id,
  685. position: this.Cesium.Cartesian3.fromDegrees(
  686. element.value[0],
  687. element.value[1],
  688. 0
  689. ),
  690. //待修改为军标贴图
  691. // point: {
  692. // show: true,
  693. // pixelSize: 14,
  694. // outlineWidth: 3,
  695. // color: color,
  696. // outlineColor: outlineColor
  697. // },
  698. //目前为单一贴图 待优化
  699. billboard: billboard,
  700. label: {
  701. text:
  702. element.name == null ? str + String(element.id) : element.name,
  703. show: true,
  704. font: "14px sans-serif",
  705. pixelOffset: new this.Cesium.Cartesian2(0, 20),
  706. fillColor: this.Cesium.Color.WHITE,
  707. },
  708. });
  709. this.enemyIdList.push({ id: element.id });
  710. }
  711. });
  712. },
  713. /*
  714. 绘制单个模型实体移动轨迹方法
  715. 输入:
  716. id:要移动的实体id号
  717. newPosition:实体移动后的位置
  718. oldPosition:实体移动前的位置
  719. color:移动轨迹颜色
  720. */
  721. drawTrace(id, newPosition, oldPosition, color) {
  722. let flag = 0;
  723. let polyId = 0;
  724. //找到要绘制的轨迹实体id
  725. for (let i = 0; i < this.polyLineList.length; i++) {
  726. if (this.polyLineList[i].entityId == id) {
  727. flag++;
  728. polyId = this.polyLineList[i].polyId;
  729. break;
  730. }
  731. }
  732. //线条不存在
  733. if (flag == 0) {
  734. //保存线条信息
  735. this.polyLineList.push({
  736. polyId: this.polyId,
  737. entityId: id,
  738. });
  739. //新增线条实体
  740. let entity = this.$data._viewer.entities.add({
  741. id: this.polyId++,
  742. polyline: {
  743. positions: [oldPosition, newPosition],
  744. width: 2,
  745. material: color,
  746. glowPower: 0.2,
  747. followSurface: false,
  748. show: true,
  749. },
  750. });
  751. //避免show属性添加异常问题
  752. if (!this.isShow) entity.show = false;
  753. }
  754. //线条存在
  755. else {
  756. //获取平台对应线条实体
  757. var newPolyId;
  758. let poly = this.$data._viewer.entities.getById(polyId);
  759. newPolyId = polyId + 1e7;
  760. if (poly == undefined) {
  761. newPolyId = polyId;
  762. polyId = polyId + 1e7;
  763. poly = this.$data._viewer.entities.getById(polyId);
  764. }
  765. //获取实体当前的位置集合
  766. let polyPosition = poly._polyline._positions._value;
  767. //将要移动的新位置数据添加到实体的位置集合中
  768. polyPosition.push(newPosition);
  769. //添加更新位置信息后的实体 先新增,后删除,解决轨迹闪现问题
  770. let entity = this.$data._viewer.entities.add({
  771. id: newPolyId,
  772. polyline: {
  773. positions: polyPosition,
  774. width: 2,
  775. material: color,
  776. followSurface: false,
  777. show: true,
  778. },
  779. });
  780. //等待一小段时间,确保在新实体被添加之后再移除原来实体,避免闪现问题
  781. setTimeout(() => {
  782. this.$data._viewer.entities.removeById(polyId);
  783. }, 100);
  784. if (!this.isShow) {
  785. //如果当前轨迹显示为false,则查看更新的轨迹是否被设置了单个显示状态
  786. for (let i = 0; i < this.redSelection.length; i++) {
  787. if (id == this.redSelection[i].id) return;
  788. }
  789. for (let i = 0; i < this.blueSelection.length; i++) {
  790. if (id == this.blueSelection[i].id) return;
  791. }
  792. entity.show = false;
  793. }
  794. }
  795. },
  796. //轨迹显隐控制
  797. showChange() {
  798. //弹出提示
  799. if (this.isShow) {
  800. const h = this.$createElement;
  801. this.$notify({
  802. title: '开启显示',
  803. message: h('i', '开启全部平台轨迹显示'),
  804. offset: -18,
  805. duration: 2000
  806. });
  807. }
  808. else {
  809. const h = this.$createElement;
  810. this.$notify({
  811. title: '关闭显示',
  812. message: h('i', '关闭全部平台轨迹显示,可通过勾选显示指定平台轨迹'),
  813. offset: -18,
  814. duration: 2000
  815. });
  816. }
  817. //清空选择内容
  818. this.redSelection = [];
  819. this.blueSelection = [];
  820. this.$refs.redTable.clearSelection();
  821. this.$refs.blueTable.clearSelection();
  822. //遍历轨迹实体集合 设置所有实体的show属性
  823. for (let i = 0; i < this.polyLineList.length; i++) {
  824. let entity = this.$data._viewer.entities.getById(
  825. this.polyLineList[i].polyId
  826. );
  827. if (entity == undefined) {
  828. entity = this.$data._viewer.entities.getById(this.polyLineList[i].polyId + 1e7);
  829. }
  830. entity.show = this.isShow;
  831. }
  832. },
  833. /*
  834. 移动单个模型实体方法
  835. 输入:
  836. id:要移动的实体id号
  837. position:实体移动后的位置
  838. color:移动轨迹颜色
  839. */
  840. moveSingleModel(id, position, color) {
  841. //通过id获取实体
  842. let entity = this.$data._viewer.entities.getById(id);
  843. //获取实体原始位置
  844. let oldPosition = entity.position._value;
  845. //如果未移动 返回
  846. if (position.x == oldPosition.x && position.y == oldPosition.y) return;
  847. //设置方向
  848. entity.orientation = this.Cesium.VelocityOrientationProperty(
  849. entity.position
  850. );
  851. //模型移动--直接修改position 的 value值实现
  852. entity.position.setValue(position);
  853. //绘制移动路径
  854. this.drawTrace(id, position, oldPosition, color);
  855. },
  856. //移动本平台模型
  857. moveNavModel() {
  858. console.log("移动本平台模型");
  859. let position = this.Cesium.Cartesian3.fromDegrees(
  860. this.navPos[1].value,
  861. this.navPos[0].value,
  862. 0
  863. );
  864. this.moveSingleModel(this.platformID, position, this.Cesium.Color.RED);
  865. },
  866. //移动友方模型
  867. moveFriendModel() {
  868. console.log("移动友方模型");
  869. this.map.data.friend.forEach((element) => {
  870. let position = this.Cesium.Cartesian3.fromDegrees(
  871. element.value[0],
  872. element.value[1],
  873. 0
  874. );
  875. this.moveSingleModel(element.id, position, this.Cesium.Color.RED);
  876. });
  877. },
  878. //移动敌方模型
  879. moveEnemyModel() {
  880. console.log("移动敌方模型");
  881. this.map.data.enemy.forEach((element) => {
  882. let position = this.Cesium.Cartesian3.fromDegrees(
  883. element.value[0],
  884. element.value[1],
  885. 0
  886. );
  887. this.moveSingleModel(element.id, position, this.Cesium.Color.BLUE);
  888. });
  889. },
  890. //红方轨迹控制操作
  891. handleRedSelectionChange(val) {
  892. if (this.isShow) return;
  893. for (let i = 0; i < this.redSelection.length; i++) {
  894. let flag = 0;
  895. //检查当前选中是否被取消
  896. for (let j = 0; j < val.length; j++) {
  897. if (val[j].id == this.redSelection[i].id) {
  898. flag++;
  899. break;
  900. }
  901. }
  902. if (flag == 0) {//新选择中被取消了
  903. for (let z = 0; z < this.polyLineList.length; z++) {
  904. //找到对应的轨迹实体并将其show属性置为false
  905. if (this.redSelection[i].id == this.polyLineList[z].entityId) {
  906. let entity = this.$data._viewer.entities.getById(
  907. this.polyLineList[z].polyId
  908. );
  909. if (entity == undefined) {
  910. entity = this.$data._viewer.entities.getById(
  911. this.polyLineList[z].polyId + 1e7
  912. );
  913. }
  914. entity.show = false;
  915. break;
  916. }
  917. }
  918. }
  919. }
  920. if (!this.isShow) {
  921. for (let i = 0; i < this.polyLineList.length; i++) {
  922. for (let j = 0; j < val.length; j++) {
  923. //将所有被选中的红方平台的轨迹实体show属性置为true
  924. if (val[j].id == this.polyLineList[i].entityId) {
  925. let entity = this.$data._viewer.entities.getById(
  926. this.polyLineList[i].polyId
  927. );
  928. if (entity == undefined) {
  929. entity = this.$data._viewer.entities.getById(
  930. this.polyLineList[i].polyId + 1e7
  931. );
  932. }
  933. entity.show = true;
  934. }
  935. }
  936. }
  937. }
  938. //更新
  939. this.redSelection = val;
  940. },
  941. //蓝方轨迹控制操作
  942. handleBlueSelectionChange(val) {
  943. if (this.isShow) return;
  944. for (let i = 0; i < this.blueSelection.length; i++) {
  945. let flag = 0;
  946. //检查当前选中是否被取消
  947. for (let j = 0; j < val.length; j++) {
  948. if (val[j].id == this.blueSelection[i].id) {
  949. flag++;
  950. break;
  951. }
  952. }
  953. if (flag == 0) {//新选择中被取消了
  954. for (let z = 0; z < this.polyLineList.length; z++) {
  955. //找到对应的轨迹实体并将其show属性置为false
  956. if (this.blueSelection[i].id == this.polyLineList[z].entityId) {
  957. let entity = this.$data._viewer.entities.getById(
  958. this.polyLineList[z].polyId
  959. );
  960. if (entity == undefined) {
  961. entity = this.$data._viewer.entities.getById(
  962. this.polyLineList[z].polyId + 1e7
  963. );
  964. }
  965. entity.show = false;
  966. break;
  967. }
  968. }
  969. }
  970. }
  971. for (let i = 0; i < this.polyLineList.length; i++) {
  972. for (let j = 0; j < val.length; j++) {
  973. //将所有被选中的蓝方平台的轨迹实体show属性置为true
  974. if (val[j].id == this.polyLineList[i].entityId) {
  975. let entity = this.$data._viewer.entities.getById(
  976. this.polyLineList[i].polyId
  977. );
  978. if (entity == undefined) {
  979. entity = this.$data._viewer.entities.getById(
  980. this.polyLineList[i].polyId + 1e7
  981. );
  982. }
  983. entity.show = true;
  984. }
  985. }
  986. }
  987. this.blueSelection = val;
  988. },
  989. //根据camera高度近似计算当前层级
  990. heightToZoom(height) {
  991. var A = 40487.57;
  992. var B = 0.00007096758;
  993. var C = 91610.74;
  994. var D = -40467.74;
  995. return Math.round(D + (A - D) / (1 + Math.pow(height / C, B)));
  996. },
  997. //获取相机层级和视高
  998. getCameraHeightAndZoom() {
  999. let height = this.$data._viewer.camera.positionCartographic.height;
  1000. let zoom = this.heightToZoom(height);
  1001. this.$store.commit("app/setCameraLocation", { height, zoom });
  1002. },
  1003. //显示鼠标经纬度
  1004. getMouseLocation(event) {
  1005. let { longitude, latitude } = this.getCoordinatesFromEvent(event);
  1006. this.$store.commit("app/setMouseLocation", { longitude, latitude });
  1007. },
  1008. // 从鼠标点击事件获取坐标
  1009. getCoordinatesFromEvent(event) {
  1010. let clickPosition = new this.Cesium.Cartesian2(
  1011. event.clientX - 1080,
  1012. event.clientY - 160
  1013. );
  1014. //获取地图上的经纬度
  1015. const viewerPosition =
  1016. this.$data._viewer.scene.camera.pickEllipsoid(clickPosition);
  1017. const cartographic =
  1018. this.$data._viewer.scene.globe.ellipsoid.cartesianToCartographic(
  1019. viewerPosition
  1020. );
  1021. const latitude = this.Cesium.Math.toDegrees(cartographic.latitude);
  1022. const longitude = this.Cesium.Math.toDegrees(cartographic.longitude);
  1023. return {
  1024. latitude,
  1025. longitude,
  1026. };
  1027. },
  1028. //获取camera中心点坐标
  1029. getCenterPosition() {
  1030. let result = this.$data._viewer.camera.pickEllipsoid(
  1031. new this.Cesium.Cartesian2(
  1032. this.$data._viewer.canvas.clientWidth / 2,
  1033. this.$data._viewer.canvas.clientHeight / 2
  1034. )
  1035. );
  1036. let curPosition =
  1037. this.Cesium.Ellipsoid.WGS84.cartesianToCartographic(result);
  1038. let lon = (curPosition.longitude * 180) / Math.PI;
  1039. let lat = (curPosition.latitude * 180) / Math.PI;
  1040. let height = this.$data._viewer.camera.positionCartographic.height;
  1041. return {
  1042. longitude: lon,
  1043. latitude: lat,
  1044. height: height,
  1045. };
  1046. },
  1047. // 图像放大
  1048. big() {
  1049. let { longitude, latitude, height } = this.getCenterPosition();
  1050. this.$data._viewer.camera.flyTo({
  1051. destination: this.Cesium.Cartesian3.fromDegrees(
  1052. longitude,
  1053. latitude,
  1054. height / 1.8
  1055. ),
  1056. duration: 1.0,
  1057. });
  1058. },
  1059. //图像缩小
  1060. small() {
  1061. let { longitude, latitude, height } = this.getCenterPosition();
  1062. this.$data._viewer.camera.flyTo({
  1063. destination: this.Cesium.Cartesian3.fromDegrees(
  1064. longitude,
  1065. latitude,
  1066. height * 1.2
  1067. ),
  1068. duration: 1.0,
  1069. });
  1070. },
  1071. home() {
  1072. this.$data._viewer.camera.flyTo({
  1073. destination: this.Cesium.Cartesian3.fromDegrees(
  1074. 117.918977,
  1075. 25.0,
  1076. 1500000
  1077. ),
  1078. duration: 2.0,
  1079. });
  1080. },
  1081. },
  1082. };
  1083. </script>
  1084. <style scoped>
  1085. .model {
  1086. position: absolute;
  1087. top: 20px;
  1088. left: 100px;
  1089. z-index: 999;
  1090. }
  1091. .tableHeight {
  1092. height: 100%;
  1093. }
  1094. .clearfix:before,
  1095. .clearfix:after {
  1096. display: table;
  1097. content: "";
  1098. }
  1099. .clearfix:after {
  1100. clear: both;
  1101. }
  1102. .navCtrl {
  1103. position: absolute;
  1104. top: 10px;
  1105. left: 10px;
  1106. z-index: 999;
  1107. }
  1108. .table1 {
  1109. position: absolute;
  1110. top: 10px;
  1111. left: 10px;
  1112. z-index: 999;
  1113. width: 400px;
  1114. height: 800px;
  1115. }
  1116. .table1 /deep/ .el-card__header {
  1117. background-color: #11144e;
  1118. color: white;
  1119. }
  1120. .table2 {
  1121. position: absolute;
  1122. top: 430px;
  1123. left: 10px;
  1124. z-index: 999;
  1125. width: 400px;
  1126. height: 400px;
  1127. }
  1128. .table2 /deep/ .el-card__header {
  1129. background-color: #11144e;
  1130. color: white;
  1131. }
  1132. .main-layout {
  1133. height: 100%;
  1134. width: 100%;
  1135. }
  1136. .container {
  1137. height: 100%;
  1138. }
  1139. .mapecharts {
  1140. width: 100%;
  1141. height: 100%;
  1142. }
  1143. .buttons {
  1144. display: flex;
  1145. flex-direction: column;
  1146. align-items: center;
  1147. justify-items: center;
  1148. position: absolute;
  1149. z-index: 999;
  1150. right: 20px;
  1151. top: 20px;
  1152. }
  1153. .situationButtons {
  1154. position: absolute;
  1155. top: 20px;
  1156. left: 50%;
  1157. transform: translateX(-100%);
  1158. }
  1159. .buttons .el-button {
  1160. margin: 5px !important;
  1161. }
  1162. </style>