theme_ctl_landuseUnique.html 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. <!--********************************************************************
  2. * Copyright© 2000 - 2021 SuperMap Software Co.Ltd. All rights reserved.
  3. *********************************************************************-->
  4. <!DOCTYPE html>
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  8. <title data-i18n="resources.title_landuseUnique"></title>
  9. <style type="text/css">
  10. body {
  11. margin: 0;
  12. overflow: hidden;
  13. background: #fff;
  14. width: 100%;
  15. height: 100%
  16. }
  17. #map {
  18. position: absolute;
  19. width: 100%;
  20. height: 100%;
  21. }
  22. /*图例 style*/
  23. .legend {
  24. position: absolute;
  25. right: 50px;
  26. top: 300px;
  27. width: 250px;
  28. text-align: center;
  29. border: 2px solid #D6E3F1;
  30. background: #FFF;
  31. z-index: 9999999;
  32. display: none;
  33. }
  34. .legendTitle {
  35. background: #1E90FF;
  36. }
  37. .legendContent {
  38. padding-left: 15px;
  39. padding-right: 15px;
  40. height: 300px;
  41. display: block;
  42. overflow-y: auto;
  43. }
  44. .legendItemHeader {
  45. top: 5px;
  46. width: 100px;
  47. height: 18px;
  48. text-align: center;
  49. }
  50. .legendItemValue {
  51. top: 5px;
  52. width: 120px;
  53. text-align: center;
  54. height: 18px;
  55. }
  56. /*信息框 style*/
  57. #infoPlane {
  58. border: 2px solid #D6E3F1;
  59. position: absolute;
  60. right: 50px;
  61. top: 200px;
  62. width: 250px;
  63. z-index: 9999999;
  64. display: none;
  65. }
  66. .editPane {
  67. position: absolute;
  68. right: 60px;
  69. top: 50px;
  70. text-align: center;
  71. background: #FFF;
  72. z-index: 1000;
  73. }
  74. </style>
  75. </head>
  76. <body>
  77. <div class='panel panel-primary editPane' id='editPane' style="z-index: 99999">
  78. <div class='panel-heading'>
  79. <h5 class='panel-title text-center' data-i18n="resources.title_landuseUnique"></h5>
  80. </div>
  81. <div class='panel-body' id='params'>
  82. <p></p>
  83. <div align='right' class='button-group'>
  84. <input type='button' id='btn1' class='btn btn-primary' data-i18n="[value]resources.btn_addThemeLayer" onclick="addThemeLayer()"/>
  85. <input type='button' id='btn2' class='btn btn-primary' data-i18n="[value]resources.text_input_value_clear" onclick="clearLayer()"/>
  86. </div>
  87. </div>
  88. </div>
  89. <div>
  90. <div id="map"></div>
  91. <div id="mapLegend" class="legend">
  92. <div class="legendTitle">
  93. <span data-i18n="resources.text_legend"></span>
  94. </div>
  95. <div class="legendContent">
  96. <table>
  97. <tr>
  98. <td class="legendItemHeader" data-i18n="resources.text_landType"></td>
  99. <td class="legendItemValue" data-i18n="resources.text_color"></td>
  100. </tr>
  101. <tr>
  102. <td class="legendItemHeader" data-i18n="resources.text_grassland"></td>
  103. <td class="legendItemValue" style="background: #C1FFC1"></td>
  104. </tr>
  105. <tr>
  106. <td class="legendItemHeader" data-i18n="resources.text_city"></td>
  107. <td class="legendItemValue" style="background: #CD7054"></td>
  108. </tr>
  109. <tr>
  110. <td class="legendItemHeader" data-i18n="resources.text_shrub"></td>
  111. <td class="legendItemValue" style="background: #7CCD7C"></td>
  112. </tr>
  113. <tr>
  114. <td class="legendItemHeader" data-i18n="resources.text_dryLand"></td>
  115. <td class="legendItemValue" style="background: #EE9A49"></td>
  116. </tr>
  117. <tr>
  118. <td class="legendItemHeader" data-i18n="resources.text_lakeReservoir"></td>
  119. <td class="legendItemValue" style="background: #8EE5EE"></td>
  120. </tr>
  121. <tr>
  122. <td class="legendItemHeader" data-i18n="resources.text_economicForest"></td>
  123. <td class="legendItemValue" style="background: #548B54"></td>
  124. </tr>
  125. <tr>
  126. <td class="legendItemHeader" data-i18n="resources.text_desert"></td>
  127. <td class="legendItemValue" style="background: #DEB887"></td>
  128. </tr>
  129. <tr>
  130. <td class="legendItemHeader" data-i18n="resources.text_irrigatedLand"></td>
  131. <td class="legendItemValue" style="background: #E0FFFF"></td>
  132. </tr>
  133. <tr>
  134. <td class="legendItemHeader" data-i18n="resources.text_paddyField"></td>
  135. <td class="legendItemValue" style="background: #388E8E"></td>
  136. </tr>
  137. <tr>
  138. <td class="legendItemHeader" data-i18n="resources.text_timberForest"></td>
  139. <td class="legendItemValue" style="background: #556B2F"></td>
  140. </tr>
  141. <tr>
  142. <td class="legendItemHeader" data-i18n="resources.text_swamp"></td>
  143. <td class="legendItemValue" style="background: #2F4F4F"></td>
  144. </tr>
  145. <tr>
  146. <td class="legendItemHeader" data-i18n="resources.text_DefaultStyle"></td>
  147. <td class="legendItemValue" style="background: #ABABAB"></td>
  148. </tr>
  149. </table>
  150. </div>
  151. </div>
  152. <div id="infoPlane">
  153. <div data-i18n="resources.text_attributeTable" style="text-align: center;background: #1E90FF"> </div>
  154. <div id="infoContent" style="overflow-y: auto; padding: 5px; background-color: #FFFFFF">
  155. </div>
  156. </div>
  157. </div>
  158. <script type="text/javascript" include="bootstrap,widgets.alert" src="../js/include-web.js"></script>
  159. <script type="text/javascript" exclude="iclient-classic" src="../../dist/classic/include-classic.js"></script>
  160. <script type="text/javascript">
  161. var host = window.isLocal ? window.server : "https://iserver.supermap.io",
  162. url1 = host + "/iserver/services/map-jingjin/rest/maps/京津地区地图",
  163. url2 = host + "/iserver/services/data-jingjin/rest/data";
  164. var map, layer, themeLayer;
  165. // 检测是否支持 Canvas
  166. if (!document.createElement('canvas').getContext) {
  167. widgets.alert.showAlert(resources.msg_supportCanvas, false);
  168. }
  169. map = new SuperMap.Map("map", {
  170. controls: [
  171. new SuperMap.Control.LayerSwitcher(),
  172. new SuperMap.Control.ScaleLine(),
  173. new SuperMap.Control.Zoom(),
  174. new SuperMap.Control.Navigation({
  175. dragPanOptions: {
  176. enableKinetic: true
  177. }
  178. })]
  179. });
  180. layer = new SuperMap.Layer.TiledDynamicRESTLayer("Jingjin", url1, {
  181. transparent: true,
  182. cacheEnabled: true
  183. }, {maxResolution: "auto"});
  184. layer.events.on({"layerInitialized": addLayer});
  185. // 定义 Unique 单值专题图层
  186. themeLayer = new SuperMap.Layer.Unique("ThemeLayer");
  187. themeLayer.setOpacity(0.8);
  188. // 图层基础样式
  189. themeLayer.style = {
  190. shadowBlur: 3,
  191. shadowColor: "#000000",
  192. shadowOffsetX: 1,
  193. shadowOffsetY: 1,
  194. fillColor: "#FFFFFF"
  195. };
  196. // 开启 hover 高亮效果
  197. themeLayer.isHoverAble = true;
  198. // hover 高亮样式
  199. themeLayer.highlightStyle = {
  200. stroke: true,
  201. strokeWidth: 2,
  202. strokeColor: 'blue',
  203. fillColor: "#00F5FF",
  204. fillOpacity: 0.2
  205. };
  206. // 用于单值专题图的属性字段名称
  207. themeLayer.themeField = "LANDTYPE";
  208. // 风格数组,设定值对应的样式
  209. themeLayer.styleGroups = [
  210. {
  211. value: "草地",
  212. style: {
  213. fillColor: "#C1FFC1"
  214. }
  215. },
  216. {
  217. value: "城市",
  218. style: {
  219. fillColor: "#CD7054"
  220. }
  221. },
  222. {
  223. value: "灌丛",
  224. style: {
  225. fillColor: "#7CCD7C"
  226. }
  227. },
  228. {
  229. value: "旱地",
  230. style: {
  231. fillColor: "#EE9A49"
  232. }
  233. },
  234. {
  235. value: "湖泊水库",
  236. style: {
  237. fillColor: "#8EE5EE"
  238. }
  239. },
  240. {
  241. value: "经济林",
  242. style: {
  243. fillColor: "#548B54"
  244. }
  245. },
  246. {
  247. value: "沙漠",
  248. style: {
  249. fillColor: "#DEB887"
  250. }
  251. },
  252. {
  253. value: "水浇地",
  254. style: {
  255. fillColor: "#E0FFFF"
  256. }
  257. },
  258. {
  259. value: "水田",
  260. style: {
  261. fillColor: "#388E8E"
  262. }
  263. },
  264. {
  265. value: "用材林",
  266. style: {
  267. fillColor: "#556B2F"
  268. }
  269. },
  270. {
  271. value: "沼泽",
  272. style: {
  273. fillColor: "#2F4F4F"
  274. }
  275. },
  276. {
  277. value: "缺省风格",
  278. style: {
  279. fillColor: "#ABABAB"
  280. }
  281. }
  282. ]
  283. //专题图层 mousemove 事件
  284. themeLayer.on("mousemove", evn);
  285. function addLayer() {
  286. map.addLayers([layer, themeLayer]);
  287. map.setCenter(new SuperMap.LonLat(117.2, 40.11), 0);
  288. }
  289. //获取 feature 数据
  290. function addThemeLayer() {
  291. clearLayer();
  292. var getFeatureParam, getFeatureBySQLService, getFeatureBySQLParams;
  293. getFeatureParam = new SuperMap.REST.FilterParameter({
  294. name: "Jingjin",
  295. attributeFilter: "SMID > -1"
  296. });
  297. getFeatureBySQLParams = new SuperMap.REST.GetFeaturesBySQLParameters({
  298. queryParameter: getFeatureParam,
  299. toIndex: 500,
  300. datasetNames: ["Jingjin:Landuse_R"]
  301. });
  302. getFeatureBySQLService = new SuperMap.REST.GetFeaturesBySQLService(url2, {
  303. eventListeners: {"processCompleted": processCompleted, "processFailed": processFailed}
  304. });
  305. getFeatureBySQLService.processAsync(getFeatureBySQLParams);
  306. }
  307. function processCompleted(getFeaturesEventArgs) {
  308. var result = getFeaturesEventArgs.result;
  309. var feas = [];
  310. if (result && result.features) {
  311. var features = result.features;
  312. var IHFeas = []; //岛洞多面
  313. for (var i = 0, len = features.length; i < len; i++) {
  314. var feature = features[i];
  315. var smid = feature.attributes.SMID.toString();
  316. if (smid === "86" || smid === "87" || smid === "89") {
  317. // islandHoleHandlerForFeature 处理岛洞面
  318. IHFeas.push(islandHoleHandlerForFeature(feature));
  319. }
  320. else {
  321. feas.push(feature);
  322. }
  323. }
  324. // 岛洞多面要素必需在其他要素之前添加
  325. feas = IHFeas.concat(feas);
  326. themeLayer.addFeatures(feas);
  327. }
  328. document.getElementById("mapLegend").style.display = "block";
  329. }
  330. function processFailed(e) {
  331. widgets.alert.showAlert(e.error.errorMsg,false);
  332. }
  333. function clearLayer() {
  334. document.getElementById("mapLegend").style.display = "none";
  335. document.getElementById("infoPlane").style.display = "none";
  336. //先清除上次的显示结果
  337. themeLayer.clear();
  338. }
  339. function evn(e) {
  340. if (e.target && e.target.refDataID) {
  341. document.getElementById("infoPlane").style.display = "block";
  342. var fid = e.target.refDataID;
  343. var fea = themeLayer.getFeatureById(fid);
  344. if (fea) {
  345. document.getElementById("infoContent").innerHTML = "";
  346. document.getElementById("infoContent").innerHTML += "ID: " + fea.attributes.SMID + "<br/>";
  347. document.getElementById("infoContent").innerHTML += resources.text_landType+": " + fea.attributes.LANDTYPE + "<br/>";
  348. document.getElementById("infoContent").innerHTML += resources.text_area + parseFloat(fea.attributes.SMAREA).toFixed(5) + "<br/>";
  349. }
  350. }
  351. else {
  352. document.getElementById("infoContent").innerHTML = "";
  353. document.getElementById("infoPlane").style.display = "none";
  354. }
  355. }
  356. </script>
  357. </body>
  358. </html>
  359. <script type="text/javascript">
  360. /*
  361. * Method: islandHoleHandlerForFeature。
  362. * 要素岛洞处理。
  363. *
  364. * 多面中,一个子面包含另一个子面,则被包含子面处理为岛洞。
  365. *
  366. * Parameters:
  367. * multiPolygon - {<SuperMap.Feature.Vector>} 需要进行岛洞处理的要素。
  368. *
  369. * Returns:
  370. * {<SuperMap.Feature.Vector>} 处理后的要素。
  371. */
  372. function islandHoleHandlerForFeature(feature) {
  373. if (feature.geometry instanceof SuperMap.Geometry.MultiPolygon && feature.geometry.components.length > 1) {
  374. var newGeometry = islandHoleHandlerForMultiPolygon(feature.geometry);
  375. feature.geometry = newGeometry;
  376. }
  377. return feature;
  378. /*
  379. * Method: islandHoleHandlerForMultiPolygon
  380. * 处理误判为岛洞的多面。
  381. *
  382. * iClient 在解析 iServer 数据时,默认将面要素处理为 MultiPolygon 类型,但有的面要素带有岛洞,
  383. * 这种情况下应该做特殊处理,本函数可以对一个多面进行岛洞处理,并返回新的多面。
  384. *
  385. * Parameters:
  386. * multiPolygon - {<SuperMap.Geometry.MultiPolygon>} 需要进行岛洞处理的多面。
  387. *
  388. * Returns:
  389. * {<SuperMap.Geometry.MultiPolygon>} 处理后的多面。
  390. */
  391. function islandHoleHandlerForMultiPolygon(multiPolygon) {
  392. if (multiPolygon instanceof SuperMap.Geometry.MultiPolygon && multiPolygon.components.length > 1) {
  393. var mPTmp = multiPolygon.clone();
  394. var componentsPolygons = mPTmp.components;
  395. //洞面关系数组
  396. var polygonHoleGroup = [];
  397. for (var k = 0, len = componentsPolygons.length; k < len; k++) {
  398. var geoPolygon = componentsPolygons[k];
  399. //不处理已经是岛洞的面
  400. if (geoPolygon.components.length = 1) {
  401. var lineRings = geoPolygon.components[0];
  402. //将每个点放到面中进行判断
  403. for (var j = 0, len1 = componentsPolygons.length; j < len1; j++) {
  404. if (componentsPolygons[j].components.length != 1) continue;
  405. if (j != k) {
  406. var polygonGeoComp = componentsPolygons[j].components[0].components;
  407. //假设此面为岛洞
  408. var isAllPoiIn = true;
  409. for (var i = 0, len2 = geoPolygon.components.length; i < len2; i++) {
  410. var point = lineRings.components[i];
  411. if (isPointInPoly(point, polygonGeoComp) == false) {
  412. isAllPoiIn = false;
  413. continue;
  414. }
  415. }
  416. //确定并记录洞面关系
  417. if (isAllPoiIn == true) {
  418. var polygonHole = [j, k];
  419. polygonHoleGroup.push(polygonHole);
  420. }
  421. }
  422. }
  423. }
  424. else {
  425. continue;
  426. }
  427. }
  428. // 根据洞面信息重构多面 Geometry。
  429. var bPsTmp = [];
  430. var hPsTmp = [];
  431. for (var m = 0, len3 = polygonHoleGroup.length; m < len3; m++) {
  432. bPsTmp.push(polygonHoleGroup[m][0]);
  433. hPsTmp.push(polygonHoleGroup[m][1]);
  434. }
  435. //岛洞基础面
  436. var bPs = delRepeatInArray(bPsTmp);
  437. //洞面
  438. var hPs = delRepeatInArray(hPsTmp);
  439. //独立面
  440. var iPs = [];
  441. //查找独立面
  442. for (var isIPs = 0, compLen = componentsPolygons.length; isIPs < compLen; isIPs++) {
  443. var isNoHP = true;
  444. for (var o = 0, len = bPs.length; o < len; o++) {
  445. if (isIPs == bPs[o]) {
  446. isNoHP = false;
  447. break;
  448. }
  449. }
  450. if (isNoHP == true) {
  451. for (var o = 0, len = hPs.length; o < len; o++) {
  452. if (isIPs == hPs[o]) {
  453. isNoHP = false;
  454. break;
  455. }
  456. }
  457. }
  458. if (isNoHP == true) {
  459. iPs.push(isIPs);
  460. }
  461. }
  462. //新洞面信息
  463. var hpInfo = [];
  464. //组织新geometry所需要的信息
  465. for (var o = 0, len4 = bPs.length; o < len4; o++) {
  466. var ph = [];
  467. ph.push(bPs[o]);
  468. for (var m = 0, len3 = polygonHoleGroup.length; m < len3; m++) {
  469. if (bPs[o] == polygonHoleGroup[m][0]) {
  470. ph.push(polygonHoleGroup[m][1]);
  471. }
  472. }
  473. if (ph.length > 1) {
  474. hpInfo.push(ph);
  475. }
  476. }
  477. var newComponents = [];
  478. //岛洞子面处理
  479. for (var m = 0, len3 = hpInfo.length; m < len3; m++) {
  480. var geoP = hpInfo[m];
  481. var newLineRings = [];
  482. for (var n = 0, len6 = geoP.length; n < len6; n++) {
  483. newLineRings.push(componentsPolygons[geoP[n]].components[0]);
  484. }
  485. var newGeoPolygon = new SuperMap.Geometry.Polygon(newLineRings);
  486. newComponents.push(newGeoPolygon)
  487. }
  488. //独立子面处理
  489. for (var s = 0, len7 = iPs.length; s < len7; s++) {
  490. var is = iPs[s];
  491. newComponents.push(componentsPolygons[is])
  492. }
  493. multiPolygon.components = newComponents;
  494. }
  495. return multiPolygon;
  496. }
  497. /*
  498. * Method: delRepeatInArray
  499. * 删除数组中的重复元素。
  500. *
  501. * Parameters:
  502. * arr - {Array} 要进行重复元素删除的数组。
  503. *
  504. * Returns:
  505. * {Array} 无重复元素的数组。
  506. */
  507. function delRepeatInArray(arr) {
  508. var newArray = [];
  509. var provisionalTable = {};
  510. for (var i = 0, a; (a = arr[i]) != null; i++) {
  511. if (!provisionalTable[a]) {
  512. newArray.push(a);
  513. provisionalTable[a] = true;
  514. }
  515. }
  516. return newArray;
  517. }
  518. /*
  519. * Method: PointInPoly
  520. * 判断一个点是否在多边形里面。(射线法)
  521. *
  522. * Parameters:
  523. * pt - {Object} 需要判定的点对象,该对象含有属性x(横坐标),属性y(纵坐标)。
  524. * poly - {Array(Objecy)} 多边形节点数组。例如一个四边形:[{"x":1,"y":1},{"x":3,"y":1},{"x":6,"y":4},{"x":2,"y":10},{"x":1,"y":1}]。
  525. *
  526. * Returns:
  527. * {Boolean} 点是否在多边形内。
  528. */
  529. function isPointInPoly(pt, poly) {
  530. for (var isIn = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
  531. ((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y))
  532. && (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)
  533. && (isIn = !isIn);
  534. return isIn;
  535. }
  536. //辅助函数 -end
  537. }
  538. </script>