index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. <template>
  2. <div id="globalMap">
  3. <div class="global-map">
  4. <Map
  5. v-if="mapStore.isAMap"
  6. ref="mapRef"
  7. @handle-show-video="handleShowVideo"
  8. @handle-show-video-detail="handleShowVideo2"
  9. @handle-show-warehouse="handleShowWarehouse"
  10. @handle-show-people="handleShowPeople"
  11. @handle-show-track="handleShowTrack"
  12. @close-detail-dialog="handleCloseDetailDialog"
  13. @resize="mapMoveEnd"
  14. />
  15. <YztMap
  16. v-else-if="!!mapStore.activeMap"
  17. ref="map2Ref"
  18. @handle-show-video="handleShowVideo"
  19. @handle-show-video-detail="handleShowVideo2"
  20. @handle-show-warehouse="handleShowWarehouse"
  21. @handle-show-people="handleShowPeople"
  22. @handle-show-track="handleShowTrack"
  23. @close-detail-dialog="handleCloseDetailDialog"
  24. @resize="mapMoveEnd"
  25. />
  26. <!--左侧菜单-->
  27. <LeftMenu
  28. ref="leftMenuRef"
  29. style="position: absolute; top: 20px; left: 20px"
  30. @click-menu="clickMenu"
  31. @select-search-marker="selectSearchMarker"
  32. />
  33. <!--右侧功能模块-->
  34. <RightMenu ref="rightMenuRef" />
  35. <!--切换地图图层-->
  36. <SwitchMapTool class="tool-box" />
  37. <!--右下角地图工具 -->
  38. <RightTool />
  39. <!--时间轴-->
  40. <TimeAxis ref="timeAxisRef" />
  41. <!--绘制工具-->
  42. <DrawTools v-if="showDrawTools" @handle-analysis-data="handleAnalysisData" />
  43. <!--附近视频-->
  44. <NearbyVideos v-if="showNearbyVideos" v-model="showNearbyVideos" :location="location" />
  45. <!--格点雨量-->
  46. <GridPointRainfall v-if="showRainfall" v-model="showRainfall" :location="location" />
  47. <!--物资详情-->
  48. <MaterialDetail v-if="showWarehouse" v-model="showWarehouse" :warehouse-data="warehouseData" />
  49. <!--通讯保障-->
  50. <CommunicationSupport v-if="communicationSupport.show" @close="handleHideCommunicationSupport" />
  51. <!--应急人员详情-->
  52. <EmergencyCrew v-if="showPeople" v-model="showPeople" :id="teamId" />
  53. <!--视频详情-->
  54. <VideoDialog v-if="showVideoDetail" v-model="showVideoDetail" :videoMonitorData="videoDetail" @close="handleVideoDetailClose" />
  55. </div>
  56. </div>
  57. </template>
  58. <script lang="ts" setup name="globalMap">
  59. import Map from '@/components/Map/index.vue';
  60. import YztMap from '@/components/Map/YztMap/index.vue';
  61. import SwitchMapTool from './SwitchMapTool.vue';
  62. import LeftMenu from './LeftMenu.vue';
  63. import RightMenu from './RightMenu/index.vue';
  64. import MaterialDetail from './MaterialDetail.vue';
  65. import TimeAxis from '@/components/TimeAxis/index.vue';
  66. import DrawTools from './RightMenu/DrawTools.vue';
  67. import CommunicationSupport from './RightMenu/CommunicationSupport.vue';
  68. import GridPointRainfall from './RightMenu/GridPointRainfall.vue';
  69. import EmergencyCrew from './RightMenu/EmergencyCrew.vue';
  70. import useMapStore from '@/store/modules/map';
  71. import { getVehicleTrajectory } from '@/api/globalMap/KeyVehicles';
  72. import { getImageUrl, iconList } from './data/mapData';
  73. import { debounce, deepClone } from '@/utils';
  74. import { parseTime } from '@/utils/ruoyi';
  75. import { getPointInfo2 } from '@/api/videoMonitor';
  76. import { toLonLat } from 'ol/proj';
  77. import { getEventDetail } from '@/api/duty/eventing';
  78. import gcoord from 'gcoord';
  79. //dom元素
  80. const rightMenuRef = ref(null);
  81. const mapRef = ref(null);
  82. const map2Ref = ref(null);
  83. const leftMenuRef = ref(null);
  84. const timeAxisRef = ref(null);
  85. const route = useRoute();
  86. const eventId = ref('');
  87. // 地图
  88. let map: any = {};
  89. // 地图类
  90. let mapUtils: any = {};
  91. const mapStore = useMapStore();
  92. // 附近视频菜单数据
  93. let tempMenu = ref({
  94. name: '',
  95. checked: false
  96. });
  97. const communicationSupport = reactive({
  98. show: false,
  99. data: {}
  100. });
  101. let addMarkersTimer;
  102. // 添加打点
  103. const addMarkers = (item) => {
  104. const dom = mapStore.isAMap ? mapRef.value : map2Ref.value;
  105. if (dom) {
  106. if (!item.checked) {
  107. let index = mapStore.pointType.findIndex((item2) => item.component === item2.component);
  108. if (index > -1) {
  109. mapStore.pointType.splice(index, 1);
  110. }
  111. } else {
  112. // 右侧图层分析状态
  113. item.checked2 = true;
  114. mapStore.pointType.push(item);
  115. }
  116. mapStore.setPointOption();
  117. }
  118. };
  119. const adjustPoint = (data) => {
  120. data.forEach((item2) => {
  121. // 获取图标
  122. if (iconList[item2.dataType]) {
  123. item2.icon = iconList[item2.dataType].image;
  124. item2.image = iconList[item2.dataType].image;
  125. item2.imageHover = iconList[item2.dataType].imageHover;
  126. item2.size = iconList[item2.dataType].size;
  127. } else {
  128. item2.icon = iconList['common'].image;
  129. item2.image = iconList['common'].image;
  130. item2.imageHover = iconList['common'].imageHover;
  131. item2.size = iconList['common'].size;
  132. }
  133. if (item2.materia_name) {
  134. item2.name = item2.materia_name;
  135. }
  136. if (item2.dataType === 43) {
  137. item2.showName = true;
  138. }
  139. item2.lnglat = [item2.longitude, item2.latitude];
  140. });
  141. return data;
  142. };
  143. const addMarkersMethod = debounce(
  144. function () {
  145. if (!mapUtils || Object.keys(mapUtils).length === 0) return;
  146. const queryParams: PointParams = {
  147. zoom_level: mapStore.mapState.zoom,
  148. latitude_min: '',
  149. latitude_max: '',
  150. longitude_min: '',
  151. longitude_max: '',
  152. option: mapStore.pointParams.option,
  153. dict_value: mapStore.pointParams.dict_value.toString()
  154. };
  155. if (!queryParams.option && !queryParams.dict_value) {
  156. return mapUtils.clearMarker2();
  157. }
  158. if (mapStore.isAMap) {
  159. const AMap = mapUtils.getAMap();
  160. const pixel = new AMap.Pixel(0, 0);
  161. const size = mapRef.value.getMapDomSize();
  162. const pixel2 = new AMap.Pixel(size[0], size[1]);
  163. const lnglat = map.containerToLngLat(pixel);
  164. const lnglat2 = map.containerToLngLat(pixel2);
  165. queryParams.longitude_min = lnglat.lng;
  166. queryParams.latitude_max = lnglat.lat;
  167. queryParams.longitude_max = lnglat2.lng;
  168. queryParams.latitude_min = lnglat2.lat;
  169. } else {
  170. // 获取地图容器尺寸
  171. const size = map.getSize();
  172. // 获取左上角和右下角像素坐标
  173. const topLeftPixel = [0, 0];
  174. const bottomRightPixel = [size[0], size[1]];
  175. // 转换为地图投影坐标
  176. const topLeftMap = map.getCoordinateFromPixel(topLeftPixel);
  177. const bottomRightMap = map.getCoordinateFromPixel(bottomRightPixel);
  178. // 转换为经纬度
  179. const lnglat = toLonLat(topLeftMap, map.getView().getProjection());
  180. const lnglat2 = toLonLat(bottomRightMap, map.getView().getProjection());
  181. queryParams.longitude_min = lnglat[0];
  182. queryParams.latitude_max = lnglat[1];
  183. queryParams.longitude_max = lnglat2[0];
  184. queryParams.latitude_min = lnglat2[1];
  185. }
  186. getPointInfo2(queryParams).then((res) => {
  187. // 如果接口返回前,取消所有选择,不赋值
  188. if (!mapStore.pointParams.option && !mapStore.pointParams.dict_value.toString()) {
  189. return;
  190. }
  191. const data = res.data ? res.data : [];
  192. // 通用详情
  193. if (!!detailsData.value.id) {
  194. data.forEach((item) => {
  195. if (item.id === detailsData.value.id) {
  196. item.isHover = true;
  197. } else if (showVideoDetail.value && videoDetail.value) {
  198. data.forEach((item) => {
  199. if (item.id === videoDetail.value.id) {
  200. item.isHover = true;
  201. }
  202. });
  203. }
  204. });
  205. detailsData.value = {
  206. id: '',
  207. dataType: ''
  208. };
  209. }
  210. mapUtils.addMarker2(data);
  211. });
  212. if (addMarkersTimer) {
  213. clearInterval(addMarkersTimer);
  214. addMarkersTimer = null;
  215. }
  216. if (mapStore.pointParams.option.includes('43')) {
  217. addMarkersTimer = setInterval(addMarkersMethod, 60 * 1000);
  218. }
  219. },
  220. 300,
  221. false
  222. );
  223. // 跳转指定地点
  224. const toAddress = (item) => {
  225. const dom = mapStore.activeMap === 'imageMap' ? map2Ref.value : mapRef.value;
  226. dom.setCenter(item);
  227. };
  228. let showDrawTools = ref(false);
  229. // 点击菜单
  230. const clickMenu = (item, dataList) => {
  231. if (item.path === '1') {
  232. // 空间分析
  233. if (item.component === 'spatial') {
  234. showDrawTools.value = !showDrawTools.value;
  235. }
  236. rightMenuRef.value.updateMenu(item.checked ? '1' : '2', item);
  237. } else if (item.path === '2') {
  238. if (item.name === '附近视频') {
  239. // 附近视频
  240. tempMenu.value = item;
  241. //为地图注册click事件获取鼠标点击出的经纬度坐标
  242. map.on('click', handleClickMap);
  243. mapStore.setIsMapSelect(true);
  244. } else {
  245. let checked = item.checked ? '1' : '2';
  246. // 打点信息
  247. addMarkers(item);
  248. if (
  249. ['易涝隐患点', '省政务无人机', '铁塔运行监测', '通讯保障', '救援队伍', '重点车辆', '河道监测', '水库监测'].includes(item.name) ||
  250. item.isVideo
  251. ) {
  252. rightMenuRef.value.updateMenu(checked, item);
  253. } else {
  254. let index = findChecked(dataList, item.name);
  255. if (item.checked && index > 0) {
  256. // 已有图层分析直接切换到该index
  257. rightMenuRef.value.showIndexMenu('图层分析');
  258. } else if (item.checked || (!item.checked && index === 0)) {
  259. rightMenuRef.value.updateMenu(checked, { name: '图层分析', meta: { icon: 'icon1' } });
  260. }
  261. }
  262. }
  263. } else if (item.path === '3') {
  264. // 通讯保障
  265. communicationSupport.show = !communicationSupport.show;
  266. communicationSupport.data = item;
  267. } else if (item.path === '4' && ['定点分析', '格点雨量'].includes(item.name)) {
  268. if (item.name === '定点分析' && !item.checked) {
  269. closeClickMap();
  270. rightMenuRef.value.updateMenu('2', item, []);
  271. } else {
  272. // 定点分析、格点雨量
  273. tempMenu.value = item;
  274. //为地图注册click事件获取鼠标点击出的经纬度坐标
  275. map.on('click', handleClickMap);
  276. mapStore.setIsMapSelect(true);
  277. }
  278. }
  279. // 菜单关闭,移除车辆
  280. if (['手机工作台', '重点车辆', '移动指挥车', '机动无人机', '卫星电话'].includes(item.name) && !item.checked) {
  281. timeAxisRef.value.clearData(item.name);
  282. }
  283. if (item.component == '43' && !item.checked && !mapStore.pointParams.option.includes('43') && addMarkersTimer) {
  284. clearInterval(addMarkersTimer);
  285. addMarkersTimer = null;
  286. }
  287. };
  288. const handleHideCommunicationSupport = () => {
  289. communicationSupport.show = false;
  290. leftMenuRef.value.setMenuChange(communicationSupport.data, false);
  291. };
  292. const findChecked = (dataList, name) => {
  293. let index = 0;
  294. dataList.forEach((item) => {
  295. if (
  296. !['易涝隐患点', '省政务无人机', '铁塔运行监测', '通讯保障', '救援队伍', '重点车辆', '附近视频', '河道监测', '水库监测'].includes(item.name) &&
  297. item.name !== name &&
  298. !item.isVideo &&
  299. item.path === '2' &&
  300. !!item.checked
  301. ) {
  302. index++;
  303. }
  304. if (item.children && item.children.length > 0) {
  305. let res = findChecked(item.children, name);
  306. index += res;
  307. }
  308. });
  309. return index;
  310. };
  311. // 点击搜索结果,添加标注
  312. const selectSearchMarker = (item) => {
  313. const dom = mapStore.isAMap ? mapRef.value : map2Ref.value;
  314. let item2 = deepClone(item);
  315. // 获取图标
  316. if (iconList[item2.dataType]) {
  317. item2.icon = iconList[item2.dataType].imageHover;
  318. item2.image = iconList[item2.dataType].image;
  319. item2.imageHover = iconList[item2.dataType].imageHover;
  320. item2.size = iconList[item2.dataType].size;
  321. } else {
  322. item2.icon = iconList['common'].imageHover;
  323. item2.image = iconList['common'].image;
  324. item2.imageHover = iconList['common'].imageHover;
  325. item2.size = iconList['common'].size;
  326. }
  327. item2.lnglat = [item2.longitude, item2.latitude];
  328. dom.addSearchMarker(item2);
  329. };
  330. const handleAnalysisData = (data) => {
  331. rightMenuRef.value.handleMenu('空间分析', data);
  332. };
  333. const getMapUtils = () => {
  334. const domRef = mapStore.isAMap ? mapRef.value : map2Ref.value;
  335. return !!domRef ? domRef.getMapUtils() : {};
  336. };
  337. // 获取地图元素操作
  338. const getMap = () => {
  339. const domRef = mapStore.isAMap ? mapRef.value : map2Ref.value;
  340. return !!domRef ? domRef.getMap() : {};
  341. };
  342. let detailsData = ref({
  343. id: '',
  344. dataType: ''
  345. });
  346. // 显示打点详情
  347. const showDetail = (data, dataType) => {
  348. const domRef = mapStore.isAMap ? mapRef.value : map2Ref.value;
  349. if (!!domRef) {
  350. const newMap = mapStore.isAMap ? map : map.getView();
  351. newMap.setCenter([data.lng, data.lat]);
  352. newMap.setZoom(18);
  353. detailsData.value = {
  354. id: data.id.toString(),
  355. dataType: dataType
  356. };
  357. }
  358. };
  359. const getDrawTool = () => {
  360. return mapStore.isAMap ? mapRef.value.drawTool : mapUtils;
  361. };
  362. const trackPlayback = (data) => {
  363. const domRef = mapStore.isAMap ? mapRef.value : mapUtils;
  364. if (!!domRef) {
  365. domRef.trackPlayback(data);
  366. }
  367. };
  368. let showNearbyVideos = ref(false);
  369. let showRainfall = ref(false);
  370. let location = ref([]);
  371. watch(showNearbyVideos, () => {
  372. if (!!showNearbyVideos.value) {
  373. closeClickMap();
  374. } else {
  375. clearData();
  376. }
  377. });
  378. watch(showRainfall, () => {
  379. if (!!showRainfall.value) {
  380. closeClickMap();
  381. } else {
  382. clearData();
  383. }
  384. });
  385. const clearData = () => {
  386. location.value = [];
  387. if (!!tempMenu.value && !!tempMenu.value.name) {
  388. leftMenuRef.value.setMenuChange(tempMenu.value, false);
  389. tempMenu.value = {
  390. name: '',
  391. checked: false
  392. };
  393. }
  394. };
  395. const closeClickMap = () => {
  396. if (mapStore.isAMap) {
  397. map.off('click', handleClickMap);
  398. } else {
  399. map.un('click', handleClickMap);
  400. }
  401. mapStore.setIsMapSelect(false);
  402. };
  403. // 显示附近视频
  404. const handleShowVideo = (data) => {
  405. location.value = [data.longitude, data.latitude];
  406. showNearbyVideos.value = true;
  407. };
  408. const showVideoDetail = ref(false);
  409. const videoDetail = ref({});
  410. const handleShowVideo2 = (data, flag) => {
  411. const newMap = mapStore.isAMap ? map : map.getView();
  412. if (!flag) {
  413. newMap.setCenter([data.longitude, data.latitude]);
  414. newMap.setZoom(18);
  415. }
  416. videoDetail.value = data;
  417. showVideoDetail.value = true;
  418. };
  419. const handleVideoDetailClose = () => {
  420. videoDetail.value = [];
  421. mapUtils.clearHoverMarker();
  422. };
  423. const handleClickMap = (e) => {
  424. if (mapStore.isAMap) {
  425. location.value = [e.lnglat.lng, e.lnglat.lat];
  426. } else {
  427. location.value = e.coordinate;
  428. }
  429. if (!!tempMenu.value && tempMenu.value.name === '附近视频') {
  430. showNearbyVideos.value = true;
  431. } else if (!!tempMenu.value && tempMenu.value.name === '格点雨量') {
  432. showRainfall.value = true;
  433. } else if (!!tempMenu.value && tempMenu.value.name === '定点分析') {
  434. const item = deepClone(tempMenu.value);
  435. const nowLocation = deepClone(location.value);
  436. tempMenu.value = {
  437. name: '',
  438. checked: false
  439. };
  440. if (mapStore.isAMap) {
  441. map.off('click', handleClickMap);
  442. } else {
  443. map.un('click', handleClickMap);
  444. }
  445. mapStore.setIsMapSelect(false);
  446. rightMenuRef.value.updateMenu(item.checked ? '1' : '2', item, nowLocation);
  447. }
  448. };
  449. let showWarehouse = ref(false);
  450. let warehouseData = ref('');
  451. const handleShowWarehouse = (data) => {
  452. warehouseData.value = data;
  453. showWarehouse.value = true;
  454. };
  455. // 救援队伍人员列表
  456. let showPeople = ref(false);
  457. let teamId = ref('');
  458. const handleShowPeople = (data) => {
  459. teamId.value = data.id;
  460. showPeople.value = true;
  461. };
  462. watch(
  463. () => mapStore.trackState.show,
  464. (show) => {
  465. if (!!show) {
  466. const dom = mapStore.isAMap ? mapRef.value : map2Ref.value;
  467. dom?.addMarker(adjustPoint(mapStore.trackState.data));
  468. mapStore.trackState.data = [];
  469. mapStore.trackState.show = false;
  470. }
  471. }
  472. );
  473. const handleShowTrack = (data) => {
  474. getVehicleTrajectory(data.id).then((res) => {
  475. const trajectory = [];
  476. if (res.data && res.data.list) {
  477. res.data.list.forEach((item) => {
  478. trajectory.push({
  479. time: !!item.gpsDate ? parseTime(item.gpsDate, '{h}:{i}') : '',
  480. lnglat: [item.lng, item.lat]
  481. });
  482. });
  483. initDataToPlay({ id: data.id, type: 'track', data: trajectory, name: data.title }, true);
  484. }
  485. });
  486. };
  487. // 传递数据给时间轴
  488. const initDataToPlay = (data, isDetail?: boolean) => {
  489. if (!!timeAxisRef.value) {
  490. timeAxisRef.value.initDataToPlay(data, isDetail);
  491. }
  492. };
  493. // 点位详情弹窗关闭后
  494. const handleCloseDetailDialog = (data) => {
  495. timeAxisRef.value.clearData(data.title, true);
  496. };
  497. const mapMoveEnd = () => {
  498. if (!mapStore.pointParams.dict_value && !mapStore.pointParams.option) return;
  499. addMarkersMethod();
  500. };
  501. watch(
  502. () => mapStore.mapLoaded,
  503. (loaded) => {
  504. if (loaded) {
  505. map = getMap();
  506. mapUtils = getMapUtils();
  507. if (!!map && Object.keys(map).length !== 0) {
  508. map.on('moveend', mapMoveEnd);
  509. }
  510. if (eventId.value) {
  511. getEventDetail({ event_id: eventId.value }).then((res) => {
  512. const lnglat = gcoord.transform([res.data.longitude, res.data.latitude], gcoord.GCJ02, gcoord.WGS84);
  513. const newMap = mapStore.isAMap ? map : map.getView();
  514. newMap.setCenter(lnglat);
  515. mapUtils.setAddress({
  516. longitude: lnglat[0],
  517. latitude: lnglat[1],
  518. image: getImageUrl('address.png'),
  519. imageHover: getImageUrl('address_hover.png'),
  520. size: [45, 48],
  521. name: '灾害地点'
  522. });
  523. });
  524. }
  525. }
  526. },
  527. {
  528. immediate: true
  529. }
  530. );
  531. watch(
  532. () => mapStore.updateAddress,
  533. (lnglat) => {
  534. if (lnglat && lnglat.length == 2) {
  535. const newMap = mapStore.isAMap ? map : map.getView();
  536. newMap.setCenter(lnglat);
  537. mapUtils.setAddress({
  538. longitude: lnglat[0],
  539. latitude: lnglat[1],
  540. image: getImageUrl('address.png'),
  541. imageHover: getImageUrl('address_hover.png'),
  542. size: [45, 48],
  543. name: '灾害地点'
  544. });
  545. }
  546. }
  547. );
  548. // 监听视频打点
  549. watch(
  550. () => mapStore.pointParams,
  551. () => {
  552. if (mapStore.updateMenu && !!mapStore.updateMenu.name) {
  553. // 视频修改的值,需要显示左侧辅助分析、显示右侧菜单
  554. leftMenuRef.value.setMenuIndex(2);
  555. // rightMenuRef.value.updateMenu('1', mapStore.updateMenu);
  556. mapStore.setUpdateMenu({});
  557. }
  558. addMarkersMethod();
  559. },
  560. {
  561. deep: true
  562. }
  563. );
  564. // 监听层级变化
  565. watch(
  566. () => mapStore.mapState.zoom,
  567. () => {
  568. mapMoveEnd();
  569. },
  570. {
  571. deep: true
  572. }
  573. );
  574. onMounted(() => {
  575. mapStore.initData();
  576. eventId.value = route.query.event_id;
  577. });
  578. onBeforeUnmount(() => {
  579. if (!!map && Object.keys(map).length !== 0) {
  580. if (mapStore.isAMap) {
  581. map.off('click', handleClickMap);
  582. map.off('moveend', handleClickMap);
  583. } else {
  584. map.un('click', handleClickMap);
  585. map.un('moveend', handleClickMap);
  586. }
  587. mapStore.setIsMapSelect(false);
  588. }
  589. if (!!addMarkersTimer) {
  590. clearInterval(addMarkersTimer);
  591. addMarkersTimer = null;
  592. }
  593. });
  594. provide('getMapUtils', getMapUtils);
  595. provide('getMap', getMap);
  596. provide('trackPlayback', trackPlayback);
  597. provide('showDetail', showDetail);
  598. provide('getDrawTool', getDrawTool);
  599. provide('initDataToPlay', initDataToPlay);
  600. provide('handleShowVideo2', handleShowVideo2);
  601. </script>
  602. <style lang="scss" scoped>
  603. #globalMap {
  604. width: 100%;
  605. height: 100%;
  606. }
  607. .global-map {
  608. width: 100%;
  609. height: 100%;
  610. position: relative;
  611. //overflow: hidden;
  612. .tool-box {
  613. position: absolute;
  614. right: 85px;
  615. bottom: 90px;
  616. z-index: 10;
  617. color: #fff;
  618. }
  619. }
  620. .box {
  621. position: absolute;
  622. top: 20px;
  623. right: 20px;
  624. width: 300px;
  625. background-color: #041d55;
  626. display: flex;
  627. flex-direction: column;
  628. padding: 20px;
  629. color: #fff;
  630. font-size: 16px;
  631. height: 500px;
  632. max-height: 90%;
  633. div {
  634. line-height: 30px;
  635. cursor: pointer;
  636. }
  637. }
  638. .fixed {
  639. position: fixed !important;
  640. }
  641. </style>