components_timeline_cloud.html 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  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. .sm-component-spin {
  91. background: transparent !important;
  92. }
  93. </style>
  94. </head>
  95. <body style=" margin: 0;overflow: hidden;background: #fff;width: 100%;height:100%;position: absolute;top: 0;">
  96. <div id="main">
  97. <sm-web-map
  98. server-url="https://www.supermapol.com"
  99. :map-id="235407763"
  100. :tianditu-key="tiandituKey"
  101. :map-options="mapOptions"
  102. :loading="loading"
  103. @load="load"
  104. ></sm-web-map>
  105. <sm-time-line
  106. ref="timeLine"
  107. :data="data"
  108. :play-interval="800"
  109. :next-enable="nextEnable"
  110. :label="label"
  111. @timelinechanged="timelineChanged"
  112. @timelineplaychanged="timelineplaychanged"
  113. ></sm-time-line>
  114. <sm-border type="border6" class="sm-cloud-info">
  115. <div class="sm-cloud-info__content">
  116. <div class="sm-header">
  117. <div class="sm-header-style"></div>
  118. <sm-text title="当前实况" :font-style="{fontSize: '18px', fontWeight: 600}"></sm-text>
  119. </div>
  120. <div class="sm-current-info">
  121. <div class="sm-temperature">
  122. <sm-image src="./img/cloud/icon_wendu.png" style="width:36px;height:41px"></sm-image>
  123. <sm-text title="27.2℃"></sm-text>
  124. </div>
  125. <div class="sm-other-info">
  126. <div>
  127. <sm-image src="./img/cloud/icon_rain.png" style="width:12px;height:12px"></sm-image>
  128. <sm-text title="降水:1mm"></sm-text>
  129. </div>
  130. <div>
  131. <sm-image src="./img/cloud/icon_sidu.png" style="width:12px;height:12px"></sm-image>
  132. <sm-text title="相对湿度:81%"></sm-text>
  133. </div>
  134. <div>
  135. <sm-image src="./img/cloud/icon_wind.png" style="width:12px;height:12px"></sm-image>
  136. <sm-text title="风向风速:东偏北一级"></sm-text>
  137. </div>
  138. </div>
  139. </div>
  140. <div class="sm-header">
  141. <div class="sm-header-style"></div>
  142. <sm-text title="今日天气" :font-style="{fontSize: '18px', fontWeight: 600}"></sm-text>
  143. </div>
  144. <div class="sm-today-weather">
  145. <div class="sm-day-info">
  146. <sm-text title="今日白天" :font-style="{textAlign: 'center'}"></sm-text>
  147. <sm-image src="./img/cloud/cloud.png" style="width:45px;height:45px"></sm-image>
  148. <sm-text title="小雨" :font-style="{textAlign: 'center'}"></sm-text>
  149. <div><sm-text title="32.5℃ 南偏西1级"></sm-text></div>
  150. </div>
  151. <div class="sm-day-info">
  152. <sm-text title="今日夜间" :font-style="{textAlign: 'center'}"></sm-text>
  153. <sm-image src="./img/cloud/cloud.png" style="width:45px;height:45px"></sm-image>
  154. <sm-text title="小雨" :font-style="{textAlign: 'center'}"></sm-text>
  155. <div><sm-text title="24.2℃ 西偏北1级"></sm-text></div>
  156. </div>
  157. </div>
  158. <div class="sm-today-rain">
  159. <sm-text title="24小时降水:3.8mm"></sm-text>
  160. </div>
  161. </div>
  162. </sm-border>
  163. </div>
  164. <script>
  165. var label = [
  166. '7月20日22点',
  167. '7月20日23点',
  168. '7月21日0点',
  169. '7月21日1点',
  170. '7月21日2点',
  171. '7月21日3点',
  172. '7月21日4点',
  173. '7月21日5点',
  174. '7月21日6点',
  175. '7月21日7点'
  176. ];
  177. new Vue({
  178. el: '#main',
  179. data() {
  180. return {
  181. mapStatus: [],
  182. mapQueue: [],
  183. loading: false,
  184. readyNext: true,
  185. nextEnable: false,
  186. tiandituKey: 'f16b023603de8ae8fdd09a2c0feb1ec2',
  187. tooltip: {
  188. formatter: function(params) {
  189. return params.name;
  190. }
  191. },
  192. label: {
  193. formatter: function(val, index) {
  194. return label[index];
  195. }
  196. },
  197. url: 'https://www.supermapol.com/proxy/iserver/services/map_qixiangyun_l93wywbb/rest/maps/',
  198. encodeUrl:
  199. '/image.png?viewBounds=%7B"leftBottom"%3A%7B"x"%3A9293238.75%2C"y"%3A3677548.75%7D%2C"rightTop"%3A%7B"x"%3A11189787.25%2C"y"%3A5574097.25%7D%7D&center=%7B"x"%3A10241513.0%2C"y"%3A4625823.0%7D&width=1090&scale=0.000000035714&prjCoordSys=%7B"epsgCode"%3A3857%7D&transparent=true&height=880',
  200. data: [
  201. 'T202007202200',
  202. 'T202007202300',
  203. 'T202007210000',
  204. 'T202007210100',
  205. 'T202007210200',
  206. 'T202007210300',
  207. 'T202007210400',
  208. 'T202007210500',
  209. 'T202007210600',
  210. 'T202007210700'
  211. ],
  212. mapOptions: {
  213. style: { version: 8, sources: {}, layers: [] },
  214. zoom: 4.6
  215. }
  216. };
  217. },
  218. computed: {
  219. allLoaded() {
  220. if (this.mapStatus.length) {
  221. var allLoaded = true;
  222. this.mapStatus.forEach(function(item) {
  223. if (!item.status) {
  224. allLoaded = false;
  225. }
  226. });
  227. return allLoaded;
  228. }
  229. return false;
  230. }
  231. },
  232. watch: {
  233. mapStatus: {
  234. handler() {
  235. var nextEnable = false;
  236. var currentIndex = this.currentIndex;
  237. this.mapStatus.forEach(function(item, index) {
  238. if (currentIndex === index && item.status) {
  239. nextEnable = true;
  240. }
  241. });
  242. this.nextEnable = nextEnable;
  243. }
  244. },
  245. allLoaded() {
  246. this.playState && this.setPlayState(true);
  247. this.nextEnable = null;
  248. }
  249. },
  250. created() {
  251. SuperMap.Components.setTheme({ textColor: '#fff', background: 'rgb(0,0,0,0)' });
  252. this.$on('addlayerssucceeded', this.updateNextRasterSource);
  253. this.$on('loadingChange', this.loadingChange);
  254. },
  255. methods: {
  256. load(e) {
  257. this.map = e.map;
  258. this.resetMapLoadStatus();
  259. },
  260. loadingChange(status) {
  261. this.loading = status;
  262. },
  263. timelineplaychanged(val) {
  264. this.playState = val.playState;
  265. },
  266. timelineChanged(val) {
  267. var currentIndex = (val && val.currentIndex) || 0;
  268. var dataId = this.data[currentIndex];
  269. var imageUrl = this.url + dataId + this.encodeUrl;
  270. this.currentIndex = currentIndex;
  271. var sourceId = this.data[0];
  272. if (!this.readyNext) {
  273. this.mapQueue.push({ key: dataId, sourceId: sourceId, imageUrl: imageUrl });
  274. return;
  275. }
  276. this.readyNext = false;
  277. this.updateRasterSource(sourceId, imageUrl);
  278. },
  279. updateRasterSource(sourceId, imageUrl) {
  280. if (this.map.getLayer(sourceId)) {
  281. this.map.setLayoutProperty(sourceId, 'visibility', 'none');
  282. }
  283. sourceId = sourceId + '_image';
  284. var source = this.map.getSource(sourceId);
  285. if (!source) {
  286. this.map.addSource(sourceId, {
  287. type: 'image',
  288. url: imageUrl,
  289. coordinates: [
  290. [50, 61],
  291. [145.9, 61],
  292. [145.9, 0],
  293. [50, 0]
  294. ]
  295. });
  296. this.map.addLayer({
  297. id: sourceId,
  298. type: 'raster',
  299. source: sourceId,
  300. paint: {
  301. 'raster-fade-duration': 0
  302. }
  303. });
  304. } else {
  305. source.updateImage({ url: imageUrl });
  306. }
  307. this.$emit('addlayerssucceeded');
  308. },
  309. updateNextRasterSource() {
  310. this.readyNext = true;
  311. if (this.mapQueue.length) {
  312. var { id: mapId, sourceId, imageUrl } = this.mapQueue.shift();
  313. this.updateRasterSource(sourceId, imageUrl);
  314. } else {
  315. var key = this.data[this.currentIndex];
  316. var sourceCaches = this.map.style.sourceCaches;
  317. var beforeIds = [];
  318. for (var sourceId in sourceCaches) {
  319. beforeIds.push(sourceId);
  320. }
  321. }
  322. !this.allLoaded && this.isAllSourceLoaded(key, beforeIds);
  323. },
  324. setPlayState(status) {
  325. this.$refs.timeLine.setPlayState(status);
  326. },
  327. isAllSourceLoaded(key, sourceIds) {
  328. if (this.timer) {
  329. clearInterval(this.timer);
  330. this.timer = null;
  331. }
  332. var map = this.map;
  333. var _this = this;
  334. this.timer = setInterval(function() {
  335. _this.$emit('loadingChange', true);
  336. var loaded = true;
  337. sourceIds.forEach(function(id) {
  338. if (_this.map && _this.map.style) {
  339. if (!_this.map.getSource(id)) {
  340. return true;
  341. }
  342. if (!_this.map.isSourceLoaded(id)) {
  343. loaded = false;
  344. }
  345. return _this.map.isSourceLoaded(id);
  346. }
  347. return true;
  348. });
  349. _this.nextEnable = false;
  350. if (loaded && _this.mapStatus) {
  351. clearInterval(_this.timer);
  352. _this.timer = null;
  353. var mapStatus = _this.mapStatus.concat();
  354. mapStatus.forEach(function(info) {
  355. if (info.key === key) {
  356. info.status = true;
  357. }
  358. });
  359. _this.mapStatus = mapStatus;
  360. _this.$emit('loadingChange', false);
  361. }
  362. }, 100);
  363. },
  364. resetMapLoadStatus() {
  365. var mapStatus = [];
  366. if (this.mapStatus && this.mapStatus.length) {
  367. mapStatus = this.mapStatus.map(function(info) {
  368. info.status = false;
  369. return info;
  370. });
  371. } else {
  372. this.data.forEach(function(key) {
  373. mapStatus.push({ key: key, status: false });
  374. });
  375. }
  376. this.mapStatus = mapStatus;
  377. }
  378. }
  379. });
  380. </script>
  381. </body>
  382. </html>