/* * @Author: your name * @Date: 2022-01-11 13:45:12 * @LastEditTime: 2022-03-22 10:35:13 * @LastEditors: Please set LastEditors * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @FilePath: /test/hello-world/src/utils/mapClass.js */ import { pipeColor, svgUrl, svgAlarm } from "@/utils/mapClass/config.js"; export const svgUrl2 = { // 地图的设备 2: require("@/assets/images/cz-tyx.svg"), 3: require("@/assets/images/cz-fmj.svg"), 4: require("@/assets/images/cz-cz.svg"), 5: require("@/assets/images/cz-jk.svg"), 6: require("@/assets/images/cz-yh.svg"), 7: require("@/assets/image/zrxk.svg"), 8: require("@/assets/image/zcrq.svg"), //应急设备,应急处置 emergency/emergency 10: require("@/assets/image/yj-jydw.png"), 11: require("@/assets/image/yj-wz.png"), 12: require("@/assets/image/yj-cl.png"), 13: require("@/assets/image/yj-yy.png"), 15: require("@/assets/image/yj-xf.png"), 16: require("@/assets/image/yj-xj.png"), }; // 编辑类 // 在地图上新增的设备可以直接编辑, // 已经保存完成的设备需要点编辑才可以编辑 export class EditorMap { // 地图的对象实例 map = null; // 外部传进来的中心店 center = null; // 父vue的实例 vue = null; // 操作 新建,编辑,删除,编辑跟删除只对已经在图上的设备有效 默认值:0, 新建:1,编辑:2, 删除: 3。 // 新建的时候会把未保存的线条清空 control = 0; // 鼠标事件对象,用来将点跟线上图 mousetool = null; // 当前正在手动绘制的对象 nowMouseTarget = null; // 当线mousetool线被按下的时候的flag 当线被按下的时候为true,就不询问是否删除了 mosueToolPolineDownFlag = false; // 绘制marer的时候的配置,在绘制完挂载事件的时候需要使用 mouseToolMarkerOptions = null; // 绘制poline的时候的配置,在绘制完挂载事件的时候需要使用 mouseToolPolineOptions = null; // 存放所有的设备的数组集合,这是一个对象,对象里面是各种设备的数组 allDevice = {}; // 存放所有的管道 pipeArr = {}; // 报警设备的对象 alarmObj = {}; // 当前的infowindow的组件 infowindowComponent = null; // infowindow本身 infowindow = null; editorObject = { editorArr: [], tabAct: '', toolBoxShow: false, }; constructor(contaienr, config = {}, vue) { this.map = new AMap.Map(contaienr, { viewMode: "3D", center: [114.196007, 38.260288], layers: [AMap.createDefaultLayer()], // layers 字段为空或者不赋值将会自动创建默认底图。 zoom: 14, ...config, }); const { center } = config; this.center = center; this.vue = vue; this.init(); } init() { // 地图事件 this.mapEvent(); // // 手动点线上图准备,编辑模式 this.mouseAddDevice(); // this.mouseAddMarker(); // this.mouseAddPipeline(); // 地图边界 this.map.getCity((res) => { const city = res.district; this.mapBound(city); }, this.center); } mapBound(city) { var district = new AMap.DistrictSearch({ extensions: "all", // 返回行政区边界坐标等具体信息 level: "district", // 设置查询行政区级别为 区 }); district.search(city, (status, result) => { // 获取朝阳区的边界信息 var bounds = result.districtList[0].boundaries; var polygons = []; console.log("boundsboundsboundsboundsbounds", bounds); if (bounds) { for (var i = 0, l = bounds.length; i < l; i++) { //生成行政区划polygon // new AMap.Polygon({ // map: this.map, // strokeWeight: 2, // path: bounds[i], // fillOpacity: 1, // fillColor: "transparent", // strokeColor: "#09f", // }); new AMap.Polyline({ map: this.map, strokeWeight: 4, strokeColor: "#09f", path: bounds[i], }); // polygons.push(polygon); } } }); } // map的事件监听 mapEvent() { // this.map.on("click", () => { // // mousetool对象画出的对象的操作 // // 如果有手动绘制对象,要手动清楚一下,因为画线的时候不好清除旧线,这其实是用来清楚旧线的 // // 当画出来的线被mousedown,不删除,但是mouseToolPipeLineFlag要归位,在移出线的时候统一归位 // // 如果对象是marker,直接删除 // if (this.nowMouseTarget?.type == "AMap.Marker") { // //this.mouseToolDrawClear(); // } else { // // 当地图上已经画了线,并且没有点在线上,询问是否删除 // if (this.nowMouseTarget && !this.mosueToolPolineDownFlag) { // this.confirm("是否重新绘制管道", { type: "warning" }) // .then(() => { // // 删除原来的线 // this.mouseToolDrawClear(); // // 鼠标事件开启,并且赋值原来的属性,this.mouseToolMarkerOptions是开启绘制的时候记录的 // this.mousetool.polyline(this.mouseToolPolineOptions); // }) // .catch(() => {}); // } // } // }); this.map.on("moveend", () => { console.log("地图停止移动"); if (this.flag) { console.log("弹框"); this.flag = false; } }); window.panTo = () => { this.flag = true; this.map.panTo([116.428285, 39.886129]); }; } // 弹框工具 confirm(message, obj) { return this.vue.$confirm(message, obj); } // 改变操作状态 changeControl(num) { this.control = num; } // 点线编辑上图准备 mouseAddDevice() { this.map.plugin(["AMap.MouseTool"], () => { this.mousetool = new AMap.MouseTool(this.map); //this.map.addControl(new AMap.ToolBar({ position: 'LT', ruler: false, direction: false })); }); // 挂载绘制结束的事件 //this.mouseDrawEvent(); } // 点或者线上图结束后触发的事件 mouseDrawEvent() { this.mousetool.on("draw", (e) => { const target = e.obj; // console.log([target._position.lng, target._position.lat]); const { type: targetType } = target; // 当这个点是marker的时候 if (targetType == "AMap.Marker") { this.mouseToolMarkerEvent(target); } else { // 如果是线,挂上编辑 this.lineEditor(target); this.mousetool.close(); this.mouseToolPolineEvent(target); console.log(targetType, "当前对象是管道"); } this.nowMouseTarget = target; }); } // 绘制marker结束后,在marker身上添加的事件 mouseToolMarkerEvent(target) { // 由于画出来的marker点击会换位置,所以当移入的时候删除绘制事件,移出去在增加绘制事件 target.on("mouseover", (e) => { // 鼠标事件关闭 this.mousetool.close(false); }); target.on("mouseout", (e) => { // 这里不方便获取原来的属性,因为position不好解决,还是设置一个值吧 // 鼠标事件开启,并且赋值原来的属性,this.mouseToolMarkerOptions是开启绘制的时候记录的 this.mousetool.marker(this.mouseToolMarkerOptions); }); // 点 target.on("click", (e) => { // 弹框 }); } // 挂上线以及线的事件 lineEditor(line) { // line.editor && line.editor.close(); // 当前点击次数,1次为编辑,2次为弹框 line.editorNum = 0; line.editor = new AMap.PolyEditor(this.map, line); } // 绘制管道的时候,挂载的事件 mouseToolPolineEvent(target) { // 线按下的时候会变成编辑,mousetool事件会清空 移出线的时候 在把polyline事件加上 target.on("mouseover", (e) => { // 鼠标事件关闭 // this.mousetool.close(false); }); target.on("mouseout", (e) => { // 有时候按在线上移动地图,map点击事件中mosueToolPolineDownFlag无法归位,在这里归位 this.mosueToolPolineDownFlag = false; // 鼠标事件开启,并且赋值原来的属性,this.mouseToolMarkerOptions是开启绘制的时候记录的 // this.mousetool.polyline(this.mouseToolPolineOptions); }); // 线 target.on("mousedown", (e) => { const line = e.target; // mosueTool按下的flag,按在线上,不询问是否删除 this.mosueToolPolineDownFlag = true; // 按下的时候要关闭事件 this.mousetool.close(false); // 如果当前状态不是编辑,则进入编辑状态 if (line.editorNum < 1) { // 打开并且++ line.editor.open(); line.editorNum++; } else { // 这里就要弹框了 console.log(line.getPath()); } }); } // 设备点击上图开启 mouseAddMarker(markerObj = {}) { // 清空已经绘制完的对象 //this.mousetoolClose(true); // 记录一下配置项,在挂载点击的时候,需要使用 this.mouseToolMarkerOptions = { draggable: true, id: 'flag', icon: new AMap.Icon({ size: [60, 60], image: require("@/assets/image/fla01g.png"), imageSize: [60, 60], }), offset: new AMap.Pixel(-19,-42), }; this.mousetool.marker(this.mouseToolMarkerOptions); } // 管线点击上图开启 mouseAddPipeline(hz) { this.editorObject.tabAct = hz; //this.mousetoolClose(false); // 开始画线 this.mosuetoolPolineFlag = true; this.mouseToolPolineOptions = { strokeColor: '#3366FF', strokeOpacity: 1, strokeWeight: 6, strokeStyle: 'solid', }; this.mousetool.polyline(this.mouseToolPolineOptions); } //⚪圆 mouseAddCircle(hz) { this.editorObject.tabAct = hz; //this.mousetoolClose(false); // 开始画线 var c ={ strokeColor: '#FF33FF', strokeOpacity: 1, strokeWeight: 4, fillColor: '#1791fc', fillOpacity: 0.4, strokeStyle: 'solid', }; this.mousetool.circle(c); } //多边形 mouseAddPolygon(hz) { this.editorObject.tabAct = hz; //this.mousetoolClose(false); // 开始画线 this.mouseToolPolineOptions = { strokeColor: '#0dec66', strokeOpacity: 1, strokeWeight: 4, strokeOpacity: 1, fillColor: '#ee6a38', fillOpacity: 0.3, strokeStyle: 'solid', } this.mousetool.polygon(this.mouseToolPolineOptions); } mouseAddRule() { //测距 this.mousetool.rule({ startMarkerOptions: { icon: new AMap.Icon({ size: new AMap.Size(128, 128), imageSize: new AMap.Size(50, 50), image: 'images/qi.png', }), offset: new AMap.Pixel(-25, -50), }, endMarkerOptions: { icon: new AMap.Icon({ size: new AMap.Size(128, 128), imageSize: new AMap.Size(40, 40), image: 'images/zhong.png', }), offset: new AMap.Pixel(-20, -40), }, midMarkerOptions: { icon: new AMap.Icon({ size: new AMap.Size(128, 128), imageSize: new AMap.Size(40, 40), image: 'images/jing.png', }), offset: new AMap.Pixel(-20, -40), }, lineOptions: { strokeStyle: 'solid', strokeColor: '#FF33FF', strokeOpacity: 1, strokeWeight: 3, }, }); } mouseAddMeasureArea() { //面积 this.mousetool.measureArea({ strokeColor: '#80d8ff', fillColor: '#80d8ff', fillOpacity: 0.5, }); } // 手动清除map上绘制的对象 mouseToolDrawClear() { if (this.nowMouseTarget) { this.map.remove(this.nowMouseTarget); // 如果有editor,则关闭 this.nowMouseTarget.editor && this.nowMouseTarget.editor.close(); this.nowMouseTarget = null; } } //编辑图形 editOverlays() { this.mousetool.close(false); var type = this.editorObject.tabAct; let layobj = this.getAllDrawLays(); switch (type) { case 'Circle': if (layobj.CircleArr.length > 0) layobj.CircleArr.forEach((ele) => { let editor = new AMap.CircleEditor(this.map, ele); editor.open(); this.editorObject.editorArr.push(editor); }); break; case 'Polyline': if (layobj.PolylineArr.length > 0) layobj.PolylineArr.forEach((ele) => { let editor = new AMap.PolyEditor(this.map, ele); editor.open(); this.editorObject.editorArr.push(editor); }); break; case 'Polygon': if (layobj.PolygonArr.length > 0) layobj.PolygonArr.forEach((ele) => { let editor = new AMap.PolyEditor(this.map, ele); editor.open(); this.editorObject.editorArr.push(editor); }); break; } } getAllDrawLays() { let laysArr = this.map.getAllOverlays(), CircleArr = [], MarkerArr = [], PolylineArr = [], PolygonArr = []; laysArr.forEach((ele) => { if (ele.CLASS_NAME == 'Overlay.Circle') CircleArr.push(ele); if (ele.CLASS_NAME == 'Overlay.Polygon') PolygonArr.push(ele); if (ele.CLASS_NAME == 'Overlay.Polyline') PolylineArr.push(ele); if (ele.CLASS_NAME == 'Overlay.Marker' && ele.getzIndex() == 9999) { MarkerArr.push(ele); } }); let allDrawLays = [...CircleArr, ...MarkerArr, ...PolylineArr, ...PolygonArr]; return { allDrawLays, CircleArr, MarkerArr, PolylineArr, PolygonArr, }; } //结束编辑 endEditOverlays() { console.log(this.editorObject.editorArr.length) if (this.editorObject.editorArr.length > 0) { this.editorObject.editorArr.forEach((ele) => { ele.close(); }); } } //结束绘制 endOverlays() { this.mousetool.close(false); } //删除图形 delOverlays() { let layobj = this.getAllDrawLays(), html = '', type = this.editorObject.tabAct, len = layobj[type + 'Arr'] ? layobj[type + 'Arr'].length : ''; // window.delRadioLays = function (num) { // this.map.remove(layobj[type + 'Arr'][num - 1]); // }; if (len > 0) this.alertFun(len, type, layobj); } delRadioLays(num){ console.log(num); //this.map.remove(layobj[this.editorObject.tabAct + 'Arr'][num - 1]); } alertFun(len, type, layobj) { let stype = '', html = ''; switch (type) { case 'Circle': stype = '圆形'; break; case 'Polyline': stype = '线段'; break; case 'Polygon': stype = '多边形'; break; } for (let i = 0; i < len; i++) { let lena = i + 1; html += '<input name="in" type="radio" onClick="delRadioLays('+lena+')"/>第'+lena+'个'+stype; } document.getElementById("delTu").innerHTML=html; // layLayer.open({ // content: html, // }); } // 关闭点击上图事件 true清除之前绘制的图像,false 仅关闭上图事件 mousetoolClose(boolean) { // 清空地图上的绘制对象的同时,也要清楚这个nowMouseTarget控制对象 if (this.nowMouseTarget) { // 如果有editor,则关闭 this.nowMouseTarget.editor && this.nowMouseTarget.editor.close(); this.nowMouseTarget = null; } this.mousetool.close(boolean); } /** * * * * * * * 地图上add设备 * * * @description: * @param {*} deviceData marker的数据 * @param {*} compontent marker点击弹出的infowindow的组件 * @return {*} */ addDevice(deviceData, compontent) { const { longitude: lng, latitude: lat, iconType } = deviceData; const icon = svgUrl2[iconType]; console.log("icon", icon); let device = this.createMarker({ map: this.map, anchor: "bottom-center", icon, position: [lng, lat], extData: deviceData, // label:{ // content:123, // direction:"top", // } }); // device.hide(); // 如果没有有这个公司的数组,就创建,有就直接push if (!Array.isArray(this.allDevice[iconType])) { this.allDevice[iconType] = []; } this.allDevice[iconType].push(device); // 设备的事件函数 this.deviceEvent(device, compontent); } deviceEvent(device, compontent) { device.on("click", (e) => { const target = e.target; // 如果control==0就是默认值,没有使用123功能,就显示infowindow if (this.control == 0) { this.markerClick(target, compontent); } else if (this.control == 2) { // 2是已经上图的设备拥有的编辑功能 } else if (this.control == 3) { // 3是删除操作 } }); device.on("mouseover", (e) => { const target = e.target; const data = target.getExtData(); console.log(data); const name = data.nickName || data.deviceName || data.videoName || data.stationName || data.time; target.setLabel({ content: name, direction: "top" }); }); device.on("mouseout", (e) => { const target = e.target; const data = target.getExtData(); target.setLabel({ content: "" }); }); } /** 点击marker出现infowindow * @description: * @param {*} target 点击的对象 * @param {*} compontent marker点击弹出的infowindow的组件 * @return {*} */ markerClick(target, compontent) { const deviceExtData = target.getExtData(); const { longitude: lng, latitude: lat } = deviceExtData; // 创建一个可以控制的组件,将其dom插入infowindow this.infowindowComponent = this.createInfowindowDom( this.vue, this, deviceExtData, compontent ); // 没恩么用,控制台测试的时候用着玩的 window.func = () => { const { longitude: lng, latitude: lat } = target.getExtData(); const cd = { id: 1, name: "9", lng, lat, }; this.infowindowComponentChange(cd); target.setExtData(cd); }; this.infowindow = new AMap.InfoWindow({ isCustom: true, content: this.infowindowComponent.$el, position: [lng, lat], // anchor: "top-left", // offset: [20, -45], anchor: "middle-left", offset: [20, -10], }); this.infowindow.open(this.map); } // 创建要加入到infowindow里的 createInfowindowDom(vueRoot, mapClass, deviceData, compontent) { const Component = this.vue.$Vue.extend(compontent, {}); return new Component({ data() { return { // 当前vue实例 vueRoot, // 自己写的map类 mapClass, // 数据 deviceData, }; }, }).$mount(); } // 当前显示的infowindow内部的数据发生变化,一般在socket传回数据的时候使用 infowindowComponentChange(data) { this.infowindowComponent.deviceData = data; } // 创建marker createMarker(MarkerOptions) { return new AMap.Marker(MarkerOptions); } // 地图上add管道 addPipeLine(objData, component) { const { path, pipePressure, iconType } = objData; // 根据压力获取颜色 const color = pipeColor[pipePressure + 1]; const pipe = this.createPipeLine({ path: eval(path), strokeWeight: 4, strokeColor: color, extData: objData, cursor: "pointer", }); this.map.add(pipe); // pipe.hide(); if (!Array.isArray(this.pipeArr[iconType])) { this.pipeArr[iconType] = []; } this.pipeArr[iconType].push(pipe); // console.log(this.pipeArr); // this.map.panTo([path[0][0], path[0][1]]); this.pipeEvent(pipe, component); } createPipeLine(pipeLineOptions) { return new AMap.Polyline(pipeLineOptions); } pipeEvent(pipe, compontent) { pipe.on("mouseover", (e) => { const target = e.target; // 获取当前颜色 const options = target.getOptions(); options.strokeColor = "blue"; target.setOptions(options); }); pipe.on("mouseout", (e) => { const target = e.target; // 根据管道压力获取颜色 const { pipePressure } = target.getExtData(); const color = pipeColor[pipePressure + 1]; // 获取当前颜色 const options = target.getOptions(); options.strokeColor = color; target.setOptions(options); }); pipe.on("click", (e) => { const target = e.target; target.lnglat = e.lnglat; // 如果control==0就是默认值,没有使用123功能,就显示infowindow if (this.control == 0) { this.pipeClick(target, compontent); } else if (this.control == 2) { // 2是已经上图的设备拥有的编辑功能 } else if (this.control == 3) { // 3是删除操作 } }); } pipeClick(target, compontent) { const deviceExtData = target.getExtData(); const { lng, lat } = target.lnglat; // 创建一个可以控制的组件,将其dom插入infowindow this.infowindowComponent = this.createInfowindowDom( this.vue, this, deviceExtData, compontent ); // 没恩么用,控制台测试的时候用着玩的 // window.func = () => { // const { lng, lat } = target.getExtData(); // const cd = { // id: 1, // name: "9", // lng, // lat, // }; // this.infowindowComponentChange(cd); // target.setExtData(cd); // }; this.infowindow = new AMap.InfoWindow({ isCustom: true, content: this.infowindowComponent.$el, position: [lng, lat], // anchor: "top-left", // offset: [20, -15], anchor: "middle-left", offset: [20, 0], }); this.infowindow.open(this.map); } infowindowClose() { if (!this.infowindow) return; this.infowindow.close(); } // 设备以及公司过滤 allfilter(companyArr, typeArr) { for (let pipeItem in this.pipeArr) { this.pipeArr[pipeItem].forEach((pipe) => { const data = pipe.getExtData(); if (companyArr.indexOf(data.companyType + "") >= 0) { pipe.show(); } else { pipe.hide(); } }); } for (let deviceItem in this.allDevice) { this.allDevice[deviceItem].forEach((device) => { const data = device.getExtData(); // 设备过滤受到bigwindow页面的的两种制约,companyArr, typeArr 两个数组制约显示隐藏 // 燃气没有公司,所以没有device.companyType不收到公司的控制 const companyHas = companyArr.indexOf(data.companyType + "") >= 0; // 设备存在 受到设备按钮限制 const deviceHas = typeArr.indexOf(+data.iconType) >= 0; // 如果是燃气公司的话,不受按钮限制 const enterprise = data.iconType == 7 || data.iconType == 8; // 必须设备存在数组里,才会显示设备 !data.companyType代表用户不受公司制约 if (enterprise || (deviceHas && (companyHas || !data.companyType))) { device.show(); } else { device.hide(); } }); } } setZoomAndCenter(longitude,latitude){ this.map.setZoomAndCenter(14.5, [longitude*1+0.02,latitude]); } // 普通调用方法 // 设备报警 deviceAlarm(obj) { // 设备的类型 const { iconType } = obj; const publicId = obj.userId || obj.deviceId; // 找到这个设备所属的空间 const device = this.allDevice[iconType].filter( (item) => (item.getExtData().userId || item.getExtData().deviceId) == publicId )[0]; // 更改的icon const icon = svgAlarm[iconType]; device.setIcon(icon); device.setzIndex(13); // 将旧的值缓存一下 // device.oldData = device.getExtData(); // device.setExtData(obj); // 可能出现infoWindow数据变化 this.alarmInfowindowChange(obj); if (!this.alarmObj[iconType]) { this.alarmObj[iconType] = []; } const ind = this.alarmObj[iconType].indexOf(publicId); if (ind < 0) { this.alarmObj[iconType].push(publicId); } } // 报警时候,可能发生infowindowComponent存在,也要变化 alarmInfowindowChange(obj) { if (!this.infowindowComponent) return; // 如果infowindow是打开的,就改变里面的数据 必须是 调压箱2 阀门3 用户6 才会发生变化电话 const infowindowDeviceType = [2, 3, 6].includes( this.infowindowComponent.deviceData.iconType ); // 如果存在userId就用userId,如果存在deviceId就用deviceId const infowindowDeviceId = this.infowindowComponent.deviceData.userId || this.infowindowComponent.deviceData.deviceId; // 如果存在userId就用userId,如果存在deviceId就用deviceId const objId = obj.userId || obj.deviceId; // 如果两个值匹配,才可以改变infowindow身上的组件 const infowindowComponentHas = infowindowDeviceId == objId; if ( this.infowindowComponent && infowindowDeviceType && infowindowComponentHas ) { // this.infowindowComponentChange(obj); if (this.infowindowComponent.http) { this.infowindowComponent.myHttp(); } } } //如果传过来的报警设备中,有不在deviceAlarm中,就是恢复的设备恢复 relieveAlarm(alarmObj) { // 把报警数组改变结构,如果有userId就是用户,如果有deviceId就是其他设备 const httpObj = {}; alarmObj.forEach((item) => { const publicId = item.userId || item.deviceId; if (!Array.isArray(httpObj[item.iconType])) { httpObj[item.iconType] = []; } httpObj[item.iconType].push(publicId); }); // 循环现有报警设备 for (let iconType in this.alarmObj) { const arr = this.alarmObj[iconType]; // 循环现有报警设备 for (let i = 0; i < arr.length; i++) { // 看看现有报警设备中有没有不在 报警数组中的值,有就恢复可能是userId,也可能是deviceId const publicId = arr[i]; // 看看接口传来的数据中还有没有这些Id,如果没有了,就是修好了 const hasId = httpObj[iconType]?.includes(publicId); // 如果已经不在报警数组中,就要去大数组中找他,利用userId // 如果id不存在了,说明不报警了 if (!hasId) { // 过滤出来这个要恢复的设备 const device = this.allDevice[iconType].filter( (item) => (item.getExtData().userId || item.getExtData().deviceId) == publicId )[0]; // 恢复 const icon = svgUrl[iconType]; device.setIcon(icon); // 赋值 // const deviceData = { ...device.oldData }; // device.setExtData(deviceData); // device.oldData = null; // 如果infowindow是打开的 this.alarmInfowindowChange(device.getExtData()); // 在arr中删掉 arr.splice(i, 1); // 由于删掉了当前,所以要--恢复位置 i--; } } } } // ws协议方法 wsAlarm(obj) { const { iconType, userId, userStatus } = obj; const decice = this.allDevice[iconType].filter( (item) => item.getExtData().userId == userId )[0]; let icon = null; // 2报警,1恢复 if (userStatus == 2) { icon = svgAlarm[iconType]; device.oldData = device.getExtData(); device.setExtData(obj); } else if (userStatus == 1) { icon = svgUrl[iconType]; const oldData = device.oldData; device.setExtData(oldData); device.oldData = null; } decice.setIcon(icon); } // 卫星图切换 satellite = null; changeMap(bool) { // 卫星, if (!bool) { if (this.satellite) return; this.satellite = new AMap.TileLayer.Satellite(); this.map.addLayer(this.satellite); } else { if (this.satellite) { this.map.removeLayer(this.satellite); this.satellite = null; } } } // 轨迹回放 /** * @description: * @param {*} vehicleId 设备id * @param {*} path 轨迹回访率丼 * @return {*} */ backTrack(vehicleId, path, times,component) { this.infowindowClose(); AMap.plugin("AMap.MoveAnimation", () => { let marker = this.allDevice[9].filter( (item) => item.getExtData().vehicleId == vehicleId )[0]; // 绘制轨迹 marker.polyline = new AMap.Polyline({ map: this.map, path, showDir: true, strokeColor: "#28F", //线颜色 // strokeOpacity: 1, //线透明度 strokeWeight: 6, //线宽 // strokeStyle: "solid" //线样式 }); marker.passedPolyline = new AMap.Polyline({ map: this.map, strokeColor: "#AF5", //线颜色 strokeWeight: 6, //线宽 }); marker.on("moving", (e) => { marker.passedPolyline.setPath(e.passedPath); // this.map.setCenter(e.target.getPosition(), true); // console.log(getPosition()); }); // 每个path的点 // marker.pointArr = []; // carTarget //点击的时候,先传进来一个点 const carPathData = { ...marker.getExtData(), time: times[0] }; carPathData.iconType = 14; this.addDevice(carPathData,component); // marker.pointArr.push(point); marker.on("moveend", (e) => { // this.addDevice(carPathData,carBackComponent); // 如果不是最后一个点,就创建一个新的worderpoint,如果是就不创建,并且把自身删除 let z = { longitude: e.pos[0], latitude: e.pos[1], iconType: 14, time: times[e.index], }; // if (e.index == path.length - 1) { // point = this.addDevice(z, null); // } else { this.addDevice(z,component); // workPoint.infoWindow.open(map,e.passedPos); // } console.log("定点", e); }); marker.moveAlong(path, { // 每一段的时长 duration: 8000, //可根据实际采集时间间隔设置 // JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置 autoRotation: true, }); }); } clearbackTrack(vehicleId) { // let marker = this.allDevice[9].filter( // (item) => item.getExtData().vehicleId == vehicleId // )[0]; this.allDevice["9"]?.forEach((item) => { if (item) { // 停止运动 item.stopMove(); // 删除每个点 console.log(item.pointArr); if (item.polyline) { this.map.remove(item.polyline); } if (item.passedPolyline) { this.map.remove(item.passedPolyline); } this.map.remove(item); } }); // 最后把数组清空 this.allDevice["9"] = []; // 把car的路径点也清空 this.allDevice["14"]?.forEach((iten) => { this.map.remove(iten); }); this.allDevice["14"] = []; this.infowindowClose(); } }