components_timeline_cloud copy.html 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. <!--********************************************************************
  2. * Copyright© 2000 - 2020 SuperMap Software Co.Ltd. All rights reserved.
  3. *********************************************************************-->
  4. <!DOCTYPE html>
  5. <html>
  6. <head>
  7. <meta charset="UTF-8" />
  8. <title data-i18n="resources.title_componentsTimeLineCloud_Vue"></title>
  9. <script type="text/javascript" include="vue,jquery" src="../js/include-web.js"></script>
  10. <script
  11. include="echarts-vue,iclient-mapboxgl-vue,mapbox-gl-enhance"
  12. src="../../dist/mapboxgl/include-mapboxgl.js"
  13. ></script>
  14. <style>
  15. #main {
  16. margin: 0 auto;
  17. width: 100%;
  18. height: 100%;
  19. }
  20. .sm-component-time-line {
  21. position: absolute;
  22. bottom: 20px;
  23. width: 100%;
  24. height: 80px;
  25. z-index: 1000;
  26. }
  27. .sm-cloud-info {
  28. position: absolute;
  29. right: 10px;
  30. top: 20px;
  31. width: 290px;
  32. height: 310px;
  33. z-index: 1000;
  34. }
  35. .sm-header {
  36. display: inline-flex;
  37. align-items: center;
  38. height: 25px;
  39. }
  40. .sm-header-style {
  41. width: 6px;
  42. height: 16px;
  43. background: #fff;
  44. }
  45. .sm-current-info {
  46. display: inline-flex;
  47. align-items: center;
  48. }
  49. .sm-other-info {
  50. width: 180px;
  51. }
  52. .sm-temperature {
  53. display: inline-flex;
  54. align-items: center;
  55. width: 120px;
  56. }
  57. .sm-other-info div {
  58. display: inline-flex;
  59. justify-content: center;
  60. align-items: center;
  61. }
  62. .sm-other-info .sm-component-text {
  63. justify-content: flex-start;
  64. }
  65. .sm-today-weather {
  66. display: inline-flex;
  67. justify-content: center;
  68. align-items: center;
  69. width: 100%;
  70. }
  71. .sm-day-info {
  72. width: 130;
  73. height: 110px;
  74. }
  75. .sm-day-info > div {
  76. display: flex;
  77. justify-content: center;
  78. }
  79. .sm-day-info .sm-component-image {
  80. display: block;
  81. margin: 0 auto;
  82. }
  83. .sm-today-rain {
  84. position: absolute;
  85. bottom: -10px;
  86. display: flex;
  87. justify-content: center;
  88. width: 100%;
  89. }
  90. </style>
  91. </head>
  92. <body style=" margin: 0;overflow: hidden;background: #fff;width: 100%;height:100%;position: absolute;top: 0;">
  93. <div id="main">
  94. <sm-web-map
  95. server-url="https://www.supermapol.com"
  96. :map-id="235407763"
  97. :tianditu-key="tiandituKey"
  98. :loading="loading"
  99. @load="load"
  100. ></sm-web-map>
  101. <sm-time-line
  102. ref="timeLine"
  103. :data="data"
  104. :play-interval="1000"
  105. :next-enable="nextEnable"
  106. :label="label"
  107. @timelinechanged="timelineChanged"
  108. @timelineplaychanged="timelineplaychanged"
  109. ></sm-time-line>
  110. <sm-border type="border6" class="sm-cloud-info">
  111. <div class="sm-cloud-info__content">
  112. <div class="sm-header">
  113. <div class="sm-header-style"></div>
  114. <sm-text title="当前实况" :font-style="{fontSize: '18px', fontWeight: 600}"></sm-text>
  115. </div>
  116. <div class="sm-current-info">
  117. <div class="sm-temperature">
  118. <sm-image src="./img/cloud/icon_wendu.png" style="width:36px;height:41px"></sm-image>
  119. <sm-text title="27.2℃"></sm-text>
  120. </div>
  121. <div class="sm-other-info">
  122. <div>
  123. <sm-image src="./img/cloud/icon_rain.png" style="width:12px;height:12px"></sm-image>
  124. <sm-text title="降水:1mm"></sm-text>
  125. </div>
  126. <div>
  127. <sm-image src="./img/cloud/icon_sidu.png" style="width:12px;height:12px"></sm-image>
  128. <sm-text title="相对湿度:81%"></sm-text>
  129. </div>
  130. <div>
  131. <sm-image src="./img/cloud/icon_wind.png" style="width:12px;height:12px"></sm-image>
  132. <sm-text title="风向风速:东偏北一级"></sm-text>
  133. </div>
  134. </div>
  135. </div>
  136. <div class="sm-header">
  137. <div class="sm-header-style"></div>
  138. <sm-text title="今日天气" :font-style="{fontSize: '18px', fontWeight: 600}"></sm-text>
  139. </div>
  140. <div class="sm-today-weather">
  141. <div class="sm-day-info">
  142. <sm-text title="今日白天" :font-style="{textAlign: 'center'}"></sm-text>
  143. <sm-image src="./img/cloud/cloud.png" style="width:45px;height:45px"></sm-image>
  144. <sm-text title="小雨" :font-style="{textAlign: 'center'}"></sm-text>
  145. <div><sm-text title="32.5℃ 南偏西1级"></sm-text></div>
  146. </div>
  147. <div class="sm-day-info">
  148. <sm-text title="今日夜间" :font-style="{textAlign: 'center'}"></sm-text>
  149. <sm-image src="./img/cloud/cloud.png" style="width:45px;height:45px"></sm-image>
  150. <sm-text title="小雨" :font-style="{textAlign: 'center'}"></sm-text>
  151. <div><sm-text title="24.2℃ 西偏北1级"></sm-text></div>
  152. </div>
  153. </div>
  154. <div class="sm-today-rain">
  155. <sm-text title="24小时降水:3.8mm"></sm-text>
  156. </div>
  157. </div>
  158. </sm-border>
  159. </div>
  160. <script>
  161. var label = [
  162. '7月20日22点',
  163. '7月20日23点',
  164. '7月21日0点',
  165. '7月21日1点',
  166. '7月21日2点',
  167. '7月21日3点',
  168. '7月21日4点',
  169. '7月21日5点',
  170. '7月21日6点',
  171. '7月21日6点'
  172. ];
  173. new Vue({
  174. el: '#main',
  175. data() {
  176. return {
  177. mapStatus: [],
  178. mapQueue: [],
  179. loading: false,
  180. readyNext: true,
  181. nextEnable: false,
  182. tiandituKey: 'f16b023603de8ae8fdd09a2c0feb1ec2',
  183. tooltip: {
  184. formatter: function(params) {
  185. console.log('params', params);
  186. return params.name;
  187. }
  188. },
  189. data: [
  190. { name: '7月20日22点', value: 'de4dac90d63311ea8d11cb07464492f0' },
  191. { name: '7月20日23点', value: 'deb37340d63311ea8d11cb07464492f0' },
  192. { name: '7月21日0点', value: 'df03b620d63311ea8d11cb07464492f0' },
  193. { name: '7月21日1点', value: 'df20b400d63311ea8d11cb07464492f0' },
  194. { name: '7月21日2点', value: 'df55cdc0d63311ea8d11cb07464492f0' },
  195. { name: '7月21日3点', value: 'df9b1420d63311ea8d11cb07464492f0' },
  196. { name: '7月21日4点', value: 'dfdf2200d63311ea8d11cb07464492f0' },
  197. { name: '7月21日5点', value: '03df7100d63411ea8d11cb07464492f0' },
  198. { name: '7月21日6点', value: '64310670d7ad11eab208537bd0e9be18' },
  199. { name: '7月21日6点', value: '7de12b80daa111eab51dd76b96acbea5' }
  200. ],
  201. mapDatas: {
  202. de4dac90d63311ea8d11cb07464492f0: {
  203. title: '气象云202007202200',
  204. id: 235407763,
  205. url: 'https://www.supermapol.com',
  206. withCredentials: false
  207. },
  208. deb37340d63311ea8d11cb07464492f0: {
  209. title: '气象云202007202300',
  210. id: 1219321091,
  211. url: 'https://www.supermapol.com',
  212. withCredentials: false
  213. },
  214. df03b620d63311ea8d11cb07464492f0: {
  215. title: '气象云202007210000',
  216. id: 1047628748,
  217. url: 'https://www.supermapol.com',
  218. withCredentials: false
  219. },
  220. df20b400d63311ea8d11cb07464492f0: {
  221. title: '气象云202007210100',
  222. id: 262101819,
  223. url: 'https://www.supermapol.com',
  224. withCredentials: false
  225. },
  226. df55cdc0d63311ea8d11cb07464492f0: {
  227. title: '气象云202007210200',
  228. id: 1512879278,
  229. url: 'https://www.supermapol.com',
  230. withCredentials: false
  231. },
  232. df9b1420d63311ea8d11cb07464492f0: {
  233. title: '气象云202007210300',
  234. id: 1373748413,
  235. url: 'https://www.supermapol.com',
  236. withCredentials: false
  237. },
  238. dfdf2200d63311ea8d11cb07464492f0: {
  239. title: '气象云202007210400',
  240. id: 240104698,
  241. url: 'https://www.supermapol.com',
  242. withCredentials: false
  243. },
  244. '03df7100d63411ea8d11cb07464492f0': {
  245. title: '气象云202007210500',
  246. id: 1824853281,
  247. url: 'https://www.supermapol.com',
  248. withCredentials: false
  249. },
  250. '64310670d7ad11eab208537bd0e9be18': {
  251. title: '气象云202007210600',
  252. id: 1209527958,
  253. url: 'https://www.supermapol.com',
  254. withCredentials: false
  255. },
  256. '7de12b80daa111eab51dd76b96acbea5': {
  257. title: '气象云202007210700',
  258. id: 106007908,
  259. url: 'https://www.supermapol.com',
  260. withCredentials: false
  261. }
  262. },
  263. label: {
  264. formatter: function(val, index) {
  265. return label[index];
  266. }
  267. }
  268. };
  269. },
  270. computed: {
  271. allLoaded() {
  272. if (this.mapStatus.length) {
  273. return this.mapStatus.every(item => {
  274. return item.status;
  275. });
  276. }
  277. return false;
  278. }
  279. },
  280. watch: {
  281. mapStatus: {
  282. handler() {
  283. console.log('mapStatus');
  284. this.nextEnable = Boolean(
  285. this.mapStatus.find((item, index) => this.currentIndex === index && item.status)
  286. );
  287. console.log('nextEnable', this.nextEnable);
  288. }
  289. },
  290. allLoaded() {
  291. this.playState && this.setPlayState(true);
  292. this.nextEnable = null;
  293. }
  294. },
  295. created() {
  296. SuperMap.Components.setTheme({ textColor: '#fff', background: 'rgb(0,0,0,0)' });
  297. this.$on('addlayerssucceeded', this.updateNextRasterSource);
  298. this.$on('loadingChange', this.loadingChange);
  299. },
  300. methods: {
  301. load(e) {
  302. this.map = e.map;
  303. var sourceCaches = 'T202007202300' || e.map.style.sourceCaches;
  304. window.map = e.map;
  305. this.resetMapLoadStatus();
  306. // TODO,拿当前地图的sourceId
  307. },
  308. loadingChange(status) {
  309. this.loading = status;
  310. },
  311. timelineplaychanged(val) {
  312. this.playState = val.playState;
  313. },
  314. timelineChanged(val) {
  315. console.log('timelineChanged');
  316. var currentIndex = (val && val.currentIndex) || 0;
  317. var dataId = this.data[currentIndex].value;
  318. var mapInfo = this.mapDatas[dataId];
  319. var url = mapInfo.url + '/web/maps/' + mapInfo.id + '/map.json';
  320. this.currentIndex = currentIndex;
  321. this.requestMapInfo(url, mapInfo, this.updateRasterSource);
  322. },
  323. requestMapInfo(url, mapInfo, cb) {
  324. var rasterTiles = [];
  325. var sourceId = 'T202007202200';
  326. var _this = this;
  327. $.get(url, function(data) {
  328. var layers = data.layers;
  329. for (var i = 0; i < layers.length; i++) {
  330. if (layers[i].layerType === 'TILE' && layers[i].visible) {
  331. rasterTiles.push(layers[i].url);
  332. }
  333. }
  334. if (!_this.readyNext) {
  335. _this.mapQueue.push({ ...mapInfo, sourceId, rasterTiles });
  336. return;
  337. }
  338. _this.readyNext = false;
  339. cb(sourceId, rasterTiles);
  340. });
  341. },
  342. updateRasterSource(sourceId, rasterTiles) {
  343. var options = { proxy: '', tiles: rasterTiles };
  344. if (!sourceId) {
  345. return;
  346. }
  347. var source = this.map.getSource(sourceId);
  348. for (var key in options) {
  349. source[key] = options[key];
  350. }
  351. this.map.style.sourceCaches[sourceId].clearTiles();
  352. this.map.style.sourceCaches[sourceId].update(this.map.transform);
  353. this.map.triggerRepaint();
  354. this.$emit('addlayerssucceeded');
  355. },
  356. updateNextRasterSource() {
  357. console.log('b');
  358. this.readyNext = true;
  359. if (this.mapQueue.length) {
  360. let { id: mapId, sourceId, rasterTiles } = this.mapQueue.shift();
  361. this.updateRasterSource(sourceId, rasterTiles);
  362. } else {
  363. var key = this.data[this.currentIndex].value;
  364. var beforeIds = Object.keys(this.map.style.sourceCaches);
  365. }
  366. // this.playNextStep();
  367. !this.allLoaded && this.isAllSourceLoaded(key, beforeIds);
  368. },
  369. playNextStep() {
  370. console.log('a');
  371. if (this.allLoaded) {
  372. this.playState && this.setPlayState(true);
  373. this.nextEnable = null;
  374. return;
  375. }
  376. const result = this.mapStatus.find((item, index) => this.currentIndex === index && item.status);
  377. console.log(this.allLoaded, result, Boolean(result));
  378. this.nextEnable = Boolean(
  379. this.mapStatus.find((item, index) => this.currentIndex === index && item.status)
  380. );
  381. },
  382. setPlayState(status) {
  383. this.$refs.timeLine.setPlayState(status);
  384. },
  385. isAllSourceLoaded(key, sourceIds) {
  386. if (this.timer) {
  387. clearInterval(this.timer);
  388. this.timer = null;
  389. }
  390. this.timer = setInterval(() => {
  391. this.$emit('loadingChange', true);
  392. var loaded = sourceIds.every(id => {
  393. if (this.map && this.map.style) {
  394. if (!this.map.getSource(id)) {
  395. return true;
  396. }
  397. return this.map.isSourceLoaded(id);
  398. }
  399. return true;
  400. });
  401. console.log('loaded', loaded);
  402. if (loaded && this.mapStatus) {
  403. clearInterval(this.timer);
  404. this.timer = null;
  405. var mapStatus = this.mapStatus.concat();
  406. mapStatus.forEach(info => {
  407. if (info.key === key) {
  408. info.status = true;
  409. }
  410. });
  411. this.mapStatus = mapStatus;
  412. this.$emit('loadingChange', false);
  413. }
  414. }, 100);
  415. },
  416. resetMapLoadStatus() {
  417. let mapStatus;
  418. if (this.mapStatus && this.mapStatus.length) {
  419. mapStatus = this.mapStatus.map(info => {
  420. info.status = false;
  421. return info;
  422. });
  423. } else {
  424. let mapInfoList = Object.keys(this.mapDatas);
  425. if (mapInfoList.length) {
  426. mapStatus = [];
  427. mapInfoList.forEach(key => {
  428. mapStatus.push({ key, status: false });
  429. });
  430. }
  431. }
  432. this.mapStatus = mapStatus;
  433. }
  434. }
  435. });
  436. </script>
  437. </body>
  438. </html>