authenticMap.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. import config from "@/api/config.js";
  2. import * as KMap from "@/utils/ol-map/KMap";
  3. import * as util from "@/common/ol_common.js";
  4. import Style from "ol/style/Style";
  5. import Icon from "ol/style/Icon";
  6. import VectorLayer from "ol/layer/Vector.js";
  7. import WKT from "ol/format/WKT.js";
  8. import { reactive } from "vue";
  9. import Point from "ol/geom/Point.js";
  10. import Feature from "ol/Feature";
  11. import { newPoint } from "@/utils/map.js";
  12. import { Fill, Text,Circle,Stroke } from "ol/style";
  13. import { getArea } from "ol/sphere.js";
  14. import * as proj from "ol/proj";
  15. import proj4 from "proj4";
  16. import { register } from "ol/proj/proj4";
  17. import GeometryCollection from 'ol/geom/GeometryCollection.js';
  18. import { ElMessage } from "element-plus";
  19. import { useStore } from "vuex";
  20. import {bboxToFeature} from "../../utils/map";
  21. import * as turf from "@turf/turf";
  22. proj4.defs(
  23. "EPSG:38572",
  24. "+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs +type=crs"
  25. );
  26. register(proj4);
  27. export let mapData = reactive({
  28. isEdit: false,
  29. isEditArea: false,
  30. curPointData: {},
  31. point: null,
  32. selectPointArr: [],
  33. isPointHide: null,
  34. disabledForm : false,
  35. selectPoint:'',
  36. pointIndex:-1
  37. });
  38. function resetMapData(){
  39. mapData.isEdit= false
  40. mapData.isEditArea= false
  41. mapData.curPointData= {}
  42. mapData.point= null
  43. mapData.selectPointArr= []
  44. mapData.isPointHide= null
  45. mapData.disabledForm= false
  46. mapData.selectPoint= ''
  47. mapData.pointIndex=-1
  48. }
  49. /**
  50. * @description 地图层对象
  51. */
  52. class AuthenticMap {
  53. constructor() {
  54. let that = this;
  55. that.store = useStore();
  56. let vectorStyle = new KMap.VectorStyle();
  57. this.vectorStyle = vectorStyle;
  58. // 位置图标
  59. this.clickPointLayer = new KMap.VectorLayer("clickPointLayer", 9999, {
  60. style: (f) => {
  61. const style1 = new Style({
  62. image: new Icon({
  63. src: require(`@/assets/images/map/${f.get("icon")}-icon.png`),
  64. scale: 0.45,
  65. }),
  66. });
  67. const style2 = new Style({
  68. text: new Text({
  69. font: "16px sans-serif",
  70. text: f.get("masterName"),
  71. offsetY: -40,
  72. padding: [4, 3, 2, 106],
  73. fill: new Fill({ color: "#fff" }), // 字体颜色
  74. }),
  75. });
  76. const style3 = new Style({
  77. image: new Icon({
  78. src: require(`@/assets/images/map/${f.get("iconBg")}.png`),
  79. scale: 0.45,
  80. displacement: [0, 90],
  81. }),
  82. });
  83. return [style1, style2, style3];
  84. },
  85. });
  86. this.locationLayer = new KMap.VectorLayer("locationLayer", 9999, {
  87. style: () => {
  88. return new Style({
  89. image: new Icon({
  90. src: require("@/assets/images/map/location.png"),
  91. scale: 0.45,
  92. }),
  93. });
  94. },
  95. });
  96. this.selectPointLayer = new KMap.VectorLayer("selectPointLayer", 10000, {
  97. style: () => {
  98. return new Style({
  99. // geometry: new Point(coord[0][i]),
  100. image: new Circle({
  101. radius: 6,
  102. fill: new Fill({
  103. color: 'red'
  104. }),
  105. stroke: new Stroke({
  106. color: '#fff',
  107. width: 1
  108. }),
  109. }),
  110. });
  111. },
  112. });
  113. // 存储绘制的地块特征
  114. // this.drawnFeatures = [];
  115. }
  116. initMap(location, target) {
  117. let that = this
  118. let level = 16;
  119. let coordinate = util.wktCastGeom(location).getFirstCoordinate();
  120. this.kmap = new KMap.Map(
  121. target,
  122. level,
  123. coordinate[0],
  124. coordinate[1],
  125. null,
  126. 6,
  127. 22
  128. );
  129. this.kmap.initDraw((e) => {
  130. if (e.type === "drawend") {
  131. mapData.isEdit = true;
  132. mapData.point = e.feature;
  133. }
  134. });
  135. this.kmap.modifyDraw((e) => {
  136. if(e.type === "modifyend"){
  137. mapData.isEditArea = false;
  138. mapData.isEditArea = true;
  139. }
  140. }, function(e){
  141. let f = null
  142. that.kmap.map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
  143. f= feature
  144. },{hitTolerance:10});
  145. if(!f){
  146. return false
  147. }
  148. let res = f.get("id") === mapData.curPointData.id || !f.get("id")
  149. if(!res){
  150. ElMessage.warning("编辑中")
  151. }
  152. console.log('f.get("height")',f);
  153. res = f.get("height").length>0?false:res
  154. return res
  155. });
  156. this.kmap.addLayer(this.clickPointLayer.layer);
  157. this.kmap.addLayer(this.locationLayer.layer);
  158. this.kmap.addLayer(this.selectPointLayer.layer);
  159. this.addMapSingerClick();
  160. }
  161. fit(geometriesWkt){
  162. let geometries = []
  163. let f = new WKT();
  164. for(let wkt of geometriesWkt){
  165. geometries.push(f.readGeometry(wkt))
  166. }
  167. let extent = new GeometryCollection(geometries).getExtent()
  168. this.kmap.fit(extent)
  169. }
  170. //撤销上一个点
  171. undoLastDraw() {
  172. // const coordinates = this.kmap.getLayerFeatures()[0].getGeometry().getCoordinates()
  173. // coordinates[0][0].pop()
  174. // this.kmap.getLayerFeatures()[0].getGeometry().getCoordinates(coordinates)
  175. }
  176. // 取消地块
  177. cancelDraw() {
  178. this.kmap.polygonLayer.source.removeFeature(mapData.point);
  179. }
  180. // 添加点位
  181. addPoint(points) {
  182. const arrPoints = [];
  183. if (points && points.length > 0) {
  184. points.forEach((item) => {
  185. let f = newPoint({ ...item, icon: "point", iconBg: "name-bg" }, "point");
  186. arrPoints.push(f);
  187. });
  188. this.clickPointLayer.source.addFeatures(arrPoints);
  189. }
  190. }
  191. // 设置地图中心点位
  192. setMapCenter(v,isPoint = true) {
  193. let arrayOfNumbers = [];
  194. const arrayOfStrings = v.split(",");
  195. arrayOfNumbers = [arrayOfStrings[1], arrayOfStrings[0]];
  196. this.kmap.map.getView().setCenter(arrayOfNumbers);
  197. if(!isPoint) return
  198. this.locationLayer.source.clear();
  199. let point = new Feature(new Point(arrayOfNumbers));
  200. this.locationLayer.addFeature(point);
  201. }
  202. // 开始勾画
  203. startDraw() {
  204. this.kmap.setDefaultCursor("crosshair");
  205. this.kmap.startDraw();
  206. this.kmap.endModify();
  207. }
  208. //结束勾画
  209. endDraw() {
  210. this.kmap.endDraw();
  211. this.kmap.endModify();
  212. }
  213. // 开始编辑
  214. startModify(type, feature) {
  215. this.kmap.startModify();
  216. this.kmap.endDraw();
  217. if(type==='upload'){
  218. mapData.point = feature
  219. mapData.point.set("icon", "point-act");
  220. this.kmap.polygonStyle(mapData.point);
  221. mapData.isPointHide = mapData.point;
  222. }else{
  223. mapData.point.set("icon", "point-act");
  224. }
  225. }
  226. //结束编辑
  227. endModify() {
  228. this.kmap.endModify();
  229. }
  230. // 清空单个数据
  231. clearMapData(name, val, id) {
  232. name && (mapData[name] = val);
  233. this.clickPointLayer.source.forEachFeature((feature) => {
  234. feature.set("icon", "point");
  235. feature.set("iconBg", "name-bg");
  236. });
  237. const points = this.kmap.getLayerFeatures();
  238. points.forEach((feature) => {
  239. feature.set("icon", "point");
  240. });
  241. resetMapData()
  242. }
  243. //全选
  244. allSelect(ids){
  245. let arr = []
  246. this.clickPointLayer.source.forEachFeature((feature) => {
  247. if(!ids || ids.findIndex((id)=> id == feature.get('id')) > -1){
  248. feature.set("icon", "point-act");
  249. feature.set("iconBg", "name-act-bg");
  250. }
  251. });
  252. const points = this.kmap.getLayerFeatures();
  253. points.forEach((feature) => {
  254. if(!ids || ids.findIndex((id)=> id == feature.get('id')) > -1) {
  255. feature.set("icon", "point-act");
  256. this.kmap.polygonStyle(feature);
  257. mapData.isPointHide = feature;
  258. arr.push(feature)
  259. }
  260. });
  261. mapData.selectPointArr = arr;
  262. }
  263. //no全选
  264. allUnSelect(){
  265. this.clickPointLayer.source.forEachFeature((feature) => {
  266. feature.set("icon", "point");
  267. feature.set("iconBg", "name-bg");
  268. });
  269. const points = this.kmap.getLayerFeatures();
  270. points.forEach((feature) => {
  271. feature.set("icon", "point");
  272. this.kmap.polygonStyle(feature);
  273. mapData.isPointHide = feature;
  274. });
  275. mapData.selectPointArr = [];
  276. }
  277. //选中高亮样式
  278. //选中点位方法
  279. selectPonitFun(map,evt){
  280. let that = this
  281. map.forEachFeatureAtPixel(evt.pixel, function (f, layer) {
  282. let d = 0.0002
  283. let buff = bboxToFeature(evt.pixel[0] - d,evt.pixel[1] - d, evt.pixel[0]+ d, evt.pixel[1] + d)
  284. if (
  285. layer instanceof VectorLayer &&
  286. (
  287. layer.get("name") === "defaultPolygonLayer")
  288. ) {
  289. const fs = map.getFeaturesAtPixel(evt.pixel);
  290. let lonlat = map.getCoordinateFromPixel(evt.pixel);
  291. if (fs.length > 0) {
  292. const feature = fs[0];
  293. const geometry = feature.getGeometry();
  294. let coordinates = geometry.getCoordinates()[0]; // 获取多边形的顶点坐标
  295. ElMessage.success("已选择该点位")
  296. let list
  297. // if(mapData.selectPointArr.length>0){
  298. // list = f.getGeometry().getCoordinates();
  299. // }else{
  300. // list = mapData.point.getGeometry().getCoordinates();
  301. // }
  302. // const arr = list[0][0].find(subArray => subArray.includes(coordinates))
  303. // that.selectPointLayer.source.clear();
  304. // let point = new Feature(new Point(arr));
  305. // that.selectPointLayer.addFeature(point);
  306. if(mapData.selectPointArr.length>0){
  307. list = f.getGeometry().getCoordinates();
  308. }else{
  309. list = mapData.point.getGeometry().getCoordinates();
  310. }
  311. coordinates = list[0][0]
  312. let arr = []
  313. let i = 0;let curDistance = 0
  314. for(let subArray of coordinates){
  315. let from = turf.point(subArray);
  316. let to = turf.point(lonlat);
  317. let options = { units: "miles" };
  318. let distance = turf.distance(from, to, options);
  319. if(distance < 0.1){
  320. if(curDistance == 0){
  321. arr = subArray
  322. curDistance = distance
  323. mapData.pointIndex = i
  324. }else if(curDistance > distance){
  325. arr = subArray
  326. curDistance = distance
  327. mapData.pointIndex = i
  328. }
  329. }
  330. i++
  331. }
  332. that.selectPointLayer.refresh();
  333. let point = new Feature(new Point(arr));
  334. that.selectPointLayer.addFeature(point);
  335. mapData.selectPoint = coordinates
  336. }
  337. }
  338. });
  339. }
  340. // 地图点击事件
  341. addMapSingerClick() {
  342. let that = this;
  343. that.kmap.on("singleclick", (evt) => {
  344. if(mapData.curPointData.id && !mapData.disabledForm && mapData.selectPointArr.length===1){
  345. that.selectPonitFun(that.kmap.map,evt)
  346. return;
  347. }
  348. if(!mapData.curPointData.id && mapData.isEdit){
  349. that.selectPonitFun(that.kmap.map,evt)
  350. return;
  351. }
  352. //判断是否是导入的数据
  353. if(that.store.state.authentic.isEditStatus){
  354. that.selectPonitFun(that.kmap.map,evt)
  355. return;
  356. }
  357. let num = 0;
  358. that.kmap.map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
  359. // 点击的图层是否是VectorLayer
  360. if (
  361. layer instanceof VectorLayer &&
  362. (layer.get("name") === "clickPointLayer" ||
  363. layer.get("name") === "defaultPolygonLayer")
  364. ) {
  365. // 每次点击,只走一遍该方法
  366. num = num + 1;
  367. if (num === 1) {
  368. that.getSelectPointArr(feature.get("id"));
  369. that.kmap.endDraw();
  370. }
  371. }
  372. });
  373. });
  374. }
  375. clearSelectPoint(){
  376. this.selectPointLayer.source.clear();
  377. }
  378. setPoint(name) {
  379. const arr = mapData.selectPointArr.filter(
  380. (item) => item.values_.icon === "point-act"
  381. );
  382. if (arr.length > 0) {
  383. mapData.point = arr[0];
  384. mapData.point.set("icon", name);
  385. mapData.isPointHide.set("icon", name);
  386. mapData.point.set("iconBg", "name-bg");
  387. }
  388. if (arr.length === 1) {
  389. mapData.selectPointArr = [];
  390. }
  391. }
  392. //添加地块
  393. setAreaGeometry(geometryArr) {
  394. let that = this;
  395. let res = []
  396. geometryArr.map((item) => {
  397. item.icon = "point";
  398. item.iconHide = "false";
  399. res.push(that.kmap.setLayerWkt(item.featureWkt, item));
  400. });
  401. return res
  402. }
  403. deletePointFun(point,callback){
  404. const coordinates = point.getGeometry().getCoordinates();
  405. let array = coordinates[0][0]
  406. // 如果点存在,则删除它
  407. if (mapData.pointIndex > -1) {
  408. array.splice(mapData.pointIndex, 1); // 删除点
  409. // 更新多边形的坐标
  410. point.getGeometry().setCoordinates(coordinates); // 更新几何形状
  411. mapData.pointIndex = -1
  412. }
  413. this.clearSelectPoint()
  414. callback && callback(mapData.pointIndex)
  415. }
  416. // 移除点的功能
  417. removePoint(callback) {
  418. // 获取多边形的所有坐标
  419. const features = this.kmap.getLayerFeatures()
  420. if(mapData.selectPointArr.length>0){
  421. features.forEach(item =>{
  422. if(item.get("id")===mapData.selectPointArr[0].get("id")){
  423. this.deletePointFun(item,callback)
  424. }
  425. })
  426. }else{
  427. this.deletePointFun(mapData.point,callback)
  428. }
  429. }
  430. // 获取所有选中点位
  431. getSelectPointArr(id) {
  432. const arr = [];
  433. this.clickPointLayer.source.forEachFeature((feature) => {
  434. if (feature.get("id") === id) {
  435. // 修改当前点位高亮
  436. const icon = feature.get("icon") === "point" ? "point-act" : "point";
  437. const iconBg =
  438. feature.get("iconBg") === "name-bg" ? "name-act-bg" : "name-bg";
  439. feature.set("icon", icon);
  440. feature.set("iconBg", iconBg);
  441. mapData.point = feature;
  442. mapData.curPointData = feature.values_;
  443. }
  444. if (feature.get("icon") === "point-act") {
  445. arr.push(feature);
  446. }
  447. });
  448. const points = this.kmap.getLayerFeatures();
  449. points.forEach((feature) => {
  450. if (feature.get("id") === id) {
  451. const icon = feature.get("icon") === "point" ? "point-act" : "point";
  452. feature.set("icon", icon);
  453. this.kmap.polygonStyle(feature);
  454. mapData.isPointHide = feature;
  455. }
  456. });
  457. mapData.selectPointArr = arr;
  458. }
  459. hidePoint() {
  460. const feature = mapData.isPointHide;
  461. feature.set("iconHide", "true");
  462. this.kmap.polygonStyle(feature);
  463. }
  464. clearLayer() {
  465. this.clickPointLayer.source.clear();
  466. this.kmap.polygonLayer.source.clear();
  467. }
  468. addLayer() {
  469. this.kmap.addLayer(this.kmap.polygonLayer.layer);
  470. this.kmap.addLayer(this.clickPointLayer.layer);
  471. }
  472. //获取地块信息
  473. getAreaGeometry(type) {
  474. let features = null
  475. if(type==='add') {
  476. features = [mapData.point]
  477. }else if(type==='upload'){
  478. features = this.kmap.getLayerFeatures()
  479. }else{
  480. if(mapData.curPointData.id){
  481. features = [this.kmap.getFeatureById(mapData.curPointData.id)];
  482. }else{
  483. features = [mapData.point]
  484. }
  485. }
  486. let geometryArr = [];
  487. let area = 0;
  488. // 获取图层上的Polygon,转成geoJson用于回显
  489. features.forEach((item) => {
  490. geometryArr.push({ featureWkt: new WKT().writeFeature(item) });
  491. let geom = item.getGeometry().clone();
  492. geom.transform(proj.get("EPSG:4326"), proj.get("EPSG:38572"));
  493. let areaItem = getArea(geom);
  494. area = (areaItem + areaItem / 2) / 1000;
  495. });
  496. return { geometryArr, area: area.toFixed(2) };
  497. }
  498. /**
  499. address
  500. farmName
  501. masterName
  502. masterTel
  503. speciesTypeName
  504. ""
  505. * @param form
  506. */
  507. search(form){
  508. const points = this.kmap.getLayerFeatures();
  509. let arr = []
  510. let geomWkt = []
  511. points.forEach((feature) => {
  512. let condition = []
  513. if(form.address != ''){
  514. condition.push(feature.get("address").includes(form.address))
  515. }
  516. if(form.farmName != ''){
  517. const text = feature.get("farmName")
  518. if(text!==form.farmName) return
  519. condition.push(feature.get("farmName").includes(form.farmName))
  520. }
  521. if(form.masterName != ''){
  522. const text = feature.get("masterName")
  523. if(text!==form.masterName) return
  524. condition.push(feature.get("masterName").includes(form.masterName))
  525. }
  526. if(form.masterTel != ''){
  527. const text = feature.get("masterTel")
  528. if(text!==form.masterTel) return
  529. condition.push(feature.get("masterTel").includes(form.masterTel))
  530. }
  531. if(form.speciesTypeName != ''){
  532. const text = feature.get("speciesTypeName")
  533. if(text!==form.speciesTypeName) return
  534. condition.push(feature.get("speciesTypeName").includes(form.speciesTypeName))
  535. }
  536. let b = false
  537. for(let item of condition){
  538. if(item){
  539. b = true
  540. }else{
  541. b = false
  542. break
  543. }
  544. }
  545. if(b){
  546. arr.push(feature.get("id"))
  547. geomWkt.push(new WKT().writeGeometry(feature.getGeometry()))
  548. }
  549. });
  550. this.allUnSelect()
  551. this.allSelect(arr)
  552. if(geomWkt.length>0){
  553. this.fit(geomWkt)
  554. }
  555. }
  556. }
  557. export default AuthenticMap;