index.vue 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323
  1. <template>
  2. <div class="container">
  3. <el-row id="earth" style="height: 100%; width: 100%; display: flex; position: relative">
  4. <el-col style="height: 100%; position: relative" :span="this.leftwidth">
  5. <div class="main-layout" v-on:mouseover="changeActive('2D')" @mousemove="getMouseLocation">
  6. <div id="2DcesiumContainer" class="map"></div>
  7. </div>
  8. </el-col>
  9. <el-col style="height: 100%; position: relative" :span="24 - this.leftwidth">
  10. <div class="main-layout" v-on:mouseover="changeActive('3D')" @mousemove="getMouseLocation">
  11. <div id="3DcesiumContainer" class="map"></div>
  12. </div>
  13. </el-col>
  14. <el-tabs type="border-card" v-model="activeName" tab-position="left" class="menu" :stretch="true"
  15. @tab-click="legendClick">
  16. <el-tab-pane name="fouth">
  17. <el-tooltip placement="right" effect="light" slot="label">
  18. <span slot="content" class="item">想定</span>
  19. <span><i class="el-icon-house"></i></span>
  20. </el-tooltip>
  21. <el-table :data="situation">
  22. <el-table-column label="名称" prop="xdname" width="150px"></el-table-column>
  23. <el-table-column label="操作" align="center">
  24. <template slot-scope="scope">
  25. <el-button type="primary" @click="getJson(scope.row)">导入</el-button>
  26. <!-- <el-button type="primary" @click="saveJson()">保存</el-button> -->
  27. </template>
  28. </el-table-column>
  29. </el-table>
  30. </el-tab-pane>
  31. <el-tab-pane name="fifth">
  32. <el-tooltip placement="right" effect="light" slot="label">
  33. <span slot="content" class="item">消息</span>
  34. <span><i class="el-icon-chat-line-round"></i></span>
  35. </el-tooltip>
  36. <el-table :data="messageList">
  37. <el-table-column label="序号" prop="order" width="50px"></el-table-column>
  38. <el-table-column label="时间" align="center" prop="time"></el-table-column>
  39. <el-table-column label="消息" align="center" prop="context"></el-table-column>
  40. </el-table>
  41. </el-tab-pane>
  42. </el-tabs>
  43. <div class="buttons">
  44. <el-button icon="el-icon-full-screen" circle @click="ismax()"></el-button>
  45. <el-button icon="el-icon-house" circle @click="home()"></el-button>
  46. <el-button icon="el-icon-plus" circle @click="big()"></el-button>
  47. <el-button icon="el-icon-minus" circle @click="small()"></el-button>
  48. </div>
  49. </el-row>
  50. <!-- <TimeLine :showLayers="showLayers" :timeDataArray="timeDataArray" class="TimeLine"></TimeLine> -->
  51. <div>
  52. <el-dialog title="模拟消息列表" :visible.sync="dialogVisible" width="50%">
  53. <el-table :data="messageList">
  54. <el-table-column label="序号" prop="order" width="50px"></el-table-column>
  55. <el-table-column label="时间" align="center" prop="time"></el-table-column>
  56. <el-table-column label="消息" align="center" prop="context"></el-table-column>
  57. </el-table>
  58. <div slot="footer" class="dialog-footer">
  59. <el-button @click="dialogVisible = false">关闭</el-button>
  60. </div>
  61. </el-dialog>
  62. </div>
  63. </div>
  64. </template>
  65. <script>
  66. import screenfull from "screenfull";
  67. import fireController from "@/api/fireController.js";
  68. import { getToken } from "@/utils";
  69. import axios from "axios";
  70. import satelliteModel from 'public/static/model/satelite1.glb';
  71. import TimeLine from '@/components/TimeLine/index.vue';
  72. import missileModel from 'public/static/model/basic_missle.glb';
  73. import centerModel from 'public/static/model/the_white_house.glb';
  74. import radarModel from 'public/static/model/radar.glb'
  75. import { mapGetters } from "vuex";
  76. import CesiumNavigation from 'cesium-navigation-es6/viewerCesiumNavigationMixin'
  77. export default {
  78. components: {
  79. TimeLine
  80. },
  81. computed: {
  82. ...mapGetters([
  83. "dimension"
  84. ])
  85. },
  86. data() {
  87. return {
  88. save: false,
  89. messageList: [],
  90. situation: [],
  91. nameIdList: [],
  92. satelliteRange: [],
  93. missileList: {},
  94. thaadList: {},
  95. websocket: null,
  96. centerPosition: null,
  97. leftwidth: 12,
  98. unit: [],
  99. dialogVisible: false,
  100. satellite: [],
  101. center: [],
  102. move_data: {},
  103. order: 1,
  104. _viewer2D: null,
  105. _viewer3D: null,
  106. mousevalue: null,
  107. // 选中的点
  108. selectedMarker: null,
  109. // 以前的标记点坐标
  110. oldPosition: null,
  111. activeName: 'fouth',
  112. currentLab: {
  113. index: -1,
  114. isActive: false
  115. },
  116. url: "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
  117. isShow: false,
  118. handler3D: null,
  119. handler2D: null,
  120. image: null,
  121. modeltooltip: null,
  122. id: 1,
  123. showLayers: null,
  124. timeDataArray: ['Time 1', 'Time 2', 'Time 3', 'Time 4'],
  125. jsonData: null,
  126. mapNavOptions: {
  127. // 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和Cesium.Rectangle.
  128. defaultResetView: this.Cesium.Cartographic.fromDegrees(110, 30, 2000000),
  129. // 罗盘
  130. enableCompass: true,
  131. // 缩放控件
  132. enableZoomControls: false,
  133. // 距离图例
  134. enableDistanceLegend: true,
  135. // 指南针外环
  136. enableCompassOuterRing: true
  137. }
  138. };
  139. },
  140. watch: {
  141. dimension: {
  142. handler: function (val, oldVal) {
  143. console.log(val)
  144. if (val == 2) {
  145. this.leftwidth = 24;
  146. } else if (val == 3) {
  147. this.leftwidth = 0;
  148. } else if (val == 5) {
  149. this.leftwidth = 12;
  150. }
  151. },
  152. },
  153. },
  154. activated() {
  155. this.getData();
  156. },
  157. mounted() {
  158. this.cesiumInit();
  159. // this.pointMove();
  160. // this.startWebSocket();
  161. },
  162. methods: {
  163. async getJson(row) {
  164. this.order = 1;
  165. this.messageList = [];
  166. this.nameIdList = [];
  167. this.satelliteRange = [];
  168. this.missileList = {};
  169. this.thaadList = {};
  170. let redunit = [];
  171. let blueunit = [];
  172. let satellite = [];
  173. let center = [];
  174. let fileInfoStr = row.xdfile;
  175. let fileInfoArr = JSON.parse(fileInfoStr);
  176. this.$data._viewer2D.entities.removeAll();
  177. this.$data._viewer3D.entities.removeAll();
  178. await axios
  179. .get("http://127.0.0.1:8084/admin/online/onlineOperation/downloadDatasource/main", {
  180. params: {
  181. datasourceId: "1656243335922192384",
  182. fieldName: "xdfile",
  183. asImage: false,
  184. dataId: row.id,
  185. filename: fileInfoArr[0].filename,
  186. Authorization: getToken(),
  187. MenuId: "1656244747347431424"
  188. }
  189. })
  190. .then((response) => {
  191. console.log('response.data :>> ', response.data);
  192. // // 处理成功的响应
  193. // jsonData = response.data
  194. blueunit = response.data.blueunit
  195. redunit = response.data.redunit
  196. satellite = response.data.satellite
  197. center = response.data.center
  198. this.save = true
  199. this.jsonData = {
  200. id: row.id,
  201. xdname: response.data.xdname,
  202. type: response.data.type,
  203. // creator: row.creator,
  204. createtime: response.data.createtime,
  205. bluecnt: response.data.bluecnt,
  206. target: response.data.target,
  207. starttime: response.data.starttime,
  208. steptime: response.data.steptime,
  209. endtime: response.data.endtime,
  210. blueunit: blueunit,
  211. redunit: redunit,
  212. satellite: satellite,
  213. center: center
  214. }
  215. this.setTimeLine(response.data.starttime, response.data.endtime, response.data.steptime)//传入时间到时间轴
  216. })
  217. .catch((error) => {
  218. // 处理错误
  219. console.error(error);
  220. });
  221. for (let i = 0; i < blueunit.length; i++) {
  222. this.markLocationbyJson(parseFloat(blueunit[i].pos.lat), parseFloat(blueunit[i].pos.lon), parseFloat(blueunit[i].pos.height), blueunit[i].name, "blue")
  223. }
  224. for (let i = 0; i < center.length; i++) {
  225. let item = center[i]
  226. this.markLocationbyJson(parseFloat(item[center[i].name].properties.lat), parseFloat(item[center[i].name].properties.lon), parseFloat(item[center[i].name].properties.h), item.name, "center")
  227. }
  228. for (let i = 0; i < redunit.length; i++) {
  229. this.markLocationbyJson(parseFloat(redunit[i].component_movementjson.properties.launch_lat), parseFloat(redunit[i].component_movementjson.properties.launch_lon), parseFloat(redunit[i].component_movementjson.properties.launch_h), redunit[i].name, "red")
  230. let point1 = {
  231. longitude: parseFloat(redunit[i].component_movementjson.properties.launch_lon),
  232. latitude: parseFloat(redunit[i].component_movementjson.properties.launch_lat),
  233. height: parseFloat(redunit[i].component_movementjson.properties.launch_h)
  234. }
  235. let point2 = {
  236. longitude: parseFloat(redunit[i].component_movementjson.properties.target_lon),
  237. latitude: parseFloat(redunit[i].component_movementjson.properties.target_lat),
  238. height: parseFloat(redunit[i].component_movementjson.properties.target_h)
  239. }
  240. this.markLine(point1, point2, "red")
  241. }
  242. },
  243. //获取所有数据
  244. getData() {
  245. this.getCenter();
  246. this.getSatellite();
  247. this.getUnit();
  248. this.getSituation();
  249. },
  250. // 获取场景想定数据
  251. getSituation() {
  252. let params = {
  253. datasourceId: "1656243335922192384",
  254. filterDtoList: [],
  255. pageParam: {
  256. pageNum: 1,
  257. pageSize: 10
  258. }
  259. };
  260. fireController.situation(this, params).then((res) => {
  261. this.situation = res.data.dataList;
  262. });
  263. },
  264. // 获取作战单元数据
  265. getUnit() {
  266. let params = {
  267. datasourceId: "1657931215497334784",
  268. filterDtoList: [],
  269. pageParam: {
  270. pageNum: 1,
  271. pageSize: 10
  272. }
  273. };
  274. fireController.unit(this, params).then((res) => {
  275. this.unit = res.data.dataList;
  276. });
  277. },
  278. // 获取指挥中心数据
  279. getCenter() {
  280. let params = {
  281. datasourceId: "1654421731512684544",
  282. filterDtoList: [],
  283. pageParam: {
  284. pageNum: 1,
  285. pageSize: 10
  286. }
  287. };
  288. fireController.center(this, params).then((res) => {
  289. this.center = res.data.dataList;
  290. });
  291. },
  292. // 获取预警卫星数据
  293. getSatellite() {
  294. let params = {
  295. datasourceId: "1654424480958648320",
  296. filterDtoList: [],
  297. pageParam: {
  298. pageNum: 1,
  299. pageSize: 10
  300. }
  301. };
  302. fireController.satellite(this, params).then((res) => {
  303. this.satellite = res.data.dataList;
  304. });
  305. },
  306. cesiumInit() {
  307. this.$data._viewer2D = new this.Cesium.Viewer("2DcesiumContainer", {
  308. sceneMode: this.Cesium.SceneMode.SCENE2D,
  309. animation: true, // 是否显示时间轴动画
  310. baseLayerPicker: false,
  311. homeButton: false,
  312. geocoder: false,
  313. timeline: true, //是否显示时间线控件
  314. fullscreenButton: false,
  315. sceneModePicker: false,
  316. navigationHelpButton: false,
  317. selectionIndicator: false,
  318. imageryProvider: new this.Cesium.UrlTemplateImageryProvider({
  319. url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
  320. layer: "tdtVecBasicLayer",
  321. style: "default",
  322. format: "image/png",
  323. tileMatrixSetID: "GoogleMapsCompatible",
  324. show: false
  325. })
  326. });
  327. this.$data._viewer3D = new this.Cesium.Viewer("3DcesiumContainer", {
  328. animation: true, // 是否显示时间轴动画
  329. baseLayerPicker: false,
  330. homeButton: false,
  331. geocoder: false,
  332. timeline: true, //是否显示时间线控件
  333. fullscreenButton: false,
  334. sceneModePicker: false,
  335. navigationHelpButton: false,
  336. selectionIndicator: false,
  337. // imageryProvider: new this.Cesium.WebMapServiceImageryProvider({
  338. // url: '/geoserver/map/wms',
  339. // // 这里是自定义的图层名称
  340. // layers: 'map',
  341. // parameters: {
  342. // service: 'WMS',
  343. // format: 'image/png',
  344. // transparent: true
  345. // }
  346. // }),
  347. imageryProvider:
  348. // new this.Cesium.WebMapTileServiceImageryProvider({
  349. // url: "http://10.170.16.95:8080/geoserver/gwc/service/wmts/rest/map:map/{style}/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png",
  350. // layer: 'map:map',
  351. // style: 'raster',
  352. // format: 'image/png',
  353. // tileMatrixSetID: 'EPSG:900913', //一般使用EPSG:3857坐标系
  354. // }),
  355. new this.Cesium.UrlTemplateImageryProvider({
  356. url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
  357. layer: "tdtVecBasicLayer",
  358. style: "default",
  359. format: "image/png",
  360. tileMatrixSetID: "GoogleMapsCompatible",
  361. show: false
  362. })
  363. });
  364. this.$data._viewer3D._cesiumWidget._creditContainer.style.display = "none";
  365. this.$data._viewer2D._cesiumWidget._creditContainer.style.display = "none";
  366. this.$data._viewer3D.camera.setView({
  367. destination: new this.Cesium.Cartesian3.fromDegrees(117.918977, 25.0, 1500000)
  368. // 方向,俯视和仰视的视角
  369. // orientation:{
  370. // heading: this.Cesium.Math.toRadians(90),//坐标系旋转90度
  371. // pitch: this.Cesium.Math.toRadians(-45) ,//设置俯仰角度为-45度
  372. // }
  373. });
  374. this.$data._viewer2D.camera.setView({
  375. destination: new this.Cesium.Cartesian3.fromDegrees(117.918977, 25.0, 1500000)
  376. // 方向,俯视和仰视的视角
  377. // orientation:{
  378. // heading: this.Cesium.Math.toRadians(90),//坐标系旋转90度
  379. // pitch: this.Cesium.Math.toRadians(-45) ,//设置俯仰角度为-45度
  380. // }
  381. });
  382. // this.viewer.scene.screenSpaceCameraController.maximumZoomDistance = 1500000; //相机高度的最大值
  383. this.$data._viewer2D.camera.percentageChanged = 0.01;
  384. this.$data._viewer2D.camera.changed.addEventListener(this.sync); //地图移动事件
  385. this.$data._viewer3D.camera.percentageChanged = 0.01;
  386. this.$data._viewer3D.camera.changed.addEventListener(this.sync); //地图移动事件
  387. this.$data._viewer2D.camera.moveEnd.addEventListener(this.getCammeraHeightAndZoom) //地图缩放事件
  388. this.$data._viewer3D.camera.moveEnd.addEventListener(this.getCammeraHeightAndZoom) //地图缩放事件
  389. this.handler2D = new this.Cesium.ScreenSpaceEventHandler(this.$data._viewer2D.scene.canvas);
  390. this.handler3D = new this.Cesium.ScreenSpaceEventHandler(this.$data._viewer3D.scene.canvas);
  391. //设置导航组件
  392. new CesiumNavigation(this.$data._viewer2D, this.mapNavOptions);
  393. new CesiumNavigation(this.$data._viewer3D, this.mapNavOptions);
  394. },
  395. sync() {
  396. if (this.mousevalue == "3D") {
  397. // 三维地图中心点
  398. let center = new this.Cesium.Cartesian2(
  399. Math.floor(this.$data._viewer3D.canvas.clientWidth / 2),
  400. Math.floor(this.$data._viewer3D.canvas.clientHeight / 2)
  401. );
  402. // 转为世界坐标系
  403. let position = this.$data._viewer3D.scene.camera.pickEllipsoid(center);
  404. // 判断中心点是否在椭球体上
  405. if (this.Cesium.defined(position)) {
  406. // 获取三维地图中心点与相机之间的距离
  407. let distance = this.Cesium.Cartesian3.distance(position, this.$data._viewer3D.scene.camera.positionWC);
  408. position = this.convertWorldToCartographic(position);
  409. // 更新二维地图
  410. this.$data._viewer2D.scene.camera.setView({
  411. destination: new this.Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, distance)
  412. });
  413. }
  414. }
  415. if (this.mousevalue == "2D") {
  416. // 二维地图中心点
  417. let center = new this.Cesium.Cartesian2(
  418. Math.floor(this.$data._viewer2D.canvas.clientWidth / 2),
  419. Math.floor(this.$data._viewer2D.canvas.clientHeight / 2)
  420. );
  421. // 转为世界坐标系
  422. let position = this.$data._viewer2D.scene.camera.pickEllipsoid(center);
  423. // 判断中心点是否在椭球体上
  424. if (this.Cesium.defined(position)) {
  425. // 获取三维地图中心点与相机之间的距离
  426. let distance = this.$data._viewer2D.scene.camera.positionCartographic.height;
  427. position = this.convertWorldToCartographic(position);
  428. // 更新三维地图
  429. this.$data._viewer3D.scene.camera.setView({
  430. destination: new this.Cesium.Cartesian3.fromDegrees(position.longitude, position.latitude, distance)
  431. });
  432. }
  433. }
  434. },
  435. // 将世界坐标系转换为经纬度坐标系
  436. convertWorldToCartographic(worldPosition) {
  437. const ellipsoid = this.$data._viewer2D.scene.globe.ellipsoid;
  438. const cartographic = ellipsoid.cartesianToCartographic(worldPosition);
  439. const longitude = this.Cesium.Math.toDegrees(cartographic.longitude);
  440. const latitude = this.Cesium.Math.toDegrees(cartographic.latitude);
  441. const height = cartographic.height;
  442. return { longitude, latitude, height };
  443. },
  444. // 监听地图变化
  445. changeActive(value) {
  446. this.mousevalue = value;
  447. },
  448. dimensionswitch(value) {
  449. this.dimension = value;
  450. this.selectModel();
  451. },
  452. // 全屏缩小
  453. ismax() {
  454. if (screenfull.isEnabled && screenfull.isFullscreen) {
  455. screenfull.exit();
  456. } else {
  457. screenfull.request();
  458. }
  459. },
  460. /* 获取camera中心点坐标 */
  461. getCenterPosition(is3D = false) {
  462. let viewer = is3D ? this.$data._viewer3D : this.$data._viewer2D;
  463. let result = viewer.camera.pickEllipsoid(
  464. new this.Cesium.Cartesian2(viewer.canvas.clientWidth / 2, viewer.canvas.clientHeight / 2)
  465. );
  466. let curPosition = this.Cesium.Ellipsoid.WGS84.cartesianToCartographic(result);
  467. let lon = (curPosition.longitude * 180) / Math.PI;
  468. let lat = (curPosition.latitude * 180) / Math.PI;
  469. let height = viewer.camera.positionCartographic.height;
  470. return {
  471. lon: lon,
  472. lat: lat,
  473. height: height
  474. };
  475. },
  476. /* 地图放大 */
  477. big() {
  478. let { lon, lat, height } = this.getCenterPosition(this.dimension === 3);
  479. let viewer = (this.dimension === 3 || this.dimension === 5) ? this.$data._viewer3D : this.$data._viewer2D;
  480. // 镜头拉进
  481. viewer.camera.flyTo({
  482. destination: this.Cesium.Cartesian3.fromDegrees(lon, lat, height / 1.8),
  483. duration: 1.0
  484. });
  485. },
  486. /* 地图缩小 */
  487. small() {
  488. let { lon, lat, height } = this.getCenterPosition(this.dimension === 3);
  489. let viewer = (this.dimension === 3 || this.dimension === 5) ? this.$data._viewer3D : this.$data._viewer2D;
  490. // 镜头远离
  491. viewer.camera.flyTo({
  492. destination: this.Cesium.Cartesian3.fromDegrees(lon, lat, height * 1.2),
  493. duration: 1.0
  494. });
  495. },
  496. home() {
  497. let viewer = (this.dimension === 3 || this.dimension === 5) ? this.$data._viewer3D : this.$data._viewer2D;
  498. viewer.camera.flyTo({
  499. destination: this.Cesium.Cartesian3.fromDegrees(117.918977, 25.0, 1500000),
  500. duration: 2.0
  501. });
  502. },
  503. // tabs 切换点击
  504. legendClick({ index }) {
  505. this.selectModel();
  506. let tab_content = document.querySelectorAll(".menu .el-tabs__content");
  507. if (this.currentLab.index == index) {
  508. tab_content[0].style.display == "none" || ""
  509. ? (tab_content[0].style.display = "block")
  510. : (tab_content[0].style.display = "none");
  511. }
  512. if (this.currentLab.index != index) {
  513. this.currentLab.index = index;
  514. tab_content[0].style.display = "block";
  515. }
  516. },
  517. mouseMove(event) {
  518. if (this.$refs.modeltooltip) {
  519. this.$refs.modeltooltip.style.left = event.pageX - 240 + "px";
  520. this.$refs.modeltooltip.style.top = event.pageY - 115 + "px";
  521. }
  522. },
  523. //显示鼠标经纬度
  524. getMouseLocation(event) {
  525. let { longitude, latitude } = this.getCoordinatesFromEvent(event);
  526. this.$store.commit("app/setMouseLocation", { longitude, latitude });
  527. },
  528. /*根据camera高度近似计算当前层级*/
  529. heightToZoom(height) {
  530. var A = 40487.57;
  531. var B = 0.00007096758;
  532. var C = 91610.74;
  533. var D = -40467.74;
  534. return Math.round(D + (A - D) / (1 + Math.pow(height / C, B)));
  535. },
  536. getCammeraHeightAndZoom() {
  537. let viewer = (this.dimension === 3 || this.dimension === 5) ? this.$data._viewer3D : this.$data._viewer2D;
  538. //获取当前相机高度
  539. let height = viewer.camera.positionCartographic.height;
  540. let zoom = this.heightToZoom(height);
  541. this.$store.commit("app/setCameraHeightAndZoom", { height, zoom });
  542. },
  543. selectModel(cursorStyle, image, info) {
  544. console.log('image :>> ', image);
  545. let earthMap = document.getElementById("earth");
  546. earthMap.style.cursor = cursorStyle || "auto";
  547. if (cursorStyle) {
  548. document.addEventListener("mousemove", this.mouseMove);
  549. this.isShow = true;
  550. this.image = image;
  551. this.modeltooltip = info;
  552. } else {
  553. document.removeEventListener("mousemove", this.mouseMove);
  554. this.isShow = false;
  555. this.image = null;
  556. this.modeltooltip = null;
  557. }
  558. },
  559. markLocationbyJson(latitude, longitude, height, name, type) {
  560. const position = this.Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
  561. console.log('position :>> ', position);
  562. let color = ''
  563. let modelUrl = ''
  564. if (type == 'red') {
  565. color = 'Red'
  566. modelUrl = missileModel
  567. this.missileList[name] = {
  568. disturb: 20,
  569. id: this.id
  570. }
  571. }
  572. else if (type == 'blue') {
  573. color = 'Blue'
  574. modelUrl = radarModel
  575. this.thaadList[name] = {
  576. range: 700000.0,
  577. health: 100.0,
  578. id: this.id
  579. }
  580. }
  581. else if (type == 'center') {
  582. color = 'Blue'
  583. modelUrl = centerModel
  584. this.centerPosition = position
  585. }
  586. else if (type == 'satelite') {
  587. color = 'Blue'
  588. modelUrl = satelliteModel
  589. }
  590. if (type == 'blue') {
  591. console.log(' radar!!!');
  592. const range = 700000;
  593. this.$data._viewer2D.entities.add({
  594. id: this.id,
  595. position: position,
  596. ellipsoid: {
  597. radii: new this.Cesium.Cartesian3(range, range, range),
  598. material: this.Cesium.Color.GREEN.withAlpha(0.5), // 设置球体的颜色和透明度
  599. outline: true,
  600. outlineColor: this.Cesium.Color.GREEN,
  601. },
  602. point: {
  603. pixelSize: 12, // 调整点的大小,可以增大点的像素大小
  604. color: this.Cesium.Color.fromCssColorString(color)
  605. },
  606. model: {
  607. uri: modelUrl, // 替换为你的3D模型文件路径
  608. scale: 1.0, // 调整3D模型的缩放大小
  609. minimumPixelSize: 64 // 设置3D模型的最小像素大小,确保在视图中可见
  610. },
  611. label: {
  612. text: type + ' ' + name,
  613. show: true,
  614. font: "18px Helvetica", // 调整标签的字体样式和大小
  615. pixelOffset: new this.Cesium.Cartesian2(0, 20) // 调整标签的像素偏移,向下偏移20像素
  616. }
  617. });
  618. this.$data._viewer3D.entities.add({
  619. id: this.id,
  620. position: position,
  621. ellipsoid: {
  622. radii: new this.Cesium.Cartesian3(range, range, range),
  623. material: this.Cesium.Color.GREEN.withAlpha(0.5), // 设置球体的颜色和透明度
  624. outline: true,
  625. outlineColor: this.Cesium.Color.GREEN,
  626. },
  627. point: {
  628. pixelSize: 12, // 调整点的大小,可以增大点的像素大小
  629. color: this.Cesium.Color.fromCssColorString(color)
  630. },
  631. model: {
  632. uri: modelUrl, // 替换为你的3D模型文件路径
  633. scale: 1.0, // 调整3D模型的缩放大小
  634. minimumPixelSize: 64 // 设置3D模型的最小像素大小,确保在视图中可见
  635. },
  636. label: {
  637. text: type + ' ' + name,
  638. show: true,
  639. font: "18px Helvetica", // 调整标签的字体样式和大小
  640. pixelOffset: new this.Cesium.Cartesian2(0, 20) // 调整标签的像素偏移,向下偏移20像素
  641. }
  642. });
  643. this.nameIdList.push({
  644. id: this.id,
  645. name: name
  646. })
  647. this.id++;
  648. }
  649. else {
  650. this.$data._viewer2D.entities.add({
  651. id: this.id,
  652. position: position,
  653. point: {
  654. pixelSize: 12, // 调整点的大小,可以增大点的像素大小
  655. color: this.Cesium.Color.fromCssColorString(color)
  656. },
  657. model: {
  658. uri: modelUrl, // 替换为你的3D模型文件路径
  659. scale: 1.0, // 调整3D模型的缩放大小
  660. minimumPixelSize: 64 // 设置3D模型的最小像素大小,确保在视图中可见
  661. },
  662. label: {
  663. text: type + ' ' + name,
  664. show: true,
  665. font: "18px Helvetica", // 调整标签的字体样式和大小
  666. pixelOffset: new this.Cesium.Cartesian2(0, 20) // 调整标签的像素偏移,向下偏移20像素
  667. }
  668. });
  669. this.$data._viewer3D.entities.add({
  670. id: this.id,
  671. position: position,
  672. point: {
  673. pixelSize: 12, // 调整点的大小,可以增大点的像素大小
  674. color: this.Cesium.Color.fromCssColorString(color)
  675. },
  676. model: {
  677. uri: modelUrl, // 替换为你的3D模型文件路径
  678. scale: 1.0, // 调整3D模型的缩放大小
  679. minimumPixelSize: 64 // 设置3D模型的最小像素大小,确保在视图中可见
  680. },
  681. label: {
  682. text: type + ' ' + name,
  683. show: true,
  684. font: "18px Helvetica", // 调整标签的字体样式和大小
  685. pixelOffset: new this.Cesium.Cartesian2(0, 20) // 调整标签的像素偏移,向下偏移20像素
  686. }
  687. });
  688. this.nameIdList.push({
  689. id: this.id,
  690. name: name
  691. })
  692. this.id++;
  693. }
  694. },
  695. // 从鼠标点击事件获取坐标
  696. getCoordinatesFromEvent(event) {
  697. let viewer = this.mousevalue === "2D" ? this.$data._viewer2D : this.$data._viewer3D;
  698. let clickPosition;
  699. if (this.dimension === 5 && this.mousevalue === "3D") {
  700. clickPosition = new this.Cesium.Cartesian2(event.clientX - 1080, event.clientY - 160);
  701. } else {
  702. clickPosition = new this.Cesium.Cartesian2(event.clientX - 280, event.clientY - 160);
  703. }
  704. // 获取地图上的经纬度
  705. const viewerPosition = viewer.scene.camera.pickEllipsoid(clickPosition);
  706. const cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(viewerPosition);
  707. const latitude = this.Cesium.Math.toDegrees(cartographic.latitude);
  708. const longitude = this.Cesium.Math.toDegrees(cartographic.longitude);
  709. return {
  710. latitude,
  711. longitude
  712. };
  713. },
  714. markLine(point1, point2, color) {
  715. // 从点1和点2的WGS84坐标创建Cartesian3对象
  716. const position1 = this.Cesium.Cartesian3.fromDegrees(point1.longitude, point1.latitude, point1.height || 0);
  717. const position2 = this.Cesium.Cartesian3.fromDegrees(point2.longitude, point2.latitude, point2.height || 0);
  718. // 创建一个带有箭头图标的PolylineMaterial
  719. const material = new this.Cesium.PolylineArrowMaterialProperty(
  720. this.Cesium.Color.fromCssColorString(color || "red")
  721. );
  722. // 将点1和点2之间的连线添加到Viewer中
  723. this.$data._viewer2D.entities.add({
  724. polyline: {
  725. positions: [position1, position2],
  726. width: 5, // 设置线的宽度
  727. material: material,
  728. followSurface: false // 设置为false,使连线保持在固定的高度,不会贴地显示
  729. }
  730. });
  731. this.$data._viewer3D.entities.add({
  732. polyline: {
  733. positions: [position1, position2],
  734. width: 5, // 设置线的宽度
  735. material: material,
  736. followSurface: false // 设置为false,使连线保持在固定的高度,不会贴地显示
  737. }
  738. });
  739. },
  740. markSatelliteLine(position1, position2, color, viewer) {
  741. // 创建一个带有箭头图标的PolylineMaterial
  742. const material = new this.Cesium.PolylineArrowMaterialProperty(
  743. this.Cesium.Color.fromCssColorString(color || "red")
  744. );
  745. // 将点1和点2之间的连线添加到Viewer中
  746. viewer.entities.add({
  747. polyline: {
  748. positions: [position1, position2],
  749. width: 5, // 设置线的宽度
  750. material: material,
  751. followSurface: false // 设置为false,使连线保持在固定的高度,不会贴地显示
  752. }
  753. });
  754. },
  755. setTimeLine(startTime, endtime, stepTime) {
  756. let start = this.Cesium.JulianDate.fromDate(new Date(startTime)); // 设置时间轴当前时间为开始时间
  757. let stop = this.Cesium.JulianDate.fromDate(new Date(endtime));
  758. // 添加8小时,使地图时间和北京时间相同
  759. start = this.Cesium.JulianDate.addHours(start, 8, new this.Cesium.JulianDate());
  760. stop = this.Cesium.JulianDate.addHours(stop, 8, new this.Cesium.JulianDate());
  761. // 设置时钟开始时间
  762. this.$data._viewer2D.clock.startTime = start.clone();
  763. this.$data._viewer3D.clock.startTime = start.clone();
  764. // 设置时钟当前时间
  765. this.$data._viewer2D.clock.currentTime = start.clone();
  766. this.$data._viewer3D.clock.currentTime = start.clone();
  767. // 设置时钟结束时间
  768. this.$data._viewer2D.clock.stopTime = stop.clone();
  769. this.$data._viewer3D.clock.stopTime = stop.clone();
  770. // 时间速率,数字越大时间过的越快,设置1好像是和实际时间一样
  771. this.$data._viewer2D.clock.multiplier = stepTime;
  772. this.$data._viewer3D.clock.multiplier = stepTime;
  773. // 时间轴绑定到viewer上去
  774. this.$data._viewer2D.timeline.zoomTo(start, stop);
  775. this.$data._viewer3D.timeline.zoomTo(start, stop);
  776. // 循环执行,到达终止时间,重新从起点时间开始
  777. this.$data._viewer2D.clock.clockRange = this.Cesium.ClockRange.LOOP_STOP;
  778. this.$data._viewer3D.clock.clockRange = this.Cesium.ClockRange.LOOP_STOP;
  779. this.messageList.push({
  780. order: this.order++,
  781. time: startTime,
  782. context: "开始模拟!!!"
  783. })
  784. this.$data._viewer2D.clock.onTick.addEventListener(clock => {
  785. const currentTime = clock.currentTime; // 获取当前时间轴的时间
  786. const elapsedTime = this.Cesium.JulianDate.secondsDifference(
  787. currentTime,
  788. this.$data._viewer2D.clock.startTime
  789. ); // 获取从起始时间到当前时间的秒数
  790. if (parseInt(elapsedTime) % stepTime === 0 && elapsedTime != 0) {
  791. // 当从起始时间到当前时间的秒数是 stepTime 的倍数时,发送请求
  792. this.requestDataAndUpdateModel2D(startTime, elapsedTime);
  793. }
  794. });
  795. this.$data._viewer3D.clock.onTick.addEventListener(clock => {
  796. const currentTime = clock.currentTime; // 获取当前时间轴的时间
  797. const elapsedTime = this.Cesium.JulianDate.secondsDifference(
  798. currentTime,
  799. this.$data._viewer3D.clock.startTime
  800. ); // 获取从起始时间到当前时间的秒数
  801. if (parseInt(elapsedTime) % stepTime === 0 && elapsedTime != 0) {
  802. // 当从起始时间到当前时间的秒数是 stepTime 的倍数时,发送请求
  803. this.requestDataAndUpdateModel3D(startTime, elapsedTime);
  804. }
  805. });
  806. this.initSTK()
  807. },
  808. // 初始化stk方法,生成轨迹文件
  809. async initSTK() {
  810. console.log('this.jsonData :>> ', this.jsonData);
  811. // await axios
  812. // .get("/api", this.jsonData).then(res=>{
  813. // console.log('res :>> ', res);
  814. // })
  815. const config = {
  816. timeout: 0 // 设置超时时间为0,表示忽略超时问题
  817. };
  818. await axios
  819. .post("/api/traj", this.jsonData, config).then(res => {
  820. console.log('res :>> ', res);
  821. let data = res.data[1].data[0]
  822. for (let key in data) {
  823. let isSatellite = true
  824. //判断是否为卫星
  825. for (let i = 0; i < this.nameIdList.length; i++) {
  826. if (key === this.nameIdList[i].name || key === 'dateTime') {
  827. isSatellite = false
  828. break
  829. }
  830. }
  831. // 新建卫星实体
  832. if (isSatellite) {
  833. let range = 1000000
  834. console.log('key :>> ', key);
  835. let x = parseFloat(data[key].x) * 1000
  836. let y = parseFloat(data[key].y) * 1000
  837. let z = parseFloat(data[key].z) * 1000
  838. //终点位置
  839. let position = new this.Cesium.Cartesian3(x, y, z);
  840. let cylinderposition = this.convertWorldToCartographic(position)
  841. cylinderposition.height = cylinderposition.height / 10.0
  842. cylinderposition = this.Cesium.Cartesian3.fromDegrees(cylinderposition.longitude, cylinderposition.latitude, cylinderposition.height);
  843. this.$data._viewer2D.entities.add({
  844. id: this.id,
  845. position: position,
  846. point: {
  847. pixelSize: 12, // 调整点的大小,可以增大点的像素大小
  848. color: this.Cesium.Color.fromCssColorString('Blue')
  849. },
  850. // cylinder: {
  851. // length: range, // 锥形的高度,可以根据需要调整
  852. // topRadius: 0,
  853. // bottomRadius: range / 2,
  854. // material: this.Cesium.Color.BLUE.withAlpha(0.5), // 设置锥形的颜色和透明度
  855. // outline: true,
  856. // outlineColor: this.Cesium.Color.BLUE,
  857. // },
  858. model: {
  859. uri: satelliteModel, // 替换为你的3D模型文件路径
  860. scale: 1.0, // 调整3D模型的缩放大小
  861. minimumPixelSize: 64 // 设置3D模型的最小像素大小,确保在视图中可见
  862. },
  863. label: {
  864. text: 'satellite ' + key,
  865. show: true,
  866. font: "18px Helvetica", // 调整标签的字体样式和大小
  867. pixelOffset: new this.Cesium.Cartesian2(0, 20) // 调整标签的像素偏移,向下偏移20像素
  868. }
  869. });
  870. this.$data._viewer2D.entities.add({
  871. id: this.id + 1,
  872. position: cylinderposition,
  873. cylinder: {
  874. length: range, // 锥形的高度,可以根据需要调整
  875. topRadius: 0,
  876. bottomRadius: range / 2,
  877. material: this.Cesium.Color.BLUE.withAlpha(0.5), // 设置锥形的颜色和透明度
  878. outline: true,
  879. outlineColor: this.Cesium.Color.BLUE,
  880. },
  881. });
  882. this.$data._viewer3D.entities.add({
  883. id: this.id,
  884. position: position,
  885. point: {
  886. pixelSize: 12, // 调整点的大小,可以增大点的像素大小
  887. color: this.Cesium.Color.fromCssColorString('Blue')
  888. },
  889. // cylinder: {
  890. // length: range, // 锥形的高度,可以根据需要调整
  891. // topRadius: 0,
  892. // bottomRadius: range / 2,
  893. // material: this.Cesium.Color.BLUE.withAlpha(0.5), // 设置锥形的颜色和透明度
  894. // outline: true,
  895. // outlineColor: this.Cesium.Color.BLUE,
  896. // },
  897. model: {
  898. uri: satelliteModel, // 替换为你的3D模型文件路径
  899. scale: 1.0, // 调整3D模型的缩放大小
  900. minimumPixelSize: 64 // 设置3D模型的最小像素大小,确保在视图中可见
  901. },
  902. label: {
  903. text: 'satellite ' + key,
  904. show: true,
  905. font: "18px Helvetica", // 调整标签的字体样式和大小
  906. pixelOffset: new this.Cesium.Cartesian2(0, 20) // 调整标签的像素偏移,向下偏移20像素
  907. },
  908. });
  909. this.$data._viewer3D.entities.add({
  910. id: this.id + 1,
  911. position: cylinderposition,
  912. cylinder: {
  913. length: range, // 锥形的高度,可以根据需要调整
  914. topRadius: 0,
  915. bottomRadius: range / 2,
  916. material: this.Cesium.Color.BLUE.withAlpha(0.5), // 设置锥形的颜色和透明度
  917. outline: true,
  918. outlineColor: this.Cesium.Color.BLUE,
  919. },
  920. });
  921. this.nameIdList.push({
  922. id: this.id,
  923. name: key
  924. })
  925. this.satelliteRange.push({
  926. satelliteId: this.id,
  927. rangeId: this.id + 1
  928. })
  929. this.id++;
  930. this.id++;
  931. }
  932. }
  933. })
  934. },
  935. // 根据时间参数请求模型位置并更新 2D
  936. async requestDataAndUpdateModel2D(startTime, elapsedTime) {
  937. const jsDate = new Date(startTime);
  938. // 增加 elapsedTime 秒
  939. jsDate.setSeconds(jsDate.getSeconds() + elapsedTime);
  940. // 转换为需求字符串格式
  941. const newTimeString = `${jsDate.getFullYear()}-${(jsDate.getMonth() + 1).toString().padStart(2, '0')}-${jsDate.getDate().toString().padStart(2, '0')} ${jsDate.getHours().toString().padStart(2, '0')}:${jsDate.getMinutes().toString().padStart(2, '0')}:${jsDate.getSeconds().toString().padStart(2, '0')}`;
  942. await axios
  943. .post("/api/pos", { simulation_time: newTimeString + '.000' }).then(res => {
  944. console.log('res :>> ', res);
  945. let data = res.data[1].data
  946. //依次更新每个模型位置
  947. for (let i = 0; i < this.nameIdList.length; i++) {
  948. if (data[this.nameIdList[i].name] != null && data[this.nameIdList[i].name] != undefined) {
  949. this.modelEntityMoveByIDAndLocation(this.$data._viewer2D, this.nameIdList[i].id, data[this.nameIdList[i].name].x, data[this.nameIdList[i].name].y, data[this.nameIdList[i].name].z)
  950. }
  951. }
  952. for (let i = 0; i < this.nameIdList.length; i++) {
  953. if (this.thaadList[this.nameIdList[i].name] != null || this.thaadList[this.nameIdList[i].name] != undefined) {
  954. //查看在雷达原侦察范围内有几颗导弹
  955. let missileNum = this.howManyMissile(this.$data._viewer2D, this.thaadList[this.nameIdList[i].name].id, this.nameIdList[i].name)
  956. let health = 100.0
  957. for (let j = 0; j < missileNum; j++) {
  958. health = health * 0.8
  959. }
  960. if (this.thaadList[this.nameIdList[i].name].health != health) {
  961. //修改健康值并修改范围
  962. let mark = true
  963. if (health > this.thaadList[this.nameIdList[i].name].health) {
  964. mark = false
  965. }
  966. this.thaadList[this.nameIdList[i].name].health = health
  967. this.changeRange(this.$data._viewer2D, this.thaadList[this.nameIdList[i].name].id, this.thaadList[this.nameIdList[i].name].range, this.thaadList[this.nameIdList[i].name].health, newTimeString, this.nameIdList[i].name, mark)
  968. }
  969. }
  970. }
  971. this.judgeMissile(this.$data._viewer2D, newTimeString);
  972. //判断攻防是否结束
  973. if (this.ifFinish(this.$data._viewer3D, newTimeString)) {
  974. // 停止时间轴动画
  975. this.$data._viewer2D.clock.shouldAnimate = false;
  976. this.dialogVisible = true
  977. }
  978. //更新模型位置
  979. // this.modelEntityMoveByIDAndLocation(this.$data._viewer2D,"1654426964397658112",res.data[1].data.W1.x,res.data[1].data.W1.y,res.data[1].data.W1.z)
  980. })
  981. },
  982. // 根据时间参数请求模型位置并更新 3D
  983. async requestDataAndUpdateModel3D(startTime, elapsedTime) {
  984. const jsDate = new Date(startTime);
  985. // 增加 elapsedTime 秒
  986. jsDate.setSeconds(jsDate.getSeconds() + elapsedTime);
  987. // 转换为需求字符串格式
  988. const newTimeString = `${jsDate.getFullYear()}-${(jsDate.getMonth() + 1).toString().padStart(2, '0')}-${jsDate.getDate().toString().padStart(2, '0')} ${jsDate.getHours().toString().padStart(2, '0')}:${jsDate.getMinutes().toString().padStart(2, '0')}:${jsDate.getSeconds().toString().padStart(2, '0')}`;
  989. await axios
  990. .post("/api/pos", { simulation_time: newTimeString + '.000' }).then(res => {
  991. let data = res.data[1].data
  992. //依次更新每个模型位置
  993. for (let i = 0; i < this.nameIdList.length; i++) {
  994. if (this.nameIdList[i].name in data) {
  995. console.log(' 开始移动' + this.nameIdList[i].name);
  996. this.modelEntityMoveByIDAndLocation(this.$data._viewer3D, this.nameIdList[i].id, data[this.nameIdList[i].name].x, data[this.nameIdList[i].name].y, data[this.nameIdList[i].name].z)
  997. }
  998. }
  999. for (let i = 0; i < this.nameIdList.length; i++) {
  1000. if (this.thaadList[this.nameIdList[i].name] != null || this.thaadList[this.nameIdList[i].name] != undefined) {
  1001. //查看在雷达原侦察范围内有几颗导弹
  1002. let missileNum = this.howManyMissile(this.$data._viewer3D, this.thaadList[this.nameIdList[i].name].id, this.nameIdList[i].name)
  1003. let health = 100.0
  1004. //变化健康值
  1005. for (let j = 0; j < missileNum; j++) {
  1006. health = health * 0.8
  1007. }
  1008. if (this.thaadList[this.nameIdList[i].name].health != health) {
  1009. //修改健康值并修改范围
  1010. let mark = true
  1011. if (health > this.thaadList[this.nameIdList[i].name].health) {
  1012. mark = false
  1013. }
  1014. this.thaadList[this.nameIdList[i].name].health = health
  1015. this.changeRange(this.$data._viewer3D, this.thaadList[this.nameIdList[i].name].id, this.thaadList[this.nameIdList[i].name].range, this.thaadList[this.nameIdList[i].name].health, newTimeString, this.nameIdList[i].name, mark)
  1016. }
  1017. }
  1018. }
  1019. //判断是否有导弹被拦截
  1020. this.judgeMissile(this.$data._viewer3D, newTimeString);
  1021. //判断攻防是否结束
  1022. if (this.ifFinish(this.$data._viewer3D, newTimeString)) {
  1023. // 停止时间轴动画
  1024. this.$data._viewer3D.clock.shouldAnimate = false;
  1025. this.dialogVisible = true
  1026. }
  1027. //更新模型位置
  1028. // this.modelEntityMoveByIDAndLocation(this.$data._viewer3D,viewer,"1654426964397658112",res.data[1].data.W1.x,res.data[1].data.W1.y,res.data[1].data.W1.z)
  1029. })
  1030. },
  1031. // 根据模型实体Id和终点位置进行移动
  1032. modelEntityMoveByIDAndLocation(viewer, id, x, y, z) {
  1033. x = parseFloat(x) * 1000
  1034. y = parseFloat(y) * 1000
  1035. z = parseFloat(z) * 1000
  1036. let entity = viewer.entities.getById(id)
  1037. for (let i = 0; i < this.satelliteRange.length; i++) {
  1038. if (id == this.satelliteRange[i].satelliteId) {
  1039. //是卫星
  1040. let rangeEntity = viewer.entities.getById(this.satelliteRange[i].rangeId)
  1041. let position = new this.Cesium.Cartesian3(x, y, z);
  1042. let cylinderposition = this.convertWorldToCartographic(position)
  1043. cylinderposition = this.Cesium.Cartesian3.fromDegrees(cylinderposition.longitude, cylinderposition.latitude, cylinderposition.height / 10.0);
  1044. let oldPosition = viewer.entities.getById(id).position._value
  1045. //设置方向,根据实体的位置来配置方向
  1046. entity.orientation = new this.Cesium.VelocityOrientationProperty(entity.position);
  1047. //设置实体位置
  1048. entity.position.setValue(position)
  1049. //设置方向,根据实体的位置来配置方向
  1050. rangeEntity.orientation = new this.Cesium.VelocityOrientationProperty(rangeEntity.position);
  1051. //设置实体位置getValue
  1052. rangeEntity.position.setValue(cylinderposition)
  1053. this.markSatelliteLine(oldPosition, position, 'Blue', viewer)
  1054. }
  1055. }
  1056. //终点位置
  1057. let position = new this.Cesium.Cartesian3(x, y, z);
  1058. let oldPosition = viewer.entities.getById(id).position._value
  1059. //设置方向,根据实体的位置来配置方向
  1060. entity.orientation = new this.Cesium.VelocityOrientationProperty(entity.position);
  1061. //设置实体位置
  1062. entity.position.setValue(position)
  1063. this.markSatelliteLine(oldPosition, position, 'Blue', viewer)
  1064. },
  1065. //计算有多少个导弹进入了雷达的原始范围
  1066. howManyMissile(viewer, id, name) {
  1067. let radar = viewer.entities.getById(id)
  1068. let radarPos = radar.position._value
  1069. let num = 0
  1070. for (let key in this.missileList) {
  1071. let missilePos = viewer.entities.getById(this.missileList[key].id).position._value
  1072. if (this.Cesium.Cartesian3.distance(radarPos, missilePos) <= this.thaadList[name].range) {//距离小于range
  1073. num++
  1074. }
  1075. }
  1076. return num;
  1077. },
  1078. //判断导弹是否被拦截
  1079. judgeMissile(viewer, time) {
  1080. for (let key in this.missileList) {
  1081. let missile = viewer.entities.getById(this.missileList[key].id)
  1082. let missilePos = viewer.entities.getById(this.missileList[key].id).position._value
  1083. for (let item in this.thaadList) {
  1084. let radarPos = viewer.entities.getById(this.thaadList[item].id).position._value
  1085. if (this.Cesium.Cartesian3.distance(radarPos, missilePos) <= this.thaadList[item].range * this.thaadList[item].health * 0.01) {
  1086. // 导弹进入了被干扰后的雷达探测范围,判断被拦截 移除实体,删除信息
  1087. this.messageList.push({
  1088. order: this.order++,
  1089. time: time,
  1090. context: '导弹' + key + '被雷达' + item + '拦截!!!'
  1091. })
  1092. viewer.entities.remove(missile)
  1093. this.nameIdList = this.nameIdList.filter(item => item.id !== this.missileList[key].id);
  1094. delete this.missileList[key]
  1095. break
  1096. }
  1097. }
  1098. }
  1099. },
  1100. //修改雷达的显示范围
  1101. changeRange(viewer, id, range, health, time, name, mark) {
  1102. let context = '雷达' + name + '受到干扰!健康值变化为: ' + health
  1103. if (!mark) {
  1104. context = '雷达' + name + '恢复健康值,健康值变化为: ' + health
  1105. }
  1106. this.messageList.push({
  1107. order: this.order++,
  1108. time: time,
  1109. context: context
  1110. })
  1111. let radar = viewer.entities.getById(id)
  1112. let newRange = range * health * 0.01
  1113. radar.ellipsoid.radii = new this.Cesium.Cartesian3(newRange, newRange, newRange);
  1114. },
  1115. isObjectEmpty(obj) {
  1116. for (let key in obj) {
  1117. if (obj.hasOwnProperty(key)) {
  1118. return false; // 如果对象有任何属性,返回 false
  1119. }
  1120. }
  1121. return true; // 如果对象没有任何属性,返回 true
  1122. },
  1123. //判断攻防是否完成
  1124. ifFinish(viewer, time) {
  1125. if (this.isObjectEmpty(this.missileList)) {
  1126. this.messageList.push({
  1127. order: this.order,
  1128. time: time,
  1129. context: '全部导弹被拦截,红方进攻失败,蓝方防守成功!!!'
  1130. })
  1131. return true
  1132. }
  1133. else {
  1134. for (let key in this.missileList) {
  1135. let missilePos = viewer.entities.getById(this.messageList[key].id).position._value
  1136. if (this.Cesium.Cartesian3.distance(this.centerPosition, missilePos) <= 100) {
  1137. this.messageList.push({
  1138. order: this.order,
  1139. time: time,
  1140. context: '导弹' + key + '成功摧毁蓝方指挥中心!!!'
  1141. })
  1142. return true
  1143. }
  1144. }
  1145. }
  1146. return false
  1147. }
  1148. }
  1149. };
  1150. </script>
  1151. <style scoped>
  1152. ::v-deep .cesium-infoBox {
  1153. display: none !important;
  1154. }
  1155. ::v-deep .cesium-infoBox-bodyless {
  1156. display: none !important;
  1157. }
  1158. ::v-deep .cesium-infoBox-visible {
  1159. display: none !important;
  1160. }
  1161. .container {
  1162. height: 100%;
  1163. position: relative;
  1164. }
  1165. .modeltooltip {
  1166. position: absolute;
  1167. padding: 5px;
  1168. color: #fff;
  1169. font-size: 20px;
  1170. pointer-events: none;
  1171. z-index: 999;
  1172. }
  1173. .myHeader {
  1174. background-color: #1c222b !important;
  1175. color: #fff;
  1176. height: 100%;
  1177. display: flex;
  1178. flex-direction: row;
  1179. align-items: center;
  1180. /*由于flex-direction: column,因此align-items代表的是水平方向*/
  1181. justify-content: center;
  1182. /*由于flex-direction: column,因此justify-content代表的是垂直方向*/
  1183. }
  1184. .myHeader .el-button {
  1185. width: 100px;
  1186. height: 20px;
  1187. padding: 1px 23px;
  1188. }
  1189. .box-card {
  1190. min-height: 100%;
  1191. height: 100%;
  1192. }
  1193. ::v-deep .el-card__body {
  1194. height: 100% !important;
  1195. padding: 0px !important;
  1196. }
  1197. .main-layout {
  1198. height: 100%;
  1199. width: 100%;
  1200. }
  1201. .map {
  1202. width: 100%;
  1203. height: 100%;
  1204. }
  1205. .menu {
  1206. position: absolute;
  1207. height: 400px;
  1208. z-index: 999;
  1209. left: 20px;
  1210. top: 20px;
  1211. }
  1212. ::v-deep .el-tabs--left .el-tabs__header.is-left {
  1213. margin-right: 0px !important;
  1214. }
  1215. .buttons {
  1216. display: flex;
  1217. flex-direction: column;
  1218. align-items: center;
  1219. justify-items: center;
  1220. position: absolute;
  1221. z-index: 999;
  1222. right: 20px;
  1223. top: 20px;
  1224. }
  1225. .el-button {
  1226. margin: 5px !important;
  1227. }
  1228. ::v-deep .el-tabs--border-card>.el-tabs__content {
  1229. width: 300px;
  1230. height: 100%;
  1231. overflow-y: visible;
  1232. }
  1233. .model {
  1234. display: flex;
  1235. width: 100%;
  1236. flex-wrap: wrap;
  1237. }
  1238. .model>div {
  1239. width: 50%;
  1240. height: 120px;
  1241. padding: 5px;
  1242. }
  1243. .model>div:hover {
  1244. border: 2px solid blue;
  1245. }
  1246. .model>div:active {
  1247. border: 2px solid red;
  1248. }
  1249. .active {
  1250. border: 2px solid red !important;
  1251. }
  1252. .model .el-image {
  1253. display: block !important;
  1254. }
  1255. ::v-deep .el-image .el-image__inner {
  1256. border: 1px solid #ddd;
  1257. border-radius: 5px;
  1258. }
  1259. .item {
  1260. font-size: 14px;
  1261. /* right: 20px; */
  1262. }
  1263. .TimeLine {
  1264. position: absolute;
  1265. left: 21%;
  1266. bottom: 15px;
  1267. transform: translateX(-50%);
  1268. }
  1269. /* 罗盘样式 */
  1270. /deep/.compass {
  1271. pointer-events: auto;
  1272. position: absolute;
  1273. right: 0px;
  1274. top: 280px;
  1275. width: 95px;
  1276. height: 95px;
  1277. overflow: hidden;
  1278. }
  1279. </style>