index.vue 19 KB

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