index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655
  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. console.log(detailsData.value.id);
  194. if (!!detailsData.value.id) {
  195. data.forEach((item) => {
  196. if (item.id === detailsData.value.id) {
  197. item.isHover = true;
  198. } else if (showVideoDetail.value && videoDetail.value) {
  199. data.forEach((item) => {
  200. if (item.id === videoDetail.value.id) {
  201. item.isHover = true;
  202. }
  203. });
  204. }
  205. });
  206. // detailsData.value = {
  207. // id: '',
  208. // dataType: ''
  209. // };
  210. }
  211. mapUtils.addMarker2(data);
  212. });
  213. if (addMarkersTimer) {
  214. clearInterval(addMarkersTimer);
  215. addMarkersTimer = null;
  216. }
  217. if (mapStore.pointParams.option.includes('43')) {
  218. addMarkersTimer = setInterval(addMarkersMethod, 60 * 1000);
  219. }
  220. },
  221. 300,
  222. false
  223. );
  224. // 跳转指定地点
  225. const toAddress = (item) => {
  226. const dom = mapStore.activeMap === 'imageMap' ? map2Ref.value : mapRef.value;
  227. dom.setCenter(item);
  228. };
  229. let showDrawTools = ref(false);
  230. // 点击菜单
  231. const clickMenu = (item, dataList) => {
  232. if (item.path === '1') {
  233. // 空间分析
  234. if (item.component === 'spatial') {
  235. showDrawTools.value = !showDrawTools.value;
  236. }
  237. if (item.component && item.component !== 'spatial') {
  238. // 打点信息
  239. addMarkers(item);
  240. }
  241. rightMenuRef.value.updateMenu(item.checked ? '1' : '2', item);
  242. } else if (item.path === '2') {
  243. if (item.name === '附近视频') {
  244. // 附近视频
  245. tempMenu.value = item;
  246. //为地图注册click事件获取鼠标点击出的经纬度坐标
  247. map.on('click', handleClickMap);
  248. mapStore.setIsMapSelect(true);
  249. } else {
  250. let checked = item.checked ? '1' : '2';
  251. if (item.component) {
  252. // 打点信息
  253. addMarkers(item);
  254. }
  255. if (item.isVideo) {
  256. rightMenuRef.value.updateMenu(checked, item);
  257. } else {
  258. let index = findChecked(dataList, item.name);
  259. if (item.checked && index > 0) {
  260. // 已有图层分析直接切换到该index
  261. rightMenuRef.value.showIndexMenu('图层分析');
  262. } else if (item.checked || (!item.checked && index === 0)) {
  263. rightMenuRef.value.updateMenu(checked, { name: '图层分析', meta: { icon: 'icon1' } });
  264. }
  265. }
  266. }
  267. } else if (item.path === '3') {
  268. // 通讯保障
  269. communicationSupport.show = !communicationSupport.show;
  270. communicationSupport.data = item;
  271. } else if (item.path === '4' && ['定点分析', '格点雨量'].includes(item.name)) {
  272. if (item.name === '定点分析' && !item.checked) {
  273. closeClickMap();
  274. rightMenuRef.value.updateMenu('2', item, []);
  275. } else {
  276. // 定点分析、格点雨量
  277. tempMenu.value = item;
  278. //为地图注册click事件获取鼠标点击出的经纬度坐标
  279. map.on('click', handleClickMap);
  280. mapStore.setIsMapSelect(true);
  281. }
  282. }
  283. // 菜单关闭,移除车辆
  284. if (['手机工作台', '重点车辆', '移动指挥车', '机动无人机', '卫星电话'].includes(item.name) && !item.checked) {
  285. timeAxisRef.value.clearData(item.name);
  286. }
  287. if (item.component == '43' && !item.checked && !mapStore.pointParams.option.includes('43') && addMarkersTimer) {
  288. clearInterval(addMarkersTimer);
  289. addMarkersTimer = null;
  290. }
  291. };
  292. const handleHideCommunicationSupport = () => {
  293. communicationSupport.show = false;
  294. leftMenuRef.value.setMenuChange(communicationSupport.data, false);
  295. };
  296. const findChecked = (dataList, name) => {
  297. let index = 0;
  298. dataList.forEach((item) => {
  299. if (
  300. !['易涝隐患点', '省政务无人机', '铁塔运行监测', '通讯保障', '救援队伍', '重点车辆', '附近视频', '河道监测', '水库监测'].includes(item.name) &&
  301. item.name !== name &&
  302. !item.isVideo &&
  303. item.path === '2' &&
  304. !!item.checked
  305. ) {
  306. index++;
  307. }
  308. if (item.children && item.children.length > 0) {
  309. let res = findChecked(item.children, name);
  310. index += res;
  311. }
  312. });
  313. return index;
  314. };
  315. // 点击搜索结果,添加标注
  316. const selectSearchMarker = (item) => {
  317. const dom = mapStore.isAMap ? mapRef.value : map2Ref.value;
  318. let item2 = deepClone(item);
  319. // 获取图标
  320. if (iconList[item2.dataType]) {
  321. item2.icon = iconList[item2.dataType].imageHover;
  322. item2.image = iconList[item2.dataType].image;
  323. item2.imageHover = iconList[item2.dataType].imageHover;
  324. item2.size = iconList[item2.dataType].size;
  325. } else {
  326. item2.icon = iconList['common'].imageHover;
  327. item2.image = iconList['common'].image;
  328. item2.imageHover = iconList['common'].imageHover;
  329. item2.size = iconList['common'].size;
  330. }
  331. item2.lnglat = [item2.longitude, item2.latitude];
  332. dom.addSearchMarker(item2);
  333. };
  334. const handleAnalysisData = (data) => {
  335. rightMenuRef.value.handleMenu('空间分析', data);
  336. };
  337. const getMapUtils = () => {
  338. const domRef = mapStore.isAMap ? mapRef.value : map2Ref.value;
  339. return !!domRef ? domRef.getMapUtils() : {};
  340. };
  341. // 获取地图元素操作
  342. const getMap = () => {
  343. const domRef = mapStore.isAMap ? mapRef.value : map2Ref.value;
  344. return !!domRef ? domRef.getMap() : {};
  345. };
  346. let detailsData = ref({
  347. id: '',
  348. dataType: ''
  349. });
  350. // 显示打点详情
  351. const showDetail = (data, dataType) => {
  352. const domRef = mapStore.isAMap ? mapRef.value : map2Ref.value;
  353. if (!!domRef) {
  354. const newMap = mapStore.isAMap ? map : map.getView();
  355. newMap.setCenter([data.lng, data.lat]);
  356. newMap.setZoom(18);
  357. detailsData.value = {
  358. id: data.id.toString(),
  359. dataType: dataType
  360. };
  361. }
  362. };
  363. const getDrawTool = () => {
  364. return mapStore.isAMap ? mapRef.value.drawTool : mapUtils;
  365. };
  366. const trackPlayback = (data) => {
  367. const domRef = mapStore.isAMap ? mapRef.value : mapUtils;
  368. if (!!domRef) {
  369. domRef.trackPlayback(data);
  370. }
  371. };
  372. let showNearbyVideos = ref(false);
  373. let showRainfall = ref(false);
  374. let location = ref([]);
  375. watch(showNearbyVideos, () => {
  376. if (!!showNearbyVideos.value) {
  377. closeClickMap();
  378. } else {
  379. clearData();
  380. }
  381. });
  382. watch(showRainfall, () => {
  383. if (!!showRainfall.value) {
  384. closeClickMap();
  385. } else {
  386. clearData();
  387. }
  388. });
  389. const clearData = () => {
  390. location.value = [];
  391. if (!!tempMenu.value && !!tempMenu.value.name) {
  392. leftMenuRef.value.setMenuChange(tempMenu.value, false);
  393. tempMenu.value = {
  394. name: '',
  395. checked: false
  396. };
  397. }
  398. };
  399. const closeClickMap = () => {
  400. if (mapStore.isAMap) {
  401. map.off('click', handleClickMap);
  402. } else {
  403. map.un('click', handleClickMap);
  404. }
  405. mapStore.setIsMapSelect(false);
  406. };
  407. // 显示附近视频
  408. const handleShowVideo = (data) => {
  409. location.value = [data.longitude, data.latitude];
  410. showNearbyVideos.value = true;
  411. };
  412. const showVideoDetail = ref(false);
  413. const videoDetail = ref({});
  414. const handleShowVideo2 = (data, flag) => {
  415. const newMap = mapStore.isAMap ? map : map.getView();
  416. if (!flag) {
  417. newMap.setCenter([data.longitude, data.latitude]);
  418. newMap.setZoom(18);
  419. }
  420. videoDetail.value = data;
  421. showVideoDetail.value = true;
  422. };
  423. const handleVideoDetailClose = () => {
  424. videoDetail.value = [];
  425. mapUtils.clearHoverMarker();
  426. };
  427. const handleClickMap = (e) => {
  428. if (mapStore.isAMap) {
  429. location.value = [e.lnglat.lng, e.lnglat.lat];
  430. } else {
  431. location.value = e.coordinate;
  432. }
  433. if (!!tempMenu.value && tempMenu.value.name === '附近视频') {
  434. showNearbyVideos.value = true;
  435. } else if (!!tempMenu.value && tempMenu.value.name === '格点雨量') {
  436. showRainfall.value = true;
  437. } else if (!!tempMenu.value && tempMenu.value.name === '定点分析') {
  438. const item = deepClone(tempMenu.value);
  439. const nowLocation = deepClone(location.value);
  440. tempMenu.value = {
  441. name: '',
  442. checked: false
  443. };
  444. if (mapStore.isAMap) {
  445. map.off('click', handleClickMap);
  446. } else {
  447. map.un('click', handleClickMap);
  448. }
  449. mapStore.setIsMapSelect(false);
  450. rightMenuRef.value.updateMenu(item.checked ? '1' : '2', item, nowLocation);
  451. }
  452. };
  453. let showWarehouse = ref(false);
  454. let warehouseData = ref('');
  455. const handleShowWarehouse = (data) => {
  456. warehouseData.value = data;
  457. showWarehouse.value = true;
  458. };
  459. // 救援队伍人员列表
  460. let showPeople = ref(false);
  461. let teamId = ref('');
  462. const handleShowPeople = (data) => {
  463. teamId.value = data.id;
  464. showPeople.value = true;
  465. };
  466. watch(
  467. () => mapStore.trackState.show,
  468. (show) => {
  469. if (!!show) {
  470. const dom = mapStore.isAMap ? mapRef.value : map2Ref.value;
  471. dom?.addMarker(adjustPoint(mapStore.trackState.data));
  472. mapStore.trackState.data = [];
  473. mapStore.trackState.show = false;
  474. }
  475. }
  476. );
  477. const handleShowTrack = (data) => {
  478. getVehicleTrajectory(data.id).then((res) => {
  479. const trajectory = [];
  480. if (res.data && res.data.list) {
  481. res.data.list.forEach((item) => {
  482. trajectory.push({
  483. time: !!item.gpsDate ? parseTime(item.gpsDate, '{h}:{i}') : '',
  484. lnglat: [item.lng, item.lat]
  485. });
  486. });
  487. initDataToPlay({ id: data.id, type: 'track', data: trajectory, name: data.title }, true);
  488. }
  489. });
  490. };
  491. // 传递数据给时间轴
  492. const initDataToPlay = (data, isDetail?: boolean) => {
  493. if (!!timeAxisRef.value) {
  494. timeAxisRef.value.initDataToPlay(data, isDetail);
  495. }
  496. };
  497. // 点位详情弹窗关闭后
  498. const handleCloseDetailDialog = (data) => {
  499. timeAxisRef.value.clearData(data.title, true);
  500. };
  501. const mapMoveEnd = () => {
  502. if (!mapStore.pointParams.dict_value && !mapStore.pointParams.option) return;
  503. addMarkersMethod();
  504. };
  505. watch(
  506. () => mapStore.mapLoaded,
  507. (loaded) => {
  508. if (loaded) {
  509. map = getMap();
  510. mapUtils = getMapUtils();
  511. if (!!map && Object.keys(map).length !== 0) {
  512. map.on('moveend', mapMoveEnd);
  513. }
  514. if (eventId.value) {
  515. getEventDetail({ event_id: eventId.value }).then((res) => {
  516. const lnglat = gcoord.transform([res.data.longitude, res.data.latitude], gcoord.GCJ02, gcoord.WGS84);
  517. const newMap = mapStore.isAMap ? map : map.getView();
  518. newMap.setCenter(lnglat);
  519. mapUtils.setAddress({
  520. longitude: lnglat[0],
  521. latitude: lnglat[1],
  522. image: getImageUrl('address.png'),
  523. imageHover: getImageUrl('address_hover.png'),
  524. size: [45, 48],
  525. name: '灾害地点'
  526. });
  527. });
  528. }
  529. }
  530. },
  531. {
  532. immediate: true
  533. }
  534. );
  535. watch(
  536. () => mapStore.updateAddress,
  537. (lnglat) => {
  538. if (lnglat && lnglat.length == 2) {
  539. const newMap = mapStore.isAMap ? map : map.getView();
  540. newMap.setCenter(lnglat);
  541. mapUtils.setAddress({
  542. longitude: lnglat[0],
  543. latitude: lnglat[1],
  544. image: getImageUrl('address.png'),
  545. imageHover: getImageUrl('address_hover.png'),
  546. size: [45, 48],
  547. name: '灾害地点'
  548. });
  549. }
  550. }
  551. );
  552. // 监听视频打点
  553. watch(
  554. () => mapStore.pointParams,
  555. () => {
  556. if (mapStore.updateMenu && !!mapStore.updateMenu.name) {
  557. // 视频修改的值,需要显示左侧辅助分析、显示右侧菜单
  558. leftMenuRef.value.setMenuIndex(2);
  559. // rightMenuRef.value.updateMenu('1', mapStore.updateMenu);
  560. mapStore.setUpdateMenu({});
  561. }
  562. addMarkersMethod();
  563. },
  564. {
  565. deep: true
  566. }
  567. );
  568. // 监听层级变化
  569. watch(
  570. () => mapStore.mapState.zoom,
  571. () => {
  572. mapMoveEnd();
  573. },
  574. {
  575. deep: true
  576. }
  577. );
  578. onMounted(() => {
  579. mapStore.initData();
  580. eventId.value = route.query.event_id;
  581. });
  582. onBeforeUnmount(() => {
  583. if (!!map && Object.keys(map).length !== 0) {
  584. if (mapStore.isAMap) {
  585. map.off('click', handleClickMap);
  586. map.off('moveend', handleClickMap);
  587. } else {
  588. map.un('click', handleClickMap);
  589. map.un('moveend', handleClickMap);
  590. }
  591. mapStore.setIsMapSelect(false);
  592. }
  593. if (!!addMarkersTimer) {
  594. clearInterval(addMarkersTimer);
  595. addMarkersTimer = null;
  596. }
  597. });
  598. provide('getMapUtils', getMapUtils);
  599. provide('getMap', getMap);
  600. provide('trackPlayback', trackPlayback);
  601. provide('showDetail', showDetail);
  602. provide('getDrawTool', getDrawTool);
  603. provide('initDataToPlay', initDataToPlay);
  604. provide('handleShowVideo2', handleShowVideo2);
  605. </script>
  606. <style lang="scss" scoped>
  607. #globalMap {
  608. width: 100%;
  609. height: 100%;
  610. }
  611. .global-map {
  612. width: 100%;
  613. height: 100%;
  614. position: relative;
  615. //overflow: hidden;
  616. .tool-box {
  617. position: absolute;
  618. right: 85px;
  619. bottom: 90px;
  620. z-index: 10;
  621. color: #fff;
  622. }
  623. }
  624. .box {
  625. position: absolute;
  626. top: 20px;
  627. right: 20px;
  628. width: 300px;
  629. background-color: #041d55;
  630. display: flex;
  631. flex-direction: column;
  632. padding: 20px;
  633. color: #fff;
  634. font-size: 16px;
  635. height: 500px;
  636. max-height: 90%;
  637. div {
  638. line-height: 30px;
  639. cursor: pointer;
  640. }
  641. }
  642. .fixed {
  643. position: fixed !important;
  644. }
  645. </style>