MapHolder.vue 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. <template>
  2. <div id="map2DViewer">
  3. <!-- 特殊地图属性弹窗 -- 有审计功能 -->
  4. <CaseAuditPopup
  5. v-show="auditPopupShow"
  6. :tableObj="auditRefTableObj"
  7. :defaultStatus="defaultStatus"
  8. ref="auditRef"
  9. />
  10. <!-- 通用地图属性弹窗 -- 无审计功能 -->
  11. <NormalAttrPopup
  12. v-show="normalAttrPopupShow"
  13. :tableObj="tableObj"
  14. ref="normalRef"
  15. />
  16. <LabelCasePopup v-show="labelDetailsPopupShow" ref="labelRef" />
  17. </div>
  18. </template>
  19. <script>
  20. import publicFun from "@/utils/publicFunction.js";
  21. import transformCoord from "@/utils/coordinate";
  22. import { get } from "@/utils/request";
  23. import { streetLocation, townData } from "@/config/common";
  24. import CaseAuditPopup from "@/components/popup/CaseAuditPopup.vue";
  25. import NormalAttrPopup from "@/components/popup/NormalAttrPopup.vue";
  26. import LabelCasePopup from "@/components/popup/LabelCasePopup.vue";
  27. import coordinate from "@/utils/coordinate.js";
  28. import { nextTick } from "vue";
  29. export default {
  30. name: "MapHolder",
  31. components: {
  32. CaseAuditPopup,
  33. NormalAttrPopup,
  34. LabelCasePopup,
  35. },
  36. data() {
  37. return {
  38. town: "祝桥镇,南汇新城镇,川沙新镇,老港镇,惠南镇,航头镇,泥城镇,书院镇,新场镇,大团镇,唐镇,曹路镇,宣桥镇,张江镇,合庆镇,周浦镇,康桥镇,三林镇,高桥镇,高东镇,金桥镇,北蔡镇,万祥镇,高行镇",
  39. auditPopupShow: false,
  40. normalAttrPopupShow: false,
  41. labelDetailsPopupShow: false,
  42. auditPopupStatus: "normal",
  43. popup: null,
  44. labelPopup: null,
  45. normalPopup: null,
  46. // 疑点审计
  47. currentCid: null,
  48. currentHtml: null,
  49. currentProperties: null,
  50. currentSourceType: null,
  51. currentModelId: null,
  52. currentColumnId: null,
  53. // 标记疑点
  54. currentLabelCid: null,
  55. currentLabelHtml: null,
  56. // 疑点审计的保存后的疑点状态集合
  57. caseStatusMap: new Map(),
  58. tableObj: {
  59. 镇域名称: "--",
  60. "面积(平方米)": "--",
  61. 土地类型: "--",
  62. 图斑编号: "--",
  63. },
  64. auditRefTableObj: {
  65. 镇域名称: "--",
  66. "面积(平方米)": "--",
  67. 图层构成: "--",
  68. 性质: "--",
  69. },
  70. defaultStatus: "未标记",
  71. };
  72. },
  73. created() {},
  74. mounted() {
  75. // 监听全局事件总线中的卷帘对比事件(JLControl)
  76. this.$bus.$off("JLControl");
  77. this.$bus.$on("JLControl", () => {
  78. this.JLControl();
  79. });
  80. // 监听全局事件总线中的卷帘对比重绘事件(reJLControl)
  81. this.$bus.$off("reJLControl");
  82. this.$bus.$on("reJLControl", () => {
  83. this.reJLControl();
  84. });
  85. this.$bus.$off("caseAuditEvent");
  86. this.$bus.$on("caseAuditEvent", () => {
  87. this.caseAuditEvent();
  88. this.$bus.$emit("caseAuditEvent2");
  89. });
  90. //地图初始化
  91. this.mapInit();
  92. this.$store.state.mapMethodsCollection.set("RENDER", {
  93. addPolygonLayer: this.addPolygonLayer,
  94. setView: this.setView,
  95. deletePolygonLayer: this.deletePolygonLayer,
  96. addSinglePolygon: this.addSinglePolygon,
  97. deleteSinglePolygon: this.deleteSinglePolygon,
  98. deleteGroupFromMap: this.deleteGroupFromMap,
  99. drawGeometry: this.drawGeometry,
  100. deleteGeometry: this.deleteGeometry,
  101. addTiledMapLayer: this.addTiledMapLayer,
  102. });
  103. },
  104. beforeDestroyed() {
  105. // 当容器销毁时,需要停止监听该事件
  106. this.$bus.$off("JLControl");
  107. // 疑点审计
  108. this.$bus.$off("caseAuditEvent");
  109. map2DViewer.map.closePopup();
  110. },
  111. computed: {
  112. // 监听底部菜单栏的状态
  113. getLabelCaseBtnStatus() {
  114. //疑点审计 1,0
  115. let _index = this.$store.state.bottomMenuIndexs.index;
  116. let _subIndex = this.$store.state.bottomMenuIndexs.subIndex;
  117. return { index: _index, subIndex: _subIndex };
  118. },
  119. // 监听当前菜单
  120. getCurrentMenu() {
  121. return this.$store.state.navSelect;
  122. },
  123. },
  124. watch: {
  125. getLabelCaseBtnStatus(val) {
  126. // console.log(val, "标记疑点");
  127. if (val.index === 1 && val.subIndex === 1) {
  128. // 删除地图上所有弹窗
  129. this.$store.state.attrTableShow = false;
  130. this.$store.state.updateCasePopupShow = false;
  131. // 删除地图上的所有标记
  132. if (map2DViewer.myLabels) {
  133. for (let i in map2DViewer.myLabels) {
  134. // console.log(i, "图层名");
  135. this.deleteGeometry(map2DViewer.myLabels[i]);
  136. map2DViewer.myLabels[i] = null;
  137. }
  138. }
  139. this.initDraw();
  140. } else {
  141. this.stopLabelCase();
  142. if (this.labelPopup) {
  143. map2DViewer.map.closePopup();
  144. this.labelPopup = null;
  145. }
  146. }
  147. },
  148. "$store.state.navSelect": {
  149. handler(val) {
  150. if (val.index !== "3") {
  151. if (map2DViewer.map.hasLayer(map2DViewer.jlMap)) {
  152. map2DViewer.map.removeControl(map2DViewer.jlControl);
  153. map2DViewer.map.removeLayer(map2DViewer.jlMap);
  154. delete map2DViewer.jlMap;
  155. map2DViewer.jlControl = null;
  156. }
  157. this.$store.state.bottomMenuIndexs.index = -1;
  158. this.$store.state.bottomMenuIndexs.subIndex = -1;
  159. this.$store.commit("changeJlActiveState", false);
  160. }
  161. // 切换页面时判断是否需要显示区域图
  162. this.$nextTick(() => {
  163. this.getJSonData();
  164. });
  165. },
  166. // immediate: true
  167. },
  168. },
  169. methods: {
  170. // 添加tiledMapLayer图层 -- 针对arcgis rest services
  171. addTiledMapLayer(url) {
  172. let layer = L.esri.tiledMapLayer({
  173. tileSize: 512,
  174. url: url,
  175. minZoom: 0,
  176. minNativeZoom: 0,
  177. maxNativeZoom: 7,
  178. maxZoom: 14,
  179. });
  180. return layer;
  181. },
  182. // 开始标记疑点事件
  183. startLabelCase() {
  184. map2DViewer.setDrawTool({ action: "start" });
  185. },
  186. // 停止标记疑点事件
  187. stopLabelCase() {
  188. if (map2DViewer.measureTool) {
  189. map2DViewer.setDrawTool({
  190. action: "remove",
  191. });
  192. }
  193. },
  194. reStartLabelCase() {
  195. this.stopLabelCase();
  196. this.initDraw();
  197. },
  198. /**
  199. * 无审计功能的地图弹窗
  200. * @str
  201. * @properties
  202. * @sourceType
  203. */
  204. createNormalDiv(str, geojsonData, sourceType) {
  205. let currentInnerHtml = this.$refs.normalRef.$el.innerHTML;
  206. if (currentInnerHtml) {
  207. let div = document.createElement("div");
  208. div.id = str + "_id";
  209. div.className = "case-audit";
  210. // 动态创建div后赋值模板样式
  211. div.innerHTML = currentInnerHtml;
  212. // 需要显示法律法规详细信息的弹窗
  213. if (sourceType) {
  214. setTimeout(() => {
  215. let _this = this;
  216. // 法律法规点击事件
  217. if ($(`#${str}_id a`)) {
  218. $(`#${str}_id a`)
  219. .eq(0)
  220. .click((e) => {
  221. this.$store.state.lawPopupShow = true;
  222. this.$store.state.lawSourceType = sourceType;
  223. });
  224. $(`#${str}_id a`)
  225. .eq(1)
  226. .click((e) => {
  227. // 触发综合分析右侧面板点击事件
  228. this.$bus.$emit("viewDetailsPopup", geojsonData);
  229. });
  230. }
  231. }, 0);
  232. } else {
  233. // 不需要显示法律法规详细信息的弹窗
  234. $(() => {
  235. if ($(`#${str}_id a`)) {
  236. $(`#${str}_id a`).remove();
  237. }
  238. });
  239. // console.log("呈现我的模型的几何数据");
  240. }
  241. return div;
  242. }
  243. },
  244. /**
  245. * 有审计功能的地图弹窗
  246. * @str
  247. * @properties
  248. * @sourceType
  249. * @modelId -- 用于疑点标记修改保存
  250. * @columnId -- 用于疑点标记修改保存
  251. */
  252. createAuditDiv(str, geojsonData, sourceType, modelId, columnId) {
  253. // 根据ref获取组件的dom元素columnId
  254. this.currentHtml = this.$refs.auditRef.$el.innerHTML;
  255. if (this.currentHtml) {
  256. let div = document.createElement("div");
  257. div.id = str + "_id";
  258. div.className = "case-audit";
  259. // 动态创建div后赋值模板样式
  260. div.innerHTML = this.currentHtml;
  261. setTimeout(() => {
  262. // let _this = this;
  263. // 属性框内容
  264. // if ($(".center-table-item-normal")) {
  265. // $(".center-table-item-normal .leftcell").each((index, domEle) => {
  266. // $(".center-table-item-normal .leftcell").eq(index).text(Object.keys(_this.auditRefTableObj)[index]);
  267. // $(".center-table-item-normal .rightcell").eq(index).text(Object.values(_this.auditRefTableObj)[index]);
  268. // });
  269. // }
  270. // if ($(".center-table-item-special")) {
  271. // $(".center-table-item-special .leftcell").each((index, domEle) => {
  272. // $(".center-table-item-speciall .leftcell").eq(index).text(Object.keys(_this.auditRefTableObj)[index]);
  273. // $(".center-table-item-special .rightcell").eq(index).text(Object.values(_this.auditRefTableObj)[index]);
  274. // });
  275. // }
  276. // 下拉框内容
  277. if ($(`#${str}_id .center-table-item-special select`)) {
  278. if (this.caseStatusMap.has(str)) {
  279. $(`#${str}_id .center-table-item-special select`).val(
  280. this.caseStatusMap.get(str)
  281. );
  282. let inputStatus = "";
  283. if (this.caseStatusMap.has(str)) {
  284. this.caseStatusMap.get(str) === "isTrue" &&
  285. $(`#${str}_id .center-table-item-special input`).val("疑点");
  286. !this.caseStatusMap.get(str) === "isTrue" &&
  287. $(`#${str}_id .center-table-item-special input`).val(
  288. "非疑点"
  289. );
  290. }
  291. }
  292. }
  293. // 法律法规点击事件
  294. if ($(`#${str}_id a`)) {
  295. $(`#${str}_id a`)
  296. .eq(0)
  297. .click((e) => {
  298. this.$store.state.lawPopupShow = true;
  299. this.$store.state.lawSourceType = sourceType;
  300. });
  301. $(`#${str}_id a`)
  302. .eq(1)
  303. .click((e) => {
  304. // 触发综合分析右侧面板点击事件
  305. this.$bus.$emit("viewDetailsPopup", geojsonData);
  306. });
  307. }
  308. // input添加点击事件
  309. if ($(`#${str}_id input`)[1]) {
  310. $(`#${str}_id input`).click((e) => {
  311. switch (e.target.defaultValue) {
  312. case "取消":
  313. this.cancelBtnEvent();
  314. break;
  315. case "确认":
  316. this.confirmBtnEvent(str, modelId, columnId);
  317. break;
  318. }
  319. });
  320. }
  321. }, 0);
  322. return div;
  323. }
  324. },
  325. /**
  326. * 标记疑点完成时保存描述信息的弹窗
  327. * @str -- id
  328. * @coord -- 坐标信息
  329. * @data -- 其余数据
  330. * @geoType -- 几何体类型
  331. */
  332. createLabelDiv(str, coord, data, geoType) {
  333. // console.log(str, "label - str");
  334. this.currentLabelHtml = this.$refs.labelRef.$el.innerHTML;
  335. if (this.currentLabelHtml) {
  336. let div = document.createElement("div");
  337. div.id = `${str}_id`;
  338. div.className = "label-case";
  339. // 动态创建div后赋值模板样式
  340. div.innerHTML = this.currentLabelHtml;
  341. $(() => {
  342. console.log($(`#${str}_id textarea`).val(), "textarea");
  343. $(`#${str}_id`).css("height", "100%");
  344. $(`#${str}_id input`).click((e) => {
  345. console.log(e.target.defaultValue);
  346. switch (e.target.defaultValue) {
  347. case "取消":
  348. this.cancelBtnEvent();
  349. break;
  350. case "保存":
  351. this.saveBtnEvent(str, data, geoType);
  352. break;
  353. }
  354. });
  355. });
  356. return div;
  357. }
  358. },
  359. modifyBtnEvent() {
  360. console.log("用户点击了地图中的修改按钮!");
  361. },
  362. confirmBtnEvent(str, modelId, columnId) {
  363. debugger;
  364. console.log(str, "str--当前开启的");
  365. // isTrue
  366. let selectVal = $(`#${str}_id .center-table-item-special select`).val();
  367. this.caseStatusMap.set(str, selectVal);
  368. if (selectVal === "isTrue") {
  369. map2DViewer.polygons[str].setStyle({
  370. color: `rgb(${caseColorChange["isPointColor"][0]},${caseColorChange["isPointColor"][1]},${caseColorChange["isPointColor"][2]})`,
  371. weight: 4,
  372. });
  373. } else {
  374. map2DViewer.polygons[str].setStyle({
  375. color: `rgb(${caseColorChange["notPointColor"][0]},${caseColorChange["notPointColor"][1]},${caseColorChange["notPointColor"][2]})`,
  376. weight: 4,
  377. });
  378. }
  379. console.log(map2DViewer.polygons[str]);
  380. // 修改疑点时必须要写id
  381. let obj = {
  382. id: str,
  383. c_date_time: this.$dayjs().valueOf(),
  384. c_boolean: selectVal === "isTrue" ? true : false,
  385. // 修改人员名称
  386. c_editor_name: localStorage.getItem("USER_NAME"),
  387. // 修改人员ID
  388. c_editorid: localStorage.getItem("USER_ID"),
  389. };
  390. let modifyParams = new FormData();
  391. modifyParams = {
  392. columnId: columnId,
  393. modelId: modelId,
  394. content: JSON.stringify(obj),
  395. };
  396. this.$Post(this.urlsCollection.updateContent, modifyParams).then(
  397. (res) => {
  398. if (res.code === 200) {
  399. this.$message.success("数据修改成功");
  400. map2DViewer.map.closePopup();
  401. switch (selectVal) {
  402. case "isTrue":
  403. this.$store.state.mapMethodsCollection
  404. .get("METHODS")
  405. .changeSortMethod("疑点");
  406. break;
  407. case "isFalse":
  408. this.$store.state.mapMethodsCollection
  409. .get("RENDER")
  410. .changeSortMethod("非疑点");
  411. break;
  412. }
  413. }
  414. }
  415. );
  416. },
  417. cancelBtnEvent() {
  418. map2DViewer.map.closePopup();
  419. this.labelPopup = null;
  420. this.popup = null;
  421. },
  422. /**
  423. * 点击保存事件时保存点数据
  424. * @str
  425. * @data -- 绘制几何体时获取的数据;
  426. * @geoType 几何体类型 类型: 0 点;1 线;2 面;3 矩形;4 圆形;5 其他;
  427. */
  428. saveBtnEvent(str, data, geoType) {
  429. if (localStorage.getItem("USER_ID")) {
  430. let title = $(`#${str}_id select`).val();
  431. let des = $(`#${str}_id textarea`).val();
  432. let geoName = "";
  433. let currentName = $(`#${str}_id input`).eq(0).val();
  434. if (myLabelNameMap.has(currentName)) {
  435. this.$message.info("该名称已存在,请重新输入!");
  436. } else {
  437. geoName = $(`#${str}_id input`).eq(0).val();
  438. let coordinates = [data.points];
  439. let geometry = publicFun.generateGeoJSON(
  440. title,
  441. des,
  442. geoType,
  443. coordinates,
  444. geoName
  445. );
  446. let params = new FormData();
  447. let newGeojson = JSON.stringify(geometry);
  448. myLabelNameMap.set(geoName, newGeojson);
  449. params = {
  450. geojson: newGeojson,
  451. type: geoType,
  452. userId: Number(localStorage.getItem("USER_ID")),
  453. sourceId: 0,
  454. };
  455. this.$Post(this.urlsCollection.addConllection, params).then(
  456. (res) => {
  457. if (res.code == 200) {
  458. // 标记成功后删除保存的原有名称
  459. myLabelNameMap.delete(geoName);
  460. map2DViewer.map.closePopup();
  461. // 根据用户获取标记
  462. let paramData = new FormData();
  463. paramData = {
  464. userId: Number(localStorage.getItem("USER_ID")),
  465. sourceId: 0,
  466. pageSize: 10,
  467. };
  468. // 暂存map中刚刚保存的数据
  469. this.$Post(this.urlsCollection.selectByUser, paramData).then(
  470. (userRes) => {
  471. if (userRes.code === 200) {
  472. if (userRes.content.length > 0) {
  473. this.$store.state.myLabelPointsArr = [];
  474. this.$store.state.myLabelPointsArr =
  475. userRes.content.map((v) => {
  476. if (JSON.stringify(geometry) === v.geojson) {
  477. sessionStorage.setItem("myLabelPointsId", v.id);
  478. }
  479. return {
  480. id: v.id,
  481. geojson: v.geojson,
  482. type: v.type,
  483. };
  484. });
  485. // 判断刚刚暂存的数据,并调用小眼睛的方法
  486. }
  487. }
  488. // 更新时调用一次搜索接口
  489. }
  490. );
  491. }
  492. // 保存后需要删除地图上的标记
  493. this.reStartLabelCase();
  494. },
  495. (error) => {
  496. console.log("标记疑点保存失败!", error);
  497. this.reStartLabelCase();
  498. }
  499. );
  500. }
  501. }
  502. },
  503. // 卷帘对比
  504. JLControl() {
  505. if (!map2DViewer.map.hasLayer(map2DViewer.jlMap)) {
  506. // 天地图遥感影像数据
  507. // map2DViewer.jlMap = L.tileLayer(
  508. // "http://t0.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=f331ba0b9ab96fb21c56d91de868935d"
  509. // ).addTo(map2DViewer.map);
  510. map2DViewer.jlMap = this.addTiledMapLayer(
  511. systemConfig.imageryLayerSat2018s2.url
  512. ).addTo(map2DViewer.map);
  513. map2DViewer.jlControl = L.control
  514. .sideBySide(map2DViewer.map, map2DViewer.jlMap)
  515. .addTo(map2DViewer.map);
  516. } else if (map2DViewer.map.hasLayer(map2DViewer.jlMap)) {
  517. map2DViewer.map.removeControl(map2DViewer.jlControl);
  518. map2DViewer.map.removeLayer(map2DViewer.jlMap);
  519. delete map2DViewer.jlMap;
  520. map2DViewer.jlControl = null;
  521. }
  522. },
  523. // 卷帘对比重绘
  524. reJLControl() {
  525. if (map2DViewer.map.hasLayer(map2DViewer.jlMap)) {
  526. map2DViewer.map.removeControl(map2DViewer.jlControl);
  527. map2DViewer.map.removeLayer(map2DViewer.jlMap);
  528. delete map2DViewer.jlMap;
  529. map2DViewer.jlControl = null;
  530. this.JLControl();
  531. }
  532. },
  533. // 疑点审计
  534. caseAuditEvent() {
  535. if (this.currentHtml && this.currentCid) {
  536. setTimeout(() => {
  537. this.popup.setContent(
  538. this.createAuditDiv(
  539. this.currentCid,
  540. this.currentProperties,
  541. this.currentSourceType,
  542. this.currentModelId,
  543. this.currentColumnId
  544. )
  545. );
  546. }, 300);
  547. }
  548. },
  549. // 初始化引入绘制工具
  550. initDraw() {
  551. if (!map2DViewer.measureTool) {
  552. // 引入疑点标记绘制方法
  553. map2DViewer.drawToolFire = (data) => {
  554. // 纬经度
  555. if (data && data.points.length >= 1) {
  556. let geoType = null;
  557. // 类型: 0 点;1 线;2 面;3 矩形;4 圆形;5 其他;
  558. if (data.points.length === 1 && data.area === 0) {
  559. geoType = 0;
  560. }
  561. if (data.points.length === 2 && data.distance > 0) {
  562. geoType = 4;
  563. }
  564. if (data.points.length > 2 && data.area === 0) {
  565. geoType = 1;
  566. }
  567. if (data.points.length > 2 && data.area != 0 && data.area != "") {
  568. geoType = 2;
  569. }
  570. let coord = data.points[data.points.length - 1];
  571. if (coord && coord.length >= 2) {
  572. let newCoord = { lat: coord[0], lng: coord[1] };
  573. this.labelDetailsPopupShow = true;
  574. this.labelPopup = L.popup({ maxWidth: 700, maxHeight: 600 })
  575. .setLatLng(newCoord)
  576. .setContent(this.createLabelDiv("label", coord, data, geoType))
  577. .openOn(map2DViewer.map);
  578. this.labelDetailsPopupShow = false;
  579. }
  580. }
  581. };
  582. map2DViewer.setDrawTool({
  583. action: "add",
  584. offset: [150, 50],
  585. background: "#fff",
  586. color: "red",
  587. font_size: "14px",
  588. closeButton: true,
  589. iconUrl: "../../static/plugins/draw-plugin/images/marker-icon.png",
  590. });
  591. }
  592. },
  593. mapInit: function () {
  594. // 遥感影像图层crs
  595. let crs = new L.Proj.CRS(
  596. "EPSG:0986",
  597. "+proj=tmerc +lat_0=0 +lon_0=121.2751921 +k=1 +x_0=0 +y_0=-3457147.81 +ellps=krass +units=m +no_defs",
  598. {
  599. resolutions: systemConfig.imageryLayer.resolutions,
  600. origin: [-66000, 75000],
  601. bounds: L.bounds([-65000, -76000], [75000, 72000]),
  602. }
  603. );
  604. map2DViewer.map = L.map("map2DViewer", {
  605. crs: crs,
  606. zoom: 0,
  607. minZoom: systemConfig.imageryLayer.minZoom,
  608. maxZoom: systemConfig.imageryLayer.maxZoom,
  609. attributionControl: false,
  610. zoomControl: false,
  611. // preferCanvas: true,
  612. }).setView(systemConfig.mapViewer.center, systemConfig.mapViewer.zoom);
  613. //添加默认图层
  614. let guid = publicFun.buildGuid("baseLayer");
  615. let layer = this.addTiledMapLayer(systemConfig.blueBlackMap.url).addTo(
  616. map2DViewer.map
  617. );
  618. map2DViewer.layers["darkmap"] = layer;
  619. let imageryLayer = this.addTiledMapLayer(systemConfig.imageryLayer.url);
  620. map2DViewer.layers["imagery"] = imageryLayer;
  621. },
  622. // 传入街道参数,重新渲染区域图层
  623. getJSonDataToStreet(url, param) {
  624. // 先删除历史图层
  625. if (map2DViewer.map.hasLayer(map2DViewer.groups["浦东新区_polygon"])) {
  626. map2DViewer.groups["浦东新区_label"].remove();
  627. map2DViewer.groups["浦东新区_polygon"].remove();
  628. }
  629. // 请求并渲染新的区域图层
  630. get("./static/json/simplified_pdgeojson.json", "").then((geoJson) => {
  631. // 存放所有的面数据
  632. map2DViewer.groups["浦东新区_polygon"] = L.featureGroup();
  633. map2DViewer.groups["浦东新区_label"] = L.featureGroup();
  634. map2DViewer.groups["浦东新区_polygon"].addTo(map2DViewer.map);
  635. map2DViewer.groups["浦东新区_label"].addTo(map2DViewer.map);
  636. geoJson.features.map((feature) => {
  637. let correctCordArr = JSON.parse(
  638. JSON.stringify(feature.geometry.coordinates)
  639. );
  640. let newCorrectCoordArr = publicFun.latLngsCorrection(correctCordArr);
  641. feature.geometry.coordinates = newCorrectCoordArr;
  642. // if (
  643. // this.town.indexOf(feature.properties.NAME.replace("镇", "")) > -1
  644. // ) {
  645. this.renderPolygon(feature);
  646. // }
  647. });
  648. });
  649. },
  650. /**
  651. * val :经纬度数组
  652. */
  653. w84Proj4ToShanghai(val) {
  654. // 参数1:随意定义的坐标系名称,格式“EPSG:xxxxx”
  655. // 参数2:prj文件里的内容
  656. this.$proj4.defs(
  657. "EPSG:0986",
  658. "+proj=tmerc +lat_0=0 +lon_0=121.2751921 +k=1 +x_0=0 +y_0=-3457147.81 +ellps=GRS80 +units=m +no_defs +type=crs"
  659. );
  660. // "+proj=tmerc +lat_0=0 +lon_0=121.2751921 +k=1 +x_0=0 +y_0=-3457147.81 +ellps=krass +units=m +no_defs",
  661. // 从"EPSG:0986"转成"EPSG:4326"
  662. // coordinate 类型Array 例:[116, 39]
  663. let pro = `PROJCS[\"shanghaicity\",GEOGCS[\"GCS_Beijing_1954\",DATUM[\"D_Beijing_1954\",SPHEROID[\"Krasovsky_1940\",6378245.0,298.3]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Transverse_Mercator\"],PARAMETER[\"False_Easting\",-3457147.81],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",121.2751921],PARAMETER[\"Scale_Factor\",1.0],PARAMETER[\"Latitude_Of_Origin\",0.0],UNIT[\"Meter\",1.0]]`;
  664. return this.$proj4("EPSG:0986", "EPSG:4326", val);
  665. },
  666. // 可视化单一的镇域面
  667. getSingleJsonData(name) {},
  668. // 默认获取浦东新区全区的图层数据
  669. getJSonData() {
  670. if (!map2DViewer.map) {
  671. this.mapInit();
  672. } else if (
  673. // 切换到首页和疑点筛查页且图层不存在时重新渲染区域图
  674. (this.$ifMenu("1", "") || this.$ifMenu("2", "")) &&
  675. !map2DViewer.map.hasLayer(map2DViewer.groups["浦东新区_polygon"])
  676. ) {
  677. this.getJSonDataToStreet("", "");
  678. // 切换到首页时需定位到当前图层
  679. if (this.$store.state.homeSpecialTown === "全部") {
  680. this.setView(
  681. townLocationMap.get(this.$store.state.homeSpecialTown),
  682. 0
  683. );
  684. } else {
  685. let polygon = townPolygonMap.get(this.$store.state.homeSpecialTown);
  686. map2DViewer.map.fitBounds(polygon.getBounds());
  687. }
  688. } else if (
  689. !(this.$ifMenu("1", "") || this.$ifMenu("2", "")) &&
  690. map2DViewer.map.hasLayer(map2DViewer.groups["浦东新区_polygon"])
  691. ) {
  692. // 当前页不是首页和疑点筛查页时移除区域图且图层存在时
  693. map2DViewer.groups["浦东新区_label"].remove();
  694. map2DViewer.groups["浦东新区_polygon"].remove();
  695. }
  696. },
  697. setView: function (coord, zoom) {
  698. // coord = publicFun.latLngsCorrection(coord);
  699. let center = L.latLng(coord[0], coord[1]);
  700. map2DViewer.map.setView(center, zoom);
  701. },
  702. renderPolygon: function (feature) {
  703. let center = turf.center(feature.geometry);
  704. // let itemvalue = JSON.parse((Math.random() * 1000).toFixed(0));
  705. let name = feature.properties.NAME;
  706. let polygonData = JSON.parse(JSON.stringify(feature));
  707. let coordinates = polygonData.geometry.coordinates[0];
  708. // 几何体
  709. let polygon = L.polygon(this.latLngsToReverse(coordinates), {
  710. color: "#87d8fd",
  711. weight: 3,
  712. fillColor: this.getColor(name),
  713. opacity: 1,
  714. fillOpacity: 0.4,
  715. }).addTo(map2DViewer.groups["浦东新区_polygon"]);
  716. center = JSON.parse(JSON.stringify(center)).geometry.coordinates;
  717. center.reverse();
  718. // 坐标
  719. townLocationMap.set(name, center);
  720. townPolygonMap.set(name, polygon);
  721. if (this.town.indexOf(feature.properties.NAME.replace("镇", "")) > -1) {
  722. let wmarker = L.circleMarker(center, {
  723. radius: 10,
  724. weight: 1,
  725. fillOpacity: 0,
  726. color: "#e6d273",
  727. });
  728. wmarker.bindLabel(feature.properties.NAME, {
  729. noHide: true,
  730. clickable: true,
  731. offset: [-25, 10],
  732. });
  733. wmarker.addTo(map2DViewer.groups["浦东新区_label"]);
  734. let circle1 = L.circleMarker(center, {
  735. radius: 8,
  736. weight: 1,
  737. fillOpacity: 0,
  738. color: "#e6d273",
  739. }).addTo(map2DViewer.groups["浦东新区_polygon"]);
  740. let circle2 = L.circleMarker(center, {
  741. radius: 5,
  742. weight: 1,
  743. fillOpacity: 1,
  744. color: "#e6d273",
  745. }).addTo(map2DViewer.groups["浦东新区_polygon"]);
  746. }
  747. },
  748. latLngsToReverse: function (latlngsAry) {
  749. var tempLatlngsAry = JSON.parse(JSON.stringify(latlngsAry));
  750. if (typeof tempLatlngsAry[0] != "object") {
  751. // tempLatlngsAry[0] -= 0.1915;
  752. return tempLatlngsAry.reverse();
  753. } else {
  754. for (var i = 0, l = tempLatlngsAry.length; i < l; i++) {
  755. tempLatlngsAry[i] = this.latLngsToReverse(tempLatlngsAry[i]);
  756. }
  757. }
  758. return tempLatlngsAry;
  759. },
  760. getColor(name) {
  761. if (townData.A.indexOf(name) > -1) {
  762. return "#e565ff";
  763. } else if (townData.B.indexOf(name) > -1) {
  764. return "#0055ff";
  765. } else if (townData.C.indexOf(name) > -1) {
  766. return "#00ffd5";
  767. } else {
  768. return "#00000032";
  769. }
  770. },
  771. /**
  772. * 获取图层信息 -- 所有模型和预设模型
  773. * @geometry 字符串格式的geojson数据
  774. * @cid columnId
  775. * @color 随机色
  776. * @uniqueId label_columnId
  777. * @mainType 所有图层/预设模型
  778. * @sourceType 土地资源/林地资源/生态资源/水资源/全部
  779. * @defaultStatus 当前疑点图斑的状态 -- 未标记,疑点,非疑点
  780. * @modelId -- modelId
  781. * @columnId -- columnId
  782. */
  783. addSinglePolygon(
  784. geometry,
  785. cid,
  786. color,
  787. uniqueId,
  788. mainType,
  789. sourceType,
  790. defaultStatus,
  791. modelId,
  792. columnId
  793. ) {
  794. let uniqueIdList = [];
  795. if (this.$store.state.selectSelectDataMap["singlePolygon"][uniqueId]) {
  796. uniqueIdList =
  797. this.$store.state.selectSelectDataMap["singlePolygon"][uniqueId];
  798. }
  799. let singlePolygonItem = {
  800. uniqueId: uniqueId,
  801. geometry: geometry,
  802. cid: cid,
  803. };
  804. uniqueIdList.push(singlePolygonItem);
  805. this.$store.state.selectSelectDataMap["singlePolygon"][uniqueId] =
  806. uniqueIdList;
  807. // 当前数据坐标系为WGS84
  808. let targetGeometry = JSON.parse(geometry).geometry;
  809. // 预设模型与所有图层层级不同
  810. let coord = targetGeometry.coordinates;
  811. let correctCoord = publicFun.latLngsCorrection(coord);
  812. let coordinates = publicFun.latLngsToReverse(correctCoord);
  813. let polygon = L.polygon(coordinates, {
  814. color: color,
  815. weight: 3,
  816. fillColor: color,
  817. opacity: 1,
  818. fillOpacity: 0,
  819. }).addTo(map2DViewer.analysisGroups[uniqueId]);
  820. map2DViewer.polygons[cid] = polygon;
  821. polygon.on("click", (e) => {
  822. console.log(this.defaultValue, "点击面后显示默认的标记状态");
  823. let geojsonData = geometry;
  824. // 所有图层下的疑点图层 -- 常规展示
  825. if (geojsonData) {
  826. if (mainType === "预设模型") {
  827. let geoProperties = JSON.parse(geojsonData).properties;
  828. this.auditRefTableObj = {
  829. 镇域名称: geoProperties["镇域名称"] || "--",
  830. "面积(平方米)": geoProperties["面积"] || "--",
  831. 图层构成: geoProperties["图层构成"] || "--",
  832. 性质: geoProperties["性质"] || "--",
  833. };
  834. this.defaultStatus = defaultStatus;
  835. this.$refs.auditRef.$nextTick(() => {
  836. this.currentCid = cid;
  837. this.currentProperties = geojsonData;
  838. this.currentSourceType = sourceType;
  839. this.currentModelId = modelId;
  840. this.currentColumnId = columnId;
  841. let domItem = this.createAuditDiv(
  842. cid,
  843. geojsonData,
  844. sourceType,
  845. modelId,
  846. columnId
  847. );
  848. this.auditPopupShow = true;
  849. this.popup = L.popup({ maxWidth: 700, maxHeight: 600 })
  850. .setLatLng(e.latlng)
  851. .setContent(domItem);
  852. this.auditPopupShow = false;
  853. this.popup.openOn(map2DViewer.map);
  854. });
  855. } else {
  856. let geoProperties = JSON.parse(geojsonData).properties;
  857. this.tableObj = {
  858. 镇域名称: geoProperties["镇域名称"] || "--",
  859. "面积(平方米)": geoProperties["面积"] || "--",
  860. 土地类型: geoProperties["土地类型"] || "--",
  861. 图斑编号: geoProperties["图斑编号"] || "--",
  862. };
  863. this.$refs.normalRef.$nextTick(() => {
  864. let domItem = this.createNormalDiv(cid, geojsonData, sourceType);
  865. this.normalAttrPopupShow = true;
  866. this.normalPopup = L.popup({ maxWidth: 700, maxHeight: 600 })
  867. .setLatLng(e.latlng)
  868. .setContent(domItem);
  869. this.normalAttrPopupShow = false;
  870. this.normalPopup.openOn(map2DViewer.map);
  871. });
  872. }
  873. }
  874. });
  875. },
  876. deleteSinglePolygon(polygon) {
  877. map2DViewer.map.removeLayer(polygon);
  878. },
  879. // 综合分析 - 图层显示
  880. deleteGroupFromMap(uniqueId) {
  881. if (map2DViewer.analysisGroups[uniqueId]) {
  882. map2DViewer.map.removeLayer(map2DViewer.analysisGroups[uniqueId]);
  883. }
  884. },
  885. //综合分析 - 标记疑点 - 删除面
  886. deletePolygonLayer(layer) {
  887. console.log(layer, "layer");
  888. map2DViewer.polygons[layer].forEach((polygon) => {
  889. map2DViewer.map.removeLayer(polygon);
  890. });
  891. },
  892. drawPoints(data) {
  893. if (!map2DViewer.myLabels[`label_${data.id}`]) {
  894. let point = L.marker(data.coord, {
  895. opacity: 1,
  896. }).addTo(map2DViewer.groups["我的标记图层组"]);
  897. map2DViewer.myLabels[`label_${data.id}`] = point;
  898. }
  899. },
  900. drawLine(data, color) {
  901. if (!map2DViewer.myLabels[`label_${data.id}`]) {
  902. let coordinates = JSON.parse(data.geojson).geometry.coordinates[0];
  903. let polyline = L.polyline(coordinates, {
  904. color: color,
  905. weight: 3,
  906. fillOpacity: color,
  907. opacity: 1,
  908. fillOpacity: 0.4,
  909. }).addTo(map2DViewer.groups["我的标记图层组"]);
  910. // zoom the map to the polyline
  911. map2DViewer.myLabels[`label_${data.id}`] = polyline;
  912. }
  913. },
  914. drawPolygon(data, color) {
  915. if (!map2DViewer.myLabels[`label_${data.id}`]) {
  916. let coordinates = JSON.parse(data.geojson).geometry.coordinates[0];
  917. let polygon = L.polygon(coordinates, {
  918. color: color,
  919. weight: 3,
  920. fillOpacity: color,
  921. opacity: 1,
  922. fillOpacity: 0.4,
  923. }).addTo(map2DViewer.groups["我的标记图层组"]);
  924. map2DViewer.myLabels[`label_${data.id}`] = polygon;
  925. }
  926. },
  927. drawCircle(data, color) {
  928. if (!map2DViewer.myLabels[`label_${data.id}`]) {
  929. let coordinates = JSON.parse(data.geojson).geometry.coordinates[0];
  930. if ((coordinates.length = 2)) {
  931. let from = turf.point(coordinates[0].reverse());
  932. let to = turf.point(coordinates[1].reverse());
  933. let options = { units: "kilometers" };
  934. let distance = turf.distance(from, to, options);
  935. distance = parseFloat(distance * 1000).toFixed(6);
  936. let circle = L.circle(coordinates[0].reverse(), {
  937. color: color,
  938. weight: 3,
  939. fillOpacity: color,
  940. opacity: 1,
  941. fillOpacity: 0.4,
  942. radius: Number(distance),
  943. }).addTo(map2DViewer.groups["我的标记图层组"]);
  944. map2DViewer.myLabels[`label_${data.id}`] = circle;
  945. }
  946. }
  947. },
  948. /**
  949. * 综合分析 -- 我的标记 -- 绘制单一几何体方法
  950. * @type 判断需要绘制的几何体类型
  951. */
  952. drawGeometry(type, data) {
  953. let color = "#ff0000";
  954. switch (type) {
  955. case "点":
  956. this.drawPoints(data);
  957. break;
  958. case "线":
  959. this.drawLine(data, color);
  960. break;
  961. case "面":
  962. this.drawPolygon(data, color);
  963. break;
  964. case "圆":
  965. this.drawCircle(data, color);
  966. break;
  967. }
  968. },
  969. deleteGeometry(geometry) {
  970. if (geometry) {
  971. geometry.removeFrom(map2DViewer.map);
  972. }
  973. },
  974. },
  975. };
  976. </script>
  977. <style lang="less" scoped>
  978. #map2DViewer {
  979. position: absolute;
  980. width: 100%;
  981. height: calc(100% - 60px);
  982. background-color: rgb(0, 47, 71);
  983. z-index: 1;
  984. top: 60px;
  985. left: 0px;
  986. }
  987. </style>