MapHolder.vue 39 KB

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