MapHolder.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. <template>
  2. <div id="map2DViewer">
  3. <CaseAuditPopup v-show="auditPopupShow" ref="auditRef" />
  4. <LabelCasePopup v-show="labelDetailsPopupShow" ref="labelRef" />
  5. <BasemapChange />
  6. </div>
  7. </template>
  8. <script>
  9. import publicFun from "@/utils/publicFunction.js";
  10. import { get } from "@/utils/request";
  11. import CaseAuditPopup from "@/components/popup/CaseAuditPopup.vue";
  12. import LabelCasePopup from "@/components/popup/LabelCasePopup.vue";
  13. import BasemapChange from "@/components/map/BasemapChange.vue";
  14. export default {
  15. name: "MapHolder",
  16. components: { CaseAuditPopup, LabelCasePopup, BasemapChange },
  17. data() {
  18. return {
  19. // 卷帘对比开关
  20. JLControlShowStatus: false,
  21. town: "祝桥镇,南汇新城镇,川沙新镇,老港镇,惠南镇,航头镇,泥城镇,书院镇,新场镇,大团镇,唐镇,曹路镇,宣桥镇,张江镇,合庆镇,周浦镇,康桥镇,三林镇,高桥镇,高东镇,金桥镇,北蔡镇,万祥镇,高行镇",
  22. auditPopupShow: false,
  23. labelDetailsPopupShow: false,
  24. auditPopupStatus: "normal",
  25. popup: null,
  26. labelPopup: null,
  27. // 疑点审计
  28. currentCid: null,
  29. currentHtml: null,
  30. // 标记疑点
  31. currentLabelCid: null,
  32. currentLabelHtml: null
  33. };
  34. },
  35. mounted() {
  36. // 监听全局事件总线中的卷帘对比事件(JLControl)
  37. this.$bus.$on("JLControl", () => {
  38. this.JLControl();
  39. });
  40. this.$bus.$on("caseAuditEvent", () => {
  41. this.caseAuditEvent();
  42. });
  43. //地图初始化
  44. this.mapInit();
  45. this.$store.state.mapMethodsCollection.set("RENDER", {
  46. addPolygonLayer: this.addPolygonLayer,
  47. setView: this.setView,
  48. deletePolygonLayer: this.deletePolygonLayer
  49. });
  50. },
  51. beforeDestroyed() {
  52. // 当容器销毁时,需要停止监听该事件
  53. this.$bus.$off("JLControl");
  54. // 疑点审计
  55. this.$bus.$off("caseAuditEvent");
  56. },
  57. computed: {
  58. // 监听底部菜单栏的状态
  59. getLabelCaseBtnStatus() {
  60. //疑点审计 1,0
  61. let _index = this.$store.state.bottomMenuIndexs.index;
  62. let _subIndex = this.$store.state.bottomMenuIndexs.subIndex;
  63. return { index: _index, subIndex: _subIndex };
  64. },
  65. // 监听当前菜单
  66. getCurrentMenu() {
  67. return this.$store.state.navSelect;
  68. }
  69. },
  70. watch: {
  71. getLabelCaseBtnStatus(val) {
  72. console.log(val, "标记疑点");
  73. if (val.index === 1 && val.subIndex === 1) {
  74. console.log("激活标记疑点弹窗");
  75. this.initDraw();
  76. } else {
  77. console.log("移除疑点标记事件");
  78. this.stopLabelCase();
  79. }
  80. },
  81. "$store.state.navSelect": {
  82. handler(val) {
  83. console.log(val, "currentMenu -- test");
  84. if (val.index !== "3") {
  85. if (this.JLControlShowStatus) {
  86. this.JLControl();
  87. }
  88. this.stopLabelCase();
  89. this.$store.state.bottomMenuIndexs.index = -1;
  90. this.$store.state.bottomMenuIndexs.subIndex = -1;
  91. }
  92. // 切换页面时判断是否需要显示区域图
  93. this.$nextTick(() => {
  94. this.getJSonData();
  95. });
  96. },
  97. immediate: true
  98. }
  99. },
  100. methods: {
  101. // 开始标记疑点事件
  102. startLabelCase() {
  103. map2DViewer.setDrawTool({ action: "start" });
  104. },
  105. // 停止标记疑点事件
  106. stopLabelCase() {
  107. try {
  108. map2DViewer.setDrawTool({
  109. action: "remove"
  110. });
  111. } catch (e) {
  112. console.log("MapHolder.vue 停止标记疑点事件 error");
  113. }
  114. },
  115. // 常规图层弹窗
  116. createAuditDiv(str) {
  117. // 相关属性数据
  118. // 表格里的数据
  119. let popuppef = this.$refs.auditRef;
  120. let tableArr = popuppef.tableArr;
  121. // console.log(tableArr, "shuju");
  122. // 根据ref获取组件的dom元素
  123. this.currentHtml = this.$refs.auditRef.$el.innerHTML;
  124. console.log($(`#${str}_id`), "8888");
  125. if (this.currentHtml) {
  126. let div = document.createElement("div");
  127. div.id = str + "_id";
  128. div.className = "case-audit";
  129. // 动态创建div后赋值模板样式
  130. div.innerHTML = this.currentHtml;
  131. $(() => {
  132. // 法律法规点击事件
  133. if ($(`#${str}_id a`)) {
  134. $(`#${str}_id a`).click(e => {
  135. console.log(e, "显示疑点相关的弹窗");
  136. this.$store.state.lawPopupShow = true;
  137. });
  138. }
  139. // input添加点击事件
  140. if ($(`#${str}_id input`)[1]) {
  141. $(`#${str}_id input`).click(e => {
  142. switch (e.target.defaultValue) {
  143. case "修改":
  144. this.modifyBtnEvent();
  145. break;
  146. case "确认":
  147. this.confirmBtnEvent();
  148. break;
  149. }
  150. });
  151. }
  152. });
  153. return div;
  154. }
  155. },
  156. /**
  157. * 标记疑点完成时保存描述信息的弹窗
  158. * @str -- id
  159. * @coord -- 坐标信息
  160. * @data -- 其余数据
  161. */
  162. createLabelDiv(str, coord, data) {
  163. console.log(str, "label - str");
  164. this.currentLabelHtml = this.$refs.labelRef.$el.innerHTML;
  165. if (this.currentLabelHtml) {
  166. let div = document.createElement("div");
  167. div.id = `${str}_id`;
  168. div.className = "label-case";
  169. // 动态创建div后赋值模板样式
  170. div.innerHTML = this.currentLabelHtml;
  171. $(() => {
  172. console.log($(`#${str}_id textarea`).val(), "textarea");
  173. $(`#${str}_id`).css("height", "100%");
  174. $(`#${str}_id input`).click(e => {
  175. console.log(e.target.defaultValue);
  176. switch (e.target.defaultValue) {
  177. case "删除":
  178. this.deleteBtnEvent(str);
  179. break;
  180. case "保存":
  181. this.saveBtnEvent(str, coord, data);
  182. break;
  183. }
  184. });
  185. });
  186. return div;
  187. }
  188. },
  189. modifyBtnEvent() {
  190. console.log("用户点击了地图中的修改按钮!");
  191. },
  192. confirmBtnEvent() {
  193. console.log("用户点击地图中的确认按钮");
  194. },
  195. deleteBtnEvent() {
  196. console.log("delete btn");
  197. },
  198. // 点击保存事件时保存点数据
  199. saveBtnEvent(str, coord, data) {
  200. console.log("save btn");
  201. let type = $(`#${str}_id select`).val();
  202. let des = $(`#${str}_id textarea`).val();
  203. let _oldMyLabelPointsArr = this.$store.state.myLabelPointsArr;
  204. let _myLabelPointsArrMap = {
  205. id: publicFun.buildGuid("myLabel"),
  206. coord: coord,
  207. type: type,
  208. des: des,
  209. data: data
  210. };
  211. _oldMyLabelPointsArr.push(_myLabelPointsArrMap);
  212. this.$store.commit("changeMyLabelData", _oldMyLabelPointsArr);
  213. map2DViewer.map.closePopup();
  214. },
  215. // 卷帘对比
  216. JLControl() {
  217. this.JLControlShowStatus = !this.JLControlShowStatus;
  218. if (this.JLControlShowStatus) {
  219. map2DViewer.jlMap = L.tileLayer(
  220. "http://t0.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=f331ba0b9ab96fb21c56d91de868935d"
  221. ).addTo(map2DViewer.map);
  222. map2DViewer.jlControl = L.control.sideBySide(map2DViewer.map, map2DViewer.jlMap).addTo(map2DViewer.map);
  223. } else {
  224. map2DViewer.map.removeControl(map2DViewer.jlControl);
  225. map2DViewer.map.removeLayer(map2DViewer.jlMap);
  226. delete map2DViewer.jlMap;
  227. map2DViewer.jlControl = null;
  228. }
  229. },
  230. // 疑点审计
  231. caseAuditEvent() {
  232. // console.log("case audit");
  233. // 每次点击按钮后重绘弹窗
  234. if (this.currentHtml && this.currentCid) {
  235. setTimeout(() => {
  236. this.popup.setContent(this.createAuditDiv(this.currentCid)).openOn(map2DViewer.map);
  237. }, 300);
  238. }
  239. },
  240. // 初始化引入绘制工具
  241. initDraw() {
  242. // 引入疑点标记绘制方法
  243. map2DViewer.drawToolFire = data => {
  244. try {
  245. // 纬经度
  246. if (data && data.points.length >= 1) {
  247. console.log(data.points[data.points.length - 1], "绘制的图形");
  248. let coord = data.points[data.points.length - 1];
  249. if (coord && coord.length >= 2) {
  250. let newCoord = { lat: coord[0], lng: coord[1] };
  251. this.labelDetailsPopupShow = true;
  252. this.labelPopup = L.popup({ maxWidth: 700, maxHeight: 600 })
  253. .setLatLng(newCoord)
  254. .setContent(this.createLabelDiv("label", coord, data))
  255. .openOn(map2DViewer.map);
  256. this.labelDetailsPopupShow = false;
  257. }
  258. }
  259. } catch (e) {
  260. console.log("引入疑点标记绘制方法 error");
  261. }
  262. };
  263. map2DViewer.setDrawTool({
  264. action: "add",
  265. offset: [150, 50],
  266. background: "#fff",
  267. color: "red",
  268. font_size: "14px",
  269. closeButton: true,
  270. iconUrl: "../../static/plugins/draw-plugin/images/marker-icon.png"
  271. });
  272. },
  273. mapInit: function () {
  274. // var crs = new L.Proj.CRS(
  275. // "EPSG:2401",
  276. // "+proj=tmerc +lat_0=0 +lon_0=121.2751921 +k=1 +x_0=0 +y_0=-3457147.81 +ellps=krass +units=m +no_defs",
  277. // {
  278. // resolutions: [
  279. // 529.1666666666666, 264.5833333333333, 132.29166666666666, 52.916666666666664, 26.458333333333332,
  280. // 13.229166666666666, 5.291666666666666, 2.645833333333333, 1.3229166666666665, 0.5291666666666666,
  281. // 0.2645833333333333, 0.13229166666666664
  282. // ],
  283. // origin: [-66000, 75000],
  284. // bounds: L.bounds([-65000, -76000], [75000, 72000])
  285. // }
  286. // );
  287. map2DViewer.map = L.map("map2DViewer", {
  288. // crs: crs,
  289. // center: [31.074472887639914, 121.72521988031804],
  290. // zoom: 1,
  291. // minZoom: 1,
  292. // maxZoom: 12
  293. attributionControl: false,
  294. zoomControl: false,
  295. minZoom: 10,
  296. maxZoom: 16
  297. }).setView(systemConfig.mapViewer.center, systemConfig.mapViewer.zoom);
  298. //添加默认图层
  299. let guid = publicFun.buildGuid("baseLayer");
  300. let layer = L.esri
  301. .tiledMapLayer({
  302. url: systemConfig.mapService + "?servertype=Street_Purplish_Blue&token=" + systemConfig.token
  303. // url: "http://aimap.pudong.sh:5236/maps/rest/services/basemap-shanghai-gem-blue-sh2000/mapserver",
  304. // tileSize: 512
  305. })
  306. .addTo(map2DViewer.map);
  307. // layer.setStyle({opacity:0,fillOpacity:0})
  308. map2DViewer.layers["darkmap"] = layer;
  309. // 加载天地图
  310. let imageryLayer = L.tileLayer(systemConfig.imageryLayer);
  311. map2DViewer.layers["imagery"] = imageryLayer;
  312. },
  313. // 传入街道参数,重新渲染区域图层
  314. getJSonDataToStreet(url, param) {
  315. // 先删除历史图层
  316. if (map2DViewer.map.hasLayer(map2DViewer.groups["district_polygon"])) {
  317. map2DViewer.groups["district_label"].remove();
  318. map2DViewer.groups["district_polygon"].remove();
  319. }
  320. // 请求并渲染新的区域图层
  321. get("./static/json/pdgeojson.json", "").then(geoJson => {
  322. map2DViewer.groups["district_polygon"] = L.featureGroup();
  323. map2DViewer.groups["district_label"] = L.featureGroup();
  324. // console.log(map2DViewer.groups["district_polygon"], "district_polygon group");
  325. map2DViewer.groups["district_polygon"].addTo(map2DViewer.map);
  326. map2DViewer.groups["district_label"].addTo(map2DViewer.map);
  327. geoJson.features.map(feature => {
  328. if (this.town.indexOf(feature.properties.NAME.replace("镇", "")) > -1) {
  329. let center = turf.center(feature.geometry);
  330. this.renderPolygon(feature);
  331. }
  332. });
  333. });
  334. },
  335. getJSonData() {
  336. if (!map2DViewer.map) {
  337. this.mapInit();
  338. } else if (
  339. // 切换到首页和疑点筛查页且图层不存在时重新渲染区域图
  340. (this.$ifMenu("1", "") || this.$ifMenu("2", "")) &&
  341. !map2DViewer.map.hasLayer(map2DViewer.groups["district_polygon"])
  342. ) {
  343. this.getJSonDataToStreet("", "");
  344. } else if (
  345. !(this.$ifMenu("1", "") || this.$ifMenu("2", "")) &&
  346. map2DViewer.map.hasLayer(map2DViewer.groups["district_polygon"])
  347. ) {
  348. // 当前页不是首页和疑点筛查页时移除区域图且图层存在时
  349. map2DViewer.groups["district_label"].remove();
  350. map2DViewer.groups["district_polygon"].remove();
  351. }
  352. },
  353. setView: function (coord, zoom) {
  354. // console.log(coord, "位置");
  355. let center = L.latLng(coord[0], coord[1]);
  356. map2DViewer.map.setView(center, zoom);
  357. },
  358. renderPolygon: function (feature) {
  359. let center = turf.center(feature.geometry);
  360. let itemvalue = JSON.parse((Math.random() * 1000).toFixed(0));
  361. let polygonData = JSON.parse(JSON.stringify(feature));
  362. let coordinates = polygonData.geometry.coordinates[0];
  363. let polygon = L.polygon(this.latLngsToReverse(coordinates), {
  364. color: "#87d8fd",
  365. weight: 3,
  366. fillColor: this.getColor(itemvalue),
  367. opacity: 1,
  368. fillOpacity: 0.4
  369. }).addTo(map2DViewer.groups["district_polygon"]);
  370. center = JSON.parse(JSON.stringify(center)).geometry.coordinates;
  371. center.reverse();
  372. let wmarker = L.circleMarker(center, {
  373. radius: 10,
  374. weight: 1,
  375. fillOpacity: 0,
  376. color: "#e6d273"
  377. });
  378. wmarker.bindLabel(feature.properties.NAME, {
  379. noHide: true,
  380. clickable: true,
  381. offset: [-25, 10]
  382. });
  383. wmarker.addTo(map2DViewer.groups["district_label"]);
  384. L.circleMarker(center, {
  385. radius: 8,
  386. weight: 1,
  387. fillOpacity: 0,
  388. color: "#e6d273"
  389. }).addTo(map2DViewer.groups["district_polygon"]);
  390. L.circleMarker(center, {
  391. radius: 5,
  392. weight: 1,
  393. fillOpacity: 1,
  394. color: "#e6d273"
  395. }).addTo(map2DViewer.groups["district_polygon"]);
  396. },
  397. latLngsToReverse: function (latlngsAry) {
  398. var tempLatlngsAry = JSON.parse(JSON.stringify(latlngsAry));
  399. if (typeof tempLatlngsAry[0] != "object") {
  400. return tempLatlngsAry.reverse();
  401. } else {
  402. for (var i = 0, l = tempLatlngsAry.length; i < l; i++) {
  403. tempLatlngsAry[i] = this.latLngsToReverse(tempLatlngsAry[i]);
  404. }
  405. }
  406. return tempLatlngsAry;
  407. },
  408. getColor: function (val) {
  409. var that = this;
  410. if (val < 350) {
  411. return "#e565ff";
  412. } else if (val < 700 && val >= 350) {
  413. return "#0055ff";
  414. } else {
  415. return "#00ffd5";
  416. }
  417. },
  418. // 综合分析 - 图层绘制面
  419. addPolygonLayer(data, cid, color) {
  420. // cid -- 'yongjiu'
  421. // console.log(data, cid, color);
  422. data.map(feature => {
  423. let polygonData = JSON.parse(JSON.stringify(feature));
  424. let coordinates = polygonData.geometry.coordinates[0];
  425. let infos = polygonData.properties;
  426. let polygon = L.polygon(coordinates, {
  427. color: color,
  428. weight: 3,
  429. fillColor: color,
  430. opacity: 1,
  431. fillOpacity: 0.4
  432. }).addTo(map2DViewer.map);
  433. map2DViewer.polygons[`${cid}_layer`].push(polygon);
  434. polygon.infos = infos;
  435. polygon.on("click", e => {
  436. // console.log(e, "polygon");
  437. this.auditPopupShow = true;
  438. console.log(e.latlng, "获取当前弹窗坐标111");
  439. this.popup = L.popup({ maxWidth: 700, maxHeight: 600 }).setLatLng(e.latlng).setContent(this.createAuditDiv("cid"));
  440. // .openOn(map2DViewer.map);
  441. this.auditPopupShow = false;
  442. this.popup.openOn(map2DViewer.map);
  443. this.currentCid = cid;
  444. });
  445. });
  446. },
  447. //综合分析 - 标记疑点 - 删除面
  448. deletePolygonLayer(layer) {
  449. map2DViewer.polygons[layer].forEach(polygon => {
  450. map2DViewer.map.removeLayer(polygon);
  451. });
  452. }
  453. }
  454. };
  455. </script>
  456. <style scoped>
  457. #map2DViewer {
  458. position: absolute;
  459. width: 100%;
  460. height: calc(100% - 60px);
  461. background-color: #003452;
  462. z-index: 1;
  463. top: 60px;
  464. left: 0px;
  465. }
  466. </style>