MapHolder.vue 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110
  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", "") || this.$ifMenu("2", "")) &&
  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 (
  742. !(this.$ifMenu("1", "") || this.$ifMenu("2", "")) &&
  743. map2DViewer.map.hasLayer(map2DViewer.groups["浦东新区_polygon"])
  744. ) {
  745. // 当前页不是首页和疑点筛查页时移除区域图且图层存在时
  746. map2DViewer.groups["浦东新区_label"].remove();
  747. map2DViewer.groups["浦东新区_polygon"].remove();
  748. }
  749. },
  750. setView: function (coord, zoom) {
  751. let center = L.latLng(coord[0], coord[1]);
  752. map2DViewer.map.setView(center, zoom);
  753. },
  754. renderPolygon: function (feature) {
  755. let center;
  756. if (
  757. feature.properties.NAME.indexOf("南汇新城镇") > -1 ||
  758. feature.properties.NAME.indexOf("高行镇") > -1 ||
  759. feature.properties.NAME.indexOf("宣桥镇") > -1 ||
  760. feature.properties.NAME.indexOf("康桥镇") > -1
  761. ) {
  762. center = turf.centerOfMass(feature.geometry);
  763. } else {
  764. center = turf.centroid(feature.geometry);
  765. }
  766. // let itemvalue = JSON.parse((Math.random() * 1000).toFixed(0));
  767. let name = feature.properties.NAME;
  768. let polygonData = JSON.parse(JSON.stringify(feature));
  769. let coordinates = polygonData.geometry.coordinates[0];
  770. // 几何体
  771. let polygon = L.polygon(this.latLngsToReverse(coordinates), {
  772. color: "#87d8fd",
  773. weight: 3,
  774. fillColor: this.getColor(name),
  775. opacity: 1,
  776. fillOpacity: 0.4,
  777. }).addTo(map2DViewer.groups["浦东新区_polygon"]);
  778. center = JSON.parse(JSON.stringify(center)).geometry.coordinates;
  779. center.reverse();
  780. // 坐标
  781. townLocationMap.set(name, center);
  782. townPolygonMap.set(name, polygon);
  783. if (this.town.indexOf(feature.properties.NAME.replace("镇", "")) > -1) {
  784. let wmarker = L.circleMarker(center, {
  785. radius: 10,
  786. weight: 1,
  787. fillOpacity: 0,
  788. color: "#e6d273",
  789. });
  790. wmarker.bindLabel(feature.properties.NAME, {
  791. noHide: true,
  792. clickable: true,
  793. offset: [-25, 10],
  794. });
  795. wmarker.addTo(map2DViewer.groups["浦东新区_label"]);
  796. let circle1 = L.circleMarker(center, {
  797. radius: 8,
  798. weight: 1,
  799. fillOpacity: 0,
  800. color: "#e6d273",
  801. }).addTo(map2DViewer.groups["浦东新区_polygon"]);
  802. let circle2 = L.circleMarker(center, {
  803. radius: 5,
  804. weight: 1,
  805. fillOpacity: 1,
  806. color: "#e6d273",
  807. }).addTo(map2DViewer.groups["浦东新区_polygon"]);
  808. }
  809. },
  810. latLngsToReverse: function (latlngsAry) {
  811. var tempLatlngsAry = JSON.parse(JSON.stringify(latlngsAry));
  812. if (typeof tempLatlngsAry[0] != "object") {
  813. // tempLatlngsAry[0] -= 0.1915;
  814. return tempLatlngsAry.reverse();
  815. } else {
  816. for (var i = 0, l = tempLatlngsAry.length; i < l; i++) {
  817. tempLatlngsAry[i] = this.latLngsToReverse(tempLatlngsAry[i]);
  818. }
  819. }
  820. return tempLatlngsAry;
  821. },
  822. getColor(name) {
  823. if (townData.A.indexOf(name) > -1) {
  824. return "#e565ff";
  825. } else if (townData.B.indexOf(name) > -1) {
  826. return "#0055ff";
  827. } else if (townData.C.indexOf(name) > -1) {
  828. return "#00ffd5";
  829. } else {
  830. return "#00000032";
  831. }
  832. },
  833. /**
  834. * 获取图层信息 -- 所有模型和预设模型
  835. * @geometry 字符串格式的geojson数据
  836. * @cid columnId
  837. * @color 随机色
  838. * @uniqueId label_columnId
  839. * @mainType 所有图层/预设模型
  840. * @sourceType 土地资源/林地资源/生态资源/水资源/全部
  841. * @defaultStatus 当前疑点图斑的状态 -- 未标记,疑点,非疑点
  842. * @modelId -- modelId
  843. * @columnId -- columnId
  844. */
  845. addSinglePolygon(
  846. geometry,
  847. cid,
  848. color,
  849. uniqueId,
  850. mainType,
  851. sourceType,
  852. defaultStatus,
  853. modelId,
  854. columnId
  855. ) {
  856. let uniqueIdList = [];
  857. if (this.$store.state.selectSelectDataMap["singlePolygon"][uniqueId]) {
  858. uniqueIdList =
  859. this.$store.state.selectSelectDataMap["singlePolygon"][uniqueId];
  860. }
  861. let singlePolygonItem = {
  862. uniqueId: uniqueId,
  863. geometry: geometry,
  864. cid: cid,
  865. color: color,
  866. };
  867. uniqueIdList.push(singlePolygonItem);
  868. this.$store.state.selectSelectDataMap["singlePolygon"][uniqueId] =
  869. uniqueIdList;
  870. // 当前数据坐标系为WGS84
  871. let targetGeometry = JSON.parse(geometry).geometry;
  872. // 预设模型与所有图层层级不同
  873. let coord = targetGeometry.coordinates;
  874. let coordinates = publicFun.latLngsToReverse(coord);
  875. let polygon = L.polygon(coordinates, {
  876. color: color,
  877. weight: 3,
  878. fillColor: color,
  879. opacity: 1,
  880. fillOpacity: 0,
  881. }).addTo(map2DViewer.analysisGroups[uniqueId]);
  882. polygon.on("click", (e) => {
  883. // 鼠标点击图版高亮提示逻辑
  884. // 首先恢复上一个图版
  885. if (
  886. this.$store.state.map2DViewerPolygonsCid.newCid &&
  887. map2DViewer.polygons[this.$store.state.map2DViewerPolygonsCid.newCid]
  888. ) {
  889. map2DViewer.polygons[
  890. this.$store.state.map2DViewerPolygonsCid.newCid
  891. ].setStyle({
  892. color: this.$store.state.map2DViewerPolygonsCid.oldColor,
  893. fillOpacity: 0,
  894. });
  895. }
  896. // 判断是否是重复点击,不是的话高亮,是的话不操作。
  897. if (cid != this.$store.state.map2DViewerPolygonsCid.newCid) {
  898. this.$store.state.map2DViewerPolygonsCid = {
  899. newCid: cid,
  900. oldColor: color,
  901. };
  902. polygon.setStyle({
  903. color: "red",
  904. fillColor: "red",
  905. fillOpacity: 0.35,
  906. });
  907. } else {
  908. this.$store.state.map2DViewerPolygonsCid = {
  909. newCid: null,
  910. oldColor: null,
  911. };
  912. }
  913. let geojsonData = geometry;
  914. // 所有图层下的疑点图层 -- 常规展示
  915. if (geojsonData) {
  916. if (mainType === "预设模型") {
  917. let geoProperties = JSON.parse(geojsonData).properties;
  918. this.auditRefTableObj = {
  919. 镇域名称: geoProperties["镇域名称"] || "--",
  920. "面积(平方米)": geoProperties["面积"] || "--",
  921. 图层构成: geoProperties["图层构成"] || "--",
  922. 性质: geoProperties["性质"] || "--",
  923. };
  924. this.defaultStatus = defaultStatus;
  925. this.$refs.auditRef.$nextTick(() => {
  926. this.currentCid = cid;
  927. this.currentProperties = geojsonData;
  928. this.currentSourceType = sourceType;
  929. this.currentModelId = modelId;
  930. this.currentColumnId = columnId;
  931. let domItem = this.createAuditDiv(
  932. cid,
  933. geojsonData,
  934. sourceType,
  935. modelId,
  936. columnId
  937. );
  938. this.auditPopupShow = true;
  939. this.popup = L.popup({ maxWidth: 700, maxHeight: 600 })
  940. .setLatLng(e.latlng)
  941. .setContent(domItem);
  942. this.auditPopupShow = false;
  943. this.popup.openOn(map2DViewer.map);
  944. });
  945. } else {
  946. let geoProperties = JSON.parse(geojsonData).properties;
  947. this.tableObj = {
  948. 镇域名称: geoProperties["镇域名称"] || "--",
  949. "面积(平方米)": geoProperties["面积"] || "--",
  950. 土地类型: geoProperties["土地类型"] || "--",
  951. 图斑编号: geoProperties["图斑编号"] || "--",
  952. };
  953. this.$refs.normalRef.$nextTick(() => {
  954. let domItem = this.createNormalDiv(cid, geojsonData, sourceType);
  955. this.normalAttrPopupShow = true;
  956. this.normalPopup = L.popup({ maxWidth: 700, maxHeight: 600 })
  957. .setLatLng(e.latlng)
  958. .setContent(domItem);
  959. this.normalAttrPopupShow = false;
  960. this.normalPopup.openOn(map2DViewer.map);
  961. });
  962. }
  963. }
  964. });
  965. map2DViewer.polygons[cid] = polygon;
  966. },
  967. deleteSinglePolygon(polygon) {
  968. map2DViewer.map.removeLayer(polygon);
  969. },
  970. // 综合分析 - 图层显示
  971. deleteGroupFromMap(uniqueId) {
  972. if (map2DViewer.analysisGroups[uniqueId]) {
  973. map2DViewer.map.removeLayer(map2DViewer.analysisGroups[uniqueId]);
  974. }
  975. },
  976. //综合分析 - 标记疑点 - 删除面
  977. deletePolygonLayer(layer) {
  978. map2DViewer.polygons[layer].forEach((polygon) => {
  979. map2DViewer.map.removeLayer(polygon);
  980. });
  981. },
  982. drawPoints(data) {
  983. if (!map2DViewer.myLabels[`label_${data.id}`]) {
  984. let point = L.marker(data.coord, {
  985. opacity: 1,
  986. }).addTo(map2DViewer.groups["我的标记图层组"]);
  987. map2DViewer.myLabels[`label_${data.id}`] = point;
  988. }
  989. },
  990. drawLine(data, color) {
  991. if (!map2DViewer.myLabels[`label_${data.id}`]) {
  992. let coordinates = JSON.parse(data.geojson).geometry.coordinates[0];
  993. let polyline = L.polyline(coordinates, {
  994. color: color,
  995. weight: 3,
  996. fillOpacity: color,
  997. opacity: 1,
  998. fillOpacity: 0.4,
  999. }).addTo(map2DViewer.groups["我的标记图层组"]);
  1000. // zoom the map to the polyline
  1001. map2DViewer.myLabels[`label_${data.id}`] = polyline;
  1002. }
  1003. },
  1004. drawPolygon(data, color) {
  1005. if (!map2DViewer.myLabels[`label_${data.id}`]) {
  1006. let coordinates = JSON.parse(data.geojson).geometry.coordinates[0];
  1007. let polygon = L.polygon(coordinates, {
  1008. color: color,
  1009. weight: 3,
  1010. fillOpacity: color,
  1011. opacity: 1,
  1012. fillOpacity: 0.4,
  1013. }).addTo(map2DViewer.groups["我的标记图层组"]);
  1014. map2DViewer.myLabels[`label_${data.id}`] = polygon;
  1015. }
  1016. },
  1017. drawCircle(data, color) {
  1018. if (!map2DViewer.myLabels[`label_${data.id}`]) {
  1019. let coordinates = JSON.parse(data.geojson).geometry.coordinates[0];
  1020. if ((coordinates.length = 2)) {
  1021. let from = turf.point(coordinates[0].reverse());
  1022. let to = turf.point(coordinates[1].reverse());
  1023. let options = { units: "kilometers" };
  1024. let distance = turf.distance(from, to, options);
  1025. distance = parseFloat(distance * 1000).toFixed(6);
  1026. let circle = L.circle(coordinates[0].reverse(), {
  1027. color: color,
  1028. weight: 3,
  1029. fillOpacity: color,
  1030. opacity: 1,
  1031. fillOpacity: 0.4,
  1032. radius: Number(distance),
  1033. }).addTo(map2DViewer.groups["我的标记图层组"]);
  1034. map2DViewer.myLabels[`label_${data.id}`] = circle;
  1035. }
  1036. }
  1037. },
  1038. /**
  1039. * 综合分析 -- 我的标记 -- 绘制单一几何体方法
  1040. * @type 判断需要绘制的几何体类型
  1041. */
  1042. drawGeometry(type, data) {
  1043. let color = "#ff0000";
  1044. switch (type) {
  1045. case "点":
  1046. this.drawPoints(data);
  1047. break;
  1048. case "线":
  1049. this.drawLine(data, color);
  1050. break;
  1051. case "面":
  1052. this.drawPolygon(data, color);
  1053. break;
  1054. case "圆":
  1055. this.drawCircle(data, color);
  1056. break;
  1057. }
  1058. },
  1059. deleteGeometry(geometry) {
  1060. if (geometry) {
  1061. geometry.removeFrom(map2DViewer.map);
  1062. }
  1063. },
  1064. },
  1065. };
  1066. </script>
  1067. <style lang="less" scoped>
  1068. #map2DViewer {
  1069. position: absolute;
  1070. width: 140%;
  1071. height: calc(147% - 2px);
  1072. background-color: rgb(0, 47, 71);
  1073. z-index: 1;
  1074. top: -220px;
  1075. left: -400px;
  1076. scale: 0.62;
  1077. }
  1078. </style>