import emitter from "@/utils/eventBus.js"; export function MapUtil(map) { let _that = this; _that.mMap = map; //地图对象 _that._self = {}; //图层对象 _that._CustomDraw = null; //自定义绘图 _that.polygonGeo = null; //边界 _that.idsBox = {}; //存放id的容器(需要某个标记单个删除的时候存储) _that.isCheck = false; /** * 设置地图中心点以 * @param {*} location 中心坐标 [jd,wd] * @param {*} zoomLevel 层级 10 */ MapUtil.prototype.setMapCenter = (location, zoomLevel) => { map.mapboxGLMap.setCenter(location); map.mapboxGLMap.setZoom(zoomLevel); }; /** * 撒点.鼠标滑动展示内容 * @param {*} coords 坐标 geojson * @param {*} icon 图标 * @param {*} flag 标识 */ MapUtil.prototype.showPoint = (res) => { let { coords, icon, flag, iconH } = res; if (!coords) return; if (!_that._self[flag]) _that._self[flag] = []; let pointList = coords.map((it, index) => { let text = it.kfdMc || it.wzBc || it.gajgmc || it.xm || it.jczmc; let obj = { position: [it.jd, it.wd], userData: { deviceSn: "text" + index, area: text }, id: it.id, text: text, data: it }; if (it.jd && it.wd) return obj; }); const point = map.createdPoint(pointList, { image: icon, //对应上面的图片名称 scale: 1, highlightImage: iconH ? iconH : icon, //高亮图标 labelOption: { pixelOffset: [0, -2], allShow: false, fontSize: "18px", fontWeight: 600, fontColor: "#000000" } }); _that._self[flag].push(point); point.addEventListener("click", (val) => { let data = val.data ? JSON.parse(val.data) : {}; // point.highlight(data.id) //高亮展示选中的点位 _that.openInfoDetail(flag, [data]); //点击打开详情 }); }; /** * 撒点 * @param {*} coords 坐标 geojson * @param {*} icon 图标 * @param {*} flag 标识 * @param {*} showTitle 是否展示标题 */ MapUtil.prototype.makerSki = (res) => { let { coords, icon, flag, showTitle } = res; if (!coords) return; if (!_that._self[flag]) _that._self[flag] = []; //存储地图标识的容器 if (!_that.idsBox[flag]) _that.idsBox[flag] = []; //存储id的容器 if (flag == "rx") { _that.handlePolice(coords, icon, flag, showTitle); } else { coords.forEach((item) => { let el = document.createElement("img"); el.src = item.icon || icon; el.style.width = flag == "kfd" ? "32px" : "25px"; if (flag.includes("jczMap_")) el.style.width = "45px"; if (showTitle) _that.makerShowTitle(item, [item.jd, item.wd], flag); //展示标题 const marker = map.Marker(el, [item.jd, item.wd], { anchor: "bottom", offset: [0, 0] }); el.addEventListener("click", () => { _that.openInfoDetail(flag, item); //点击打开详情 }); _that._self[flag].push(marker); _that.idsBox[flag].push(item.id); }); } }; // 警力处理展示 MapUtil.prototype.handlePolice = (coords, icon, flag, showTitle) => { // 01-大型车辆-DXCL, 02-小型车辆=XXCL,03-摩托车-MTC,04-其他车辆-QTCL,05-重型车辆-ZXCL,06-风控车-FKC,07-巡逻车-XLC,08-装甲车-ZJC coords.forEach((item) => { let el = document.createElement("img"); let jcIcon = require(`@/assets/point/police-car-bx.png`); switch (item.lx) { case "01": // 特警 jcIcon = require(`@/assets/point/specialPolice.png`); break; case "02": // 交警 jcIcon = require(`@/assets/point/trafficPolice.png`); break; case "03": // 派出所民警 jcIcon = require(`@/assets/point/peoplePolice.png`); break; default: // 默认图标 jcIcon = require(`@/assets/point/specialPolice.png`); break; } if (item.zzlx == 1) jcIcon = require(`@/assets/point/by.png`); //便衣 let cllxList = item.cllx ? item.cllx.split(",") : []; if ( (cllxList.includes("03") || cllxList.includes("04")) && item.lx == "02" ) jcIcon = require(`@/assets/point/xljmtc.png`); //交警-摩托车 if ( (cllxList.includes("03") || cllxList.includes("04")) && item.lx == "01" ) jcIcon = require(`@/assets/point/tjc.png`); //特警-摩托车 if (cllxList.includes("08") || cllxList.includes("06")) jcIcon = require(`@/assets/point/zjc.png`); //装甲车 el.src = jcIcon; let isShoeCar = cllxList.includes("03") || cllxList.includes("08"); //车辆类型 // el.style.width = isShoeCar ? '38px':"25px"; //图片大小 // if(cllxList.includes('08')) el.style.height = '40px' if (showTitle) _that.makerShowTitle(item, [item.jd, item.wd], flag); //展示标题 _that.shouIcon(item, [item.jd, item.wd]); // 展示装备图标 let offset = isShoeCar ? [-10, 0] : [0, 0]; if (cllxList.includes("08")) offset = [-12, -10]; const marker = map.Marker(el, [item.jd, item.wd], { anchor: "bottom", offset: offset }); el.addEventListener("click", () => { _that.openInfoDetail(flag, item); //点击打开详情 }); _that._self[flag].push(marker); _that.idsBox[flag].push(item.id); }); }; // 信息框展示 MapUtil.prototype.makerShowTitle = (item, points, flag, text) => { let T = flag == "rx" ? "rxTitle" : "Title"; let flagT = flag + T; if (!_that._self[flagT]) _that._self[flagT] = []; // 展示名字 let textTitle = item.jzMc ? item.jzMc : item.fzrXm + "警组"; if (flag == "sbwz_car" || flag == "sbwz_sb" || flag == "sbwz_zfjly") textTitle = item.sbmc; if (flag == "gapText") textTitle = text; // 设置样式 const el = document.createElement("div"); el.className = "makerTitle"; if (flag == "sbwz_car" || flag == "sbwz_sb" || flag == "sbwz_zfjly") el.className = "makerTitlezb"; if (flag == "rx") { if (item.xfzt == "0") el.classList.add("makerTitleLine"); else if (item.xfzt == "1") el.classList.add("makerTitlecj"); else el.classList.add("makerTitleUnLine"); } if (flag == "gapText") el.className = "makerTitleGapText"; // 渲染 el.innerHTML = textTitle; const marker = map.Marker(el, points, { anchor: "bottom", offset: [0, -50] }); _that._self[flagT].push(marker); }; /** * 装备图标 * @param {点位数据} data * @param {点} point */ MapUtil.prototype.shouIcon = (data, point) => { if (!_that._self.gpsZb) _that._self.gpsZb = []; var qxIcon = require(`@/assets/point/qx.png`); //qixie var zfjlyIcon = require(`@/assets/point/interphone.png`); // 对讲机 var clIcon = require(`@/assets/point/car.png`); // 车辆 let jyqx = typeof data.jyqx == "string" ? JSON.parse(data.jyqx) : data.jyqx ? data.jyqx : []; let txzb = typeof data.txzb == "string" ? JSON.parse(data.txzb) : data.txzb ? data.txzb : []; let pbcl = typeof data.pbcl == "string" ? JSON.parse(data.pbcl) : data.pbcl ? data.pbcl : []; let list = []; let cl = pbcl && pbcl.length > 0 ? true : false; // 车辆 let zb = txzb && txzb.length > 0 ? true : false; // 智能装备 let qx = jyqx && jyqx.length > 0 ? true : false; // 警用器械 if (zb) { let el = document.createElement("img"); el.style.width = "15px"; el.src = zfjlyIcon; const makerZb = map.Marker(el, point, { anchor: "bottom", offset: [20, -26] }); list.push(makerZb); } if (qx) { let elqx = document.createElement("img"); elqx.style.width = "15px"; elqx.src = qxIcon; const makerQx = map.Marker(elqx, point, { anchor: "bottom", offset: [20, -10] }); list.push(makerQx); } if (cl) { let elcl = document.createElement("img"); elcl.style.width = "20px"; elcl.src = clIcon; const makerCl = map.Marker(elcl, point, { anchor: "bottom", offset: [20, 2] }); list.push(makerCl); } _that._self.gpsZb[data.id] = list; }; // 自定义展示 MapUtil.prototype.zdySquire = (obj) => { let { points, flag, distance } = obj; if (!_that._self[flag]) _that._self[flag] = []; let textTitle = "距离:" + distance; // 展示名字 const el = document.createElement("div"); el.className = "makerTitle"; if (flag == "distance") el.className = "makerTitleDistance"; // 设置样式 el.innerHTML = textTitle; const marker = map.Marker(el, points, { anchor: "bottom", offset: [0, -76] }); // 渲染 _that._self[flag].push(marker); }; /**扩散圆 * @param coords:[jd,wd] */ MapUtil.prototype.diffusionCircle = (obj) => { let { coords, flag, isClear } = obj; if (!_that._self[flag]) _that._self[flag] = {}; if (isClear) _that._self[flag].destroy(); //destroy销毁,show(false) 移除 let data = [{ position: coords }]; _that._self[flag] = map.DiffuseCircle(data, { radius: 10, color: "rgba(81,217,254)", //扫描扇形的颜色,必须是十六进制或者rgb duration: 30, //圆环与上一个圆环出现的间隔时间。配合speed参数可以调整圆圈的数量 speed: 4 //圆环移动速度 }); }; /** * 聚合撒点 * @param {*} coords 点位数据 geojson lng lat * @param {*} icon 点位图 */ MapUtil.prototype.aggregateScatteringPoint = (obj) => { let { coords, icon, flag, isclear, scale, fontColor } = obj; let points = coords.map((item) => { item.lng = item.jd; item.lat = item.wd; return item; }); if (!_that._self[flag]) _that._self[flag] = []; if (isclear) _that.removeElement(flag); //移除聚合 let maker = map.clusterLayer(points, { id: flag, size: 18, pixelRange: 60, // gradient:{'1':'#00BFFF','10':'#008000', '100':'#FFA500', '1000':'#FF0000'},//可以自定义图片,把颜色换成图片地址 gradient: { 1: icon, 10: icon, 100: icon, 1000: icon }, //可以自定义图片,把颜色换成图片地址 fontSize: 14, fontColor: fontColor ? fontColor : "#001022", style: "custom", // spiral(螺旋形状),circle(圆圈),custom(自定义) image: icon, scale: scale ? scale : 1, // highlightImage:icon, fontFamily: ["Microsoft YaHei"] }); _that._self[flag].push(maker); // 聚合的点击一个 maker.addEventListener("click", (val) => { _that.openInfoDetail(flag, [val]); //点击打开详情 }); // 聚合的多个 maker.addEventListener("clusterClick", (val) => { _that.openInfoDetail(flag, val); //点击打开详情 }); }; /** * 热力图 * @param {*} coords 数组 */ MapUtil.prototype.showHeatDrawing = (res) => { let { coords, flag, isclear, color } = res; if (!_that._self[flag]) _that._self[flag] = []; if (isclear) _that.removeElement(flag); //清除热力 let data = { type: "FeatureCollection", features: [] }; for (let index = 0; index < coords.length; index++) { const item = coords[index]; let jd = item.lng || item.jd; let wd = item.lat || item.wd; let mag = item.count <= 10 ? 1.4 : item.count > 10 && item.count <= 50 ? 1.6 : 1.9; let obj = { properties: { mag }, type: "Feature", geometry: { type: "Point", coordinates: [jd, wd, 0.1] } }; data.features.push(obj); } let colors = { 0: "rgba(23,102,172,0)", 0.5: "rgb(209,229,240)", 1: "rgb(178,24,43)" }; if (color) colors = { 0: color[0], 0.5: color[1], 1: color[2] }; let heartmap = map.HeatMap(data, { colors }); _that._self[flag].push(heartmap); }; // 清除所有 MapUtil.prototype.removeAll = () => { for (let key in _that._self) { if (key != "rx" && key != "gpsZb" && !key.includes("rxTitle")) { let list = _that._self[key]; for (let i = 0; i < list.length; i++) { const el = list[i]; if (el && typeof el == "object") el.destroy(); //destory()销毁 , show(false) false:隐藏 true :展示 } _that._self[key] = []; } } }; /** * 删除图层要素 * @param {*} layer 唯一标识 */ MapUtil.prototype.removeElement = (layer) => { //警力装备 if (layer == "gpsZb") { for (let key in _that._self.gpsZb) { let item = _that._self.gpsZb[key]; if (item && item.length > 0) { for (let child in item) { item[child].destroy(); } _that._self.gpsZb[key] = []; } } } if (layer == "rx") _that.idsBox[layer] = []; // 其他图层 if (!_that._self[layer]) return false; if (layer !== "gpsZb") { for (let i = 0; i < _that._self[layer].length; i++) { const el = _that._self[layer][i]; el.destroy(); //destory()销毁 , show(false) false:隐藏 true :展示 } _that._self[layer] = []; // d带标题的撒点 let T = layer == "rx" ? "rxTitle" : "Title"; let flagT = layer + T; if (!_that._self[flagT]) return false; for (let i = 0; i < _that._self[flagT].length; i++) { const el = _that._self[flagT][i]; el.destroy(); //destory()销毁 , show(false) false:隐藏 true :展示 } _that._self[flagT] = []; } }; /** * 删除图层的某个要素 * @param {*} layer 唯一标识 */ MapUtil.prototype.removeElementOne = (layer, id) => { if (!_that.idsBox[layer]) return false; let list = _that.idsBox[layer]; list.forEach((el, index) => { if (el == id) { _that.idsBox[layer].splice(index, 1); if (_that._self[layer][index]) _that._self[layer][index].destroy(); _that._self[layer].splice(index, 1); if (layer == "rx") { let flagT = layer + "rxTitle"; if (_that._self[flagT][index]) _that._self[flagT][index].destroy(); _that._self[flagT].splice(index, 1); _that.removeGpsZbOverlayById(id); //删除图标 } } }); }; // 删除图标装备 MapUtil.prototype.removeGpsZbOverlayById = (id) => { if (_that._self.gpsZb[id]) { try { let info = _that._self.gpsZb[id]; if (info) { info.forEach((element) => { element.destroy(); }); delete _that._self.gpsZb[id]; } } catch (err) { } } }; // 绘制数据的初始化 MapUtil.prototype.Drawplot = (color) => { const { point, line, polygon, circle, rectangle, geoJson, remove, enableEdit } = map.draw({ lineWidth: 2, lineColor: "rgba(233,168,32,1)", fillColor: "rgba(233,168,32,0.5)", color: "rgba(233,168,32,1)", pixelSzie: 0 }); _that._CustomDraw = { point, line, polygon, circle, rectangle, geoJson, remove, enableEdit }; }; /** * 绘制工具 * @param {*} type 绘制形状 * (point 点, line 线, circle 圆, polygon 多边形, rectangle 矩形) , * geoJson:根据geojson回显图 */ MapUtil.prototype.plot = (res, resFun) => { let { flag, color, linecolor, type, coords } = res; if (!_that._self[flag]) _that._self[flag] = []; if (res.isclear) _that.removePlot(flag); //移除绘制工具 if (res.isclear && (res.type == "polygon" || res.type == "line")) _that.removeEara(flag); //移除回显的面和线条 switch (type) { case "point": _that._CustomDraw.point((val) => { _that.handlePlot(val, type, flag, resFun); }); break; case "rectangle": _that._CustomDraw.rectangle((val) => { _that.handlePlot(val, type, flag, resFun); }); break; case "circle": _that._CustomDraw.circle((val) => { _that.handlePlot(val, type, flag, resFun); }); break; case "polygon": _that._CustomDraw.polygon( (val) => { _that.handlePlot(val, type, flag, resFun); }, { fillColor: color || "rgba(233,168,32,0.5)", lineColor: linecolor || "rgba(233,168,32,1)" } ); break; case "line": _that._CustomDraw.line((val) => { _that.handlePlot(val, type, flag, resFun); }); break; case "geoJson": //返回面 let json = { type: "FeatureCollection", features: [ { type: "Feature", geometry: { type: "Polygon", coordinates: coords // coords 是三维数组 }, id: flag, properties: { fillColor: color || "rgba(233,168,32,1)", lineColor: linecolor || "rgba(233,168,32,1)" } } ] }; _that._CustomDraw.geoJson(json, (data) => { _that.handlePlot(data, type, flag, resFun); }); break; } }; /** * 处理自定义数据 * @param {*} val 返回数据 * @param {*} type 类型 * @param {*} flag 唯一标识 * @param {*} resFun 回调 */ // 校验 MapUtil.prototype.handlePlot = (val, type, flag, resFun) => { _that._self[flag].push(val.id); let coords = val.positionData; //绘制区域 resFun(coords, type, flag, val); }; /** * 移除绘制工具 * @param {*} flag 唯一标识 */ MapUtil.prototype.removePlot = (flag) => { if (!_that._self[flag]) return false; _that._self[flag].forEach((v) => { _that._CustomDraw.remove(v); }); }; /** * 移除绘制面 * @param {*} flag 唯一标识 */ MapUtil.prototype.removeEara = (flag) => { _that._CustomDraw.remove(flag); _that.removePlot(flag); }; /** * 创建线 * @param {*} type 回显形状 * (solid 实线, dash 虚线, FlowColor 彩虹线, RoadLine 流线 */ MapUtil.prototype.createLine = (res) => { let { type, coords, isclear, flag, color, width, fontColor } = res; if (!coords) return false; // coords 是数组对象,可以同时撒多条数据 if (!_that._self[flag]) _that._self[flag] = []; if (isclear) _that.removeElement(flag); //移除回显的线条 let data = coords.map((item, index) => { return { position: item.coords[0], //二维数组 text: item.text, id: index, userData: { name: item.text } }; }); let line = map.createLine(data, { color: color ? color : "rgba(20, 237, 245,1)", width: width ? width : 8, type, highlightColor: "red", labelOption: { pixelOffset: [0, -1], allShow: false, type: "text", fontColor: fontColor ? fontColor : "rgb(0, 0, 0)" } }); _that._self[flag].push(line); }; /** * 回显平面- 圆 - 多边形 - 矩形 * @param {*} type 回显形状 * type: 'polygon', 'rectangle coords = [{ position:[[[jd,wd],[jd,wd] ---]], //三维数组 text,//展示的文字 id, //唯一标识 FID, //渲染颜色的标识 userData:{} //存储数据 }] * type:circle coords:[jd,wd] radius:半径 * @param {*} text 展示的文字 */ MapUtil.prototype.echoPlane = (res) => { let { type, coords, fontColor, fontSize, text = "", radius = 0, isclear, flag, id = 1, color, linecolor } = res; if (!coords) return; if (isclear) _that.removeElement(flag); if (!_that._self[flag]) _that._self[flag] = []; let color1 = color ? color : "rgba(29,237,245,0.6)"; let linecolor1 = linecolor ? linecolor : "rgba(29,237,245,0.6)"; let style = { color: color1, outLineColor: linecolor1, outLineWidth: 2, highlightColor: "rgba(255,0,0,0.5)", labelOption: { pixelOffset: [0, 0], allShow: true, fontColor: fontColor ? fontColor : "#ffffff", fontSize: fontSize ? fontSize : "12px" } }; let maker; // 圆 if (type == "circle") { let params = [{ center: coords, radius, text, id }]; maker = map.createCircle(params, style); } // 矩形 if (type == "rectangle") maker = map.createRectangle(coords, style); // 多边形 if (type == "polygon") maker = map.createPolygon(coords, style); _that._self[flag].push(maker); maker.addEventListener("click", (val) => { if (flag == "xfq") { maker.highlight(val.id); //高亮展示 emitter.emit("showXFQinfo", val); if (val.id == _that.lightHeight) { _that.isCheck = !_that.isCheck; if (_that.isCheck) { maker.highlight(0); //取消高亮展示 emitter.emit("showXFQinfo", null); } else { emitter.emit("showXFQinfo", val); } } _that.lightHeight = val.id; } if (flag == "zdxl_fzyc") { emitter.emit("showFzycInfo", { info: val, type: true }); } }); }; // 分割线展示文字 MapUtil.prototype.gapText = (obj) => { let { points, text, flag } = obj; _that.makerShowTitle({}, points, flag, text); //展示标题 }; /** * 轨迹回放 * @param {*} coords 轨迹坐标.二维数组[[104.03640684556253,30.7415801286654],[103.98021233220163,30.6555411499294],[103.85766040251299,30.58094579138167]] * @param {*} isClear 是否清除上一次的记录 */ MapUtil.prototype.displayLineAnimation = (res) => { let { coords, isClear, flag } = res; if (!coords) return; if (!_that._self[flag]) _that._self[flag] = []; if (isClear && _that._self[flag]) _that.removeElement(flag); //destroy 移除,start 播放,pause 暂停 let lineString = getUUid().slice(3, 5); const data = [ { position: coords, text: "实线", id: lineString, userData: { name: "测试1" } } ]; const track = map.trajectoryRealtime(data, { color: "#28F", //轨迹背景颜色 width: 8, image: "images/car.png", speed: 80, // 单位 m/s imageWidth: 20, imageHeight: 40, isShowLine: false, //轨迹线是否显示 isAgain: false, //轨迹运动是否重复, traveledColor: "#32b1fb" //运动轨迹颜色 }); track.start(); track.on("length", (data) => { let obj = { flag }; if (data && data[0].percent == 0) { obj.icon = require("@/assets/point/start.png"); // 开始 let item = data[0].position[0]; obj.coords = [{ jd: item[0], wd: item[1] }]; _that.makerSki(obj); } if (data && data[0].percent == 99) { let len = data[0].position.length; let val = data[0].position[len - 1]; obj.coords = [{ jd: val[0], wd: val[1] }]; obj.icon = require("@/assets/point/end.png"); // 结束 _that.makerSki(obj); } }); _that._self[flag].push(track); }; // 移除轨迹 MapUtil.prototype.removeTrajectory = (flag) => { if (_that._self[flag]) { _that._self[flag].destroy(); _that._self[flag] = null; } }; /**geojson 创建边界 * let data = { * type: "FeatureCollection", * features: [ * { geometry: { type: "Polygon", coordinates: [it.coordinates] }, properties: { }, type: "Feature", } * ] }; */ MapUtil.prototype.createBoundarys = (res) => { let { data } = res; if (!data) return false; if (_that.polygonGeo) _that.removeBj(); _that.polygonGeo = map.createPolygon(data, { color: "rgba(20,237,245,0.3)", outLineColor: "#cf1010", outLineWidth: 6, highlightColor: "red", type: "solid", labelOption: { pixelOffset: [2, 0], allShow: false, fontColor: "#ffffff" } }); _that.polygonGeo.flyTo(); }; // 移除边界 MapUtil.prototype.removeBj = (res) => { _that.polygonGeo.destroy(); }; // 打开详情弹窗 MapUtil.prototype.openInfoDetail = (flag, data) => { switch (flag) { case "rx": emitter.emit("showJzInfo", data); break; case "gaj": case "pcs": case "jwz": case "xfq": case "zdfkd": emitter.emit("showGazy", data); break; case "kfd": emitter.emit("changeGroupPoint", { lx: "kfd", xffwlx: "2", xffwid: data.kfdId }); emitter.emit("showGazy", [data]); break; case "sp": emitter.emit("showGzy", data); emitter.emit("showGzyInfo", data); break; case "kk": emitter.emit("showGzy", data); break; case "aj": case "jqMap": emitter.emit("showAj", data); break; case "yj": case "yjMap": emitter.emit("showYjxq", data); break; case "dzjg": case "school": case "hospital": case "banck": case "shop": emitter.emit("showShzy", data); break; case "qchzc_map": case "jczMap_hm": case "jczMap_hhx": emitter.emit("showJcz", [data]); break; case "cyryMap": console.log(data, "从业人员"); emitter.emit("showCyry", [data]); break; } }; } // 获取uuid 作为边界图层ID function getUUid() { var list = []; var hexDigits = "0123456789abcdefghijklmnopqrstuvwxyz"; for (var i = 0; i < 32; i++) { list[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); } list[14] = "4"; list[19] = hexDigits.substr((list[19] & 0x3) | 0x8, 1); list[8] = list[13] = list[18] = list[23]; let uuid = list.join(""); return uuid; }