deckglLayer_nyBuilding.html 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. <!--********************************************************************
  2. * Copyright© 2000 - 2021 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_mb_deckglLayer_nyBuilding"></title>
  9. <style>
  10. body {
  11. font-family: "Avenir Next W00", "Helvetica Neue", Helvetica, Arial, sans-serif;
  12. }
  13. .splitContainer {
  14. height: 200px;
  15. width: 600px;
  16. z-index: 1000;
  17. color: #ffffff;
  18. font-size: 12px;
  19. }
  20. .whiteBackground {
  21. background-color: rgba(225, 225, 225, 0.1);
  22. border-top: 1px dotted;
  23. border-image: linear-gradient(to right, rgba(114, 159, 207, 1), rgba(104, 104, 104, 1) 200px, rgba(104, 104, 104, 0) 75%) 30;
  24. }
  25. .blueBackground {
  26. background: linear-gradient(to right, rgba(114, 159, 207, 0.3) 0%, rgba(255, 255, 255, 0.1) 200px, rgba(00, 00, 00, 0) 75%);
  27. border-bottom: 1px dotted;
  28. border-image: linear-gradient(to right, rgba(104, 104, 104, 1), rgba(104, 104, 104, 1) 200px, rgba(104, 104, 104, 0) 75%) 30;
  29. }
  30. ._flex {
  31. display: flex;
  32. }
  33. ._topRight {
  34. position: absolute;
  35. /*bottom: 0;*/
  36. top: 15px;
  37. right: 50px;
  38. }
  39. .header-div {
  40. display: flex;
  41. height: 70px;
  42. padding: 0 15px 0 12px;
  43. color: #ffffff;
  44. align-items: center;
  45. z-index: 1000;
  46. }
  47. ._playContainer {
  48. padding: 20px 15px 0 12px;
  49. height: auto;
  50. }
  51. .header-label {
  52. flex: 1 1 100%;
  53. order: 1;
  54. font-size: 32px;
  55. align-self: flex-end;
  56. }
  57. #sliderLabels {
  58. flex: 1 1 auto;
  59. order: 1;
  60. display: flex;
  61. justify-content: space-between;
  62. margin-top: 15px;
  63. }
  64. #rangeWrapper {
  65. flex: 1 1 auto;
  66. order: 2;
  67. position: relative;
  68. padding: 0 20px;
  69. }
  70. #sliderValue {
  71. flex: 0 0 100px;
  72. order: 1;
  73. display: flex;
  74. justify-content: center;
  75. flex-direction: column;
  76. text-align: center;
  77. font-size: 300%;
  78. }
  79. #sliderInnerContainer {
  80. flex: 1 1 auto;
  81. order: 2;
  82. display: flex;
  83. flex-direction: column;
  84. justify-content: center;
  85. padding: 0 20px;
  86. }
  87. #slider .ui-slider-range {
  88. background: #729fcf;
  89. }
  90. #slider .ui-slider-handle {
  91. border-color: #729fcf;
  92. }
  93. #slider .ui-slider-handle :hover {
  94. cursor: pointer;
  95. }
  96. #playButton {
  97. flex: 0 0 100px;
  98. flex-flow: row nowrap;
  99. display: flex;
  100. justify-content: center;
  101. background-color: rgba(0, 0, 0, 0.2);
  102. order: 3;
  103. text-align: center;
  104. margin: 20px 0;
  105. }
  106. #playButton:hover {
  107. cursor: pointer;
  108. background-color: rgba(0, 0, 0, 0.4);
  109. }
  110. .toggle-button-icon {
  111. padding: 10px 0 10px 0;
  112. }
  113. .icon-play, .icon-pause {
  114. padding-right: 5px;
  115. }
  116. .legendContainer {
  117. position: absolute;
  118. bottom: 25px;
  119. right: 25px;
  120. width: 180px;
  121. color: white;
  122. padding: 10px;
  123. z-index: 1000;
  124. }
  125. .legendHead {
  126. font-size: 20px;
  127. align-self: flex-end;
  128. flex-direction: column;
  129. }
  130. .legendBody {
  131. padding-top: 10px;
  132. }
  133. .legendDiv {
  134. flex: 0 0 50px;
  135. height: 150px;
  136. width: 50px;
  137. background: linear-gradient(to bottom, rgba(0, 255, 255, 1), rgba(255, 0, 255, 0.6) 50%, rgba(68, 0, 68, 0.3));
  138. }
  139. .legendText {
  140. flex: 0 0 auto;
  141. flex-direction: column;
  142. padding-left: 10px;
  143. font-size: 18px;
  144. }
  145. </style>
  146. </head>
  147. <body style=" margin: 0;overflow: hidden;background: #fff;width: 100%;height:100%;position: absolute;top: 0;">
  148. <div class="splitContainer whiteBackground _topRight">
  149. <div class="header-div blueBackground _flex">
  150. <div class="header-label" data-i18n="resources.title_mb_deckglLayer_nyBuilding"></div>
  151. </div>
  152. <div class="_playContainer _flex">
  153. <div id="sliderValue">1880</div>
  154. <div id="sliderInnerContainer">
  155. <div id="sliderLabels">
  156. <span id="startYear">1880</span>
  157. <span id="endYear">2015</span>
  158. </div>
  159. <div id="rangeWrapper">
  160. <div id="slider"></div>
  161. </div>
  162. </div>
  163. <div id="playButton">
  164. <div class="toggle-button-icon -play _flex">
  165. <img src="../img/icon_play.png" class="icon-play">
  166. <div data-i18n="resources.text_paly"></div>
  167. </div>
  168. <div class="toggle-button-icon -pause _flex" style="display:none">
  169. <img src="../img/icon_pause.png" class="icon-pause">
  170. <div data-i18n="resources.text_pause"></div>
  171. </div>
  172. </div>
  173. </div>
  174. </div>
  175. <div class="legendContainer whiteBackground">
  176. <div class="legendHead _flex">
  177. <div>Polygon color</div>
  178. <div>by years</div>
  179. </div>
  180. <div class="legendBody _flex">
  181. <div class="legendDiv"></div>
  182. <div class="legendText _flex">
  183. <div id="legendStart" style="flex:1 1 auto; align-self: flex-start"></div>
  184. <div id="legendMiddle" style="flex:1 1 auto;align-self: flex-start"></div>
  185. <div id="legendEnd" style="align-self: flex-end"></div>
  186. </div>
  187. </div>
  188. </div>
  189. <div id="map" style="margin:0 auto;width: 100%;height: 100%"></div>
  190. <script type="text/javascript" include="papaparse,bootstrap,widgets,jquery-ui" src="../js/include-web.js"></script>
  191. <script type="text/javascript" include="deck" src="../../dist/mapboxgl/include-mapboxgl.js"></script>
  192. <script type="text/javascript">
  193. var host = window.isLocal ? window.server : "https://iserver.supermap.io", map,
  194. url = host + "/iserver/services/map-china400/rest/maps/ChinaDark",
  195. dataUrl = "https://iserver.supermap.io/iserver/services/data-ny/rest/data",
  196. deckglLayer, popup,
  197. currentYear = 1950,
  198. attribution = "<a href='https://www.mapbox.com/about/maps/' target='_blank'>© Mapbox </a>" +
  199. " with <span>© <a href='https://iclient.supermap.io' target='_blank'>SuperMap iClient</a> | </span>" +
  200. " Map Data <span>© <a href='http://support.supermap.com.cn/product/iServer.aspx' target='_blank'>SuperMap iServer</a></span> ";
  201. map = new mapboxgl.Map({
  202. container: 'map',
  203. style: {
  204. "version": 8,
  205. "sources": {
  206. "raster-tiles": {
  207. "attribution": attribution,
  208. "type": "raster",
  209. "tiles": [url + '/zxyTileImage.png?z={z}&x={x}&y={y}'],
  210. "tileSize": 256,
  211. },
  212. },
  213. "layers": [{
  214. "id": "simple-tiles",
  215. "type": "raster",
  216. "source": "raster-tiles",
  217. "minzoom": 13,
  218. "maxzoom": 22
  219. }]
  220. },
  221. center: [-73.981480, 40.702389],
  222. zoom: 14,
  223. minZoom: 14
  224. });
  225. map.addControl(new mapboxgl.NavigationControl(), 'top-left');
  226. initEvent();
  227. init();
  228. function initEvent() {
  229. $("#sliderValue").html(currentYear);
  230. $("#legendStart").html("in " + currentYear);
  231. $("#legendMiddle").html("in " + (currentYear - 25));
  232. $("#legendEnd").html("before " + (currentYear - 50));
  233. $("#playButton").click(function () {
  234. $(".toggle-button-icon").toggle();
  235. });
  236. $(".-play").click(function () {
  237. start();
  238. });
  239. $(".-pause").click(function () {
  240. pause();
  241. });
  242. $("#slider").slider({
  243. orientation: "horizontal",
  244. range: "min",
  245. min: 1880,
  246. max: 2015,
  247. value: 1950,
  248. // slide: refreshSwatch,
  249. change: refreshSwatch
  250. });
  251. map.on("moveend", eventHandle);
  252. map.on("resize", eventHandle);
  253. }
  254. //是否为新的请求
  255. var isNewRequest = false;
  256. //地图事件
  257. function eventHandle() {
  258. isNewRequest = true;
  259. requestData();
  260. }
  261. //进度条更新事件
  262. function refreshSwatch() {
  263. currentYear = $("#slider").slider("value");
  264. $("#sliderValue").html(currentYear);
  265. $("#sliderValue").html(currentYear);
  266. $("#legendStart").html("in " + currentYear);
  267. $("#legendMiddle").html("in " + (currentYear - 25));
  268. $("#legendEnd").html("before " + (currentYear - 50));
  269. deckglLayer.update();
  270. }
  271. //初始加载
  272. function init() {
  273. currentYear = $("#slider").slider("value");
  274. requestData();
  275. }
  276. //动画控制
  277. function start() {
  278. Animation();
  279. }
  280. //动画控制
  281. function pause() {
  282. clearInterval(animation);
  283. }
  284. var animation;
  285. //动画
  286. function Animation() {
  287. //动画:
  288. window.setTimeout(function () {
  289. animation = window.setInterval(timeCount, 100);
  290. }, 1000);
  291. function timeCount() {
  292. deckglLayer.update();
  293. if (currentYear === 2015) {
  294. currentYear = 1880;
  295. }
  296. currentYear++;
  297. $("#slider").slider("value", currentYear);
  298. }
  299. }
  300. //todo 一个合理的请求方式,初始化和界面范围变化时触发请求,还需要避免两种情况冲突
  301. var responseCounts = 0;
  302. //请求数据
  303. function requestData() {
  304. for (var i = 1; i <= 5; i++) {
  305. query(i)
  306. }
  307. function query(count) {
  308. var boundsParam = new SuperMap.GetFeaturesByBoundsParameters({
  309. datasetNames: ["ny:Building_Footprints"],
  310. attributeFilter: "cnstrct_yr > " + (1880 + 26 * (count - 1)) + " And cnstrct_yr <= " + (1880 + 26 * count),
  311. bounds: map.getBounds(),
  312. toIndex: 1000000,
  313. maxFeatures: 1000000,
  314. });
  315. new mapboxgl.supermap.FeatureService(dataUrl).getFeaturesByBounds(boundsParam, callback);
  316. }
  317. function callback(result) {
  318. if (isNewRequest) {
  319. responseCounts++;
  320. }
  321. if (deckglLayer) {
  322. updateLayer(dataSetAdjust(result));
  323. } else {
  324. deckglLayer = new mapboxgl.supermap.DeckglLayer("polygon-layer", {
  325. data: dataSetAdjust(result),
  326. props: {
  327. stroked: false,
  328. onHover: function (feature) {
  329. if (!popup) {
  330. popup = new mapboxgl.Popup({
  331. anchor: 'bottom',
  332. closeButton: false,
  333. offset: {
  334. 'bottom': [0, -10],
  335. }
  336. });
  337. }
  338. if (!feature.object || !feature.object.properties.isShow) {
  339. popup.remove();
  340. return;
  341. }
  342. //+ "x:" + feature.lngLat[0] + ",y:" + feature.lngLat[1]
  343. popup.setHTML("于 " + feature.object.properties.CNSTRCT_YR + " 年建成");
  344. popup.setLngLat(map.unproject([feature.x, feature.y]));
  345. popup.addTo(map);
  346. }
  347. },
  348. callback: {getFillColor: updateLayerOptions},
  349. });
  350. map.addLayer(deckglLayer);
  351. }
  352. }
  353. }
  354. //调整请求回来得数据格式以支持图层绘制
  355. function dataSetAdjust(result) {
  356. return result.result.features.features.map(function (item) {
  357. if (item.geometry.type !== "Polygon") {
  358. item.geometry.coordinates[0] = item.geometry.coordinates[0][0];
  359. item.geometry.type = 'Polygon';
  360. }
  361. return item;
  362. });
  363. }
  364. //配置颜色的算法
  365. function updateLayerOptions(feature) {
  366. // rgba(0, 255, 255, 1), rgba(255, 0, 255, 0.6) 50%,rgba(68, 0,68, 0.3)
  367. var proportion = 1, r, g, b, a;
  368. if (Number(feature.properties.CNSTRCT_YR) > currentYear) {
  369. feature.properties.isShow = false;
  370. return [0, 0, 0, 0];
  371. }
  372. feature.properties.isShow = true;
  373. if (Number(feature.properties.CNSTRCT_YR) <= (currentYear - 50)) {
  374. return [68, 0, 68, 80];
  375. }
  376. var centerYear = currentYear - 25;
  377. var endYear = currentYear - 50;
  378. if (Number(feature.properties.CNSTRCT_YR) >= centerYear) {
  379. if (currentYear !== endYear) {
  380. proportion = 1 - ((Number(feature.properties.CNSTRCT_YR) - centerYear) / (currentYear - centerYear));
  381. }
  382. r = proportion * 255;
  383. g = 255 - proportion * 255;
  384. b = 255;
  385. a = 127.5 + (1 - proportion) * 127.5;
  386. return [r, g, b, a];
  387. } else {
  388. if (currentYear !== endYear) {
  389. proportion = 1 - ((Number(feature.properties.CNSTRCT_YR) - endYear) / (centerYear - endYear));
  390. }
  391. r = 255 - proportion * (255 - 68);
  392. g = 0;
  393. b = 255 - proportion * (255 - 68);
  394. a = 80 + (1 - proportion) * 127.5;
  395. return [r, g, b, a];
  396. }
  397. }
  398. //更新图层
  399. function updateLayer(features) {
  400. if (isNewRequest && responseCounts === 1) {
  401. deckglLayer.setData(features);
  402. // Animation();
  403. } else {
  404. deckglLayer.addData(features);
  405. }
  406. //当新的请求全部返回完成后,重置请求状态
  407. if (isNewRequest && responseCounts === 5) {
  408. isNewRequest = false;
  409. responseCounts = 0;
  410. }
  411. }
  412. </script>
  413. </body>
  414. </html>