import calculate from '@/utils/map/calculate'; import gridMapUtil from '@/utils/map/grid'; import { map, onMapMounted } from '@/utils/map/index_old'; import { useCloned } from '@vueuse/core'; /** * 卫星遥测网格管理 */ export class SatelliteGrid { constructor(name) { this.name = name; } // 默认地图网格相关对象 mapViews; gridDataDetail; infoMap = new Map(); // 地图网格对象Map结构,存储对应key下的网格对象、网格坐标信息 mapViewsMap = new Map(); // 网格数据Map结构,存储对应key下的网格监测数据信息 gridDataDetailMap = new Map(); districtPolygon; firstEvent; events = new Map(); // 绘制区县边界 drawDistrict(districtName, isNew) { onMapMounted(() => { if (this.districtPolygon && !isNew) { map.remove(this.districtPolygon); map.add(this.districtPolygon); } else { // eslint-disable-next-line no-undef var district = new AMap.DistrictSearch({ extensions: 'all', //返回行政区边界坐标等具体信息 level: 'district' //设置查询行政区级别为区 }); district.search(districtName, (status, result) => { var bounds = result.districtList[0].boundaries; //获取朝阳区的边界信息 if (bounds) { for (var i = 0; i < bounds.length; i++) { //生成行政区划 polygon // eslint-disable-next-line no-undef this.districtPolygon = new AMap.Polygon({ map: map, //显示该覆盖物的地图对象 strokeWeight: 2, //轮廓线宽度 path: bounds[i], //多边形轮廓线的节点坐标数组 fillOpacity: 0, //多边形填充透明度 fillColor: '#CCF3FF', //多边形填充颜色 // strokeColor: '#ffffff' //线条颜色 strokeColor: '#0552f7', //线条颜色 zIndex: 9 }); } map.setFitView(); //将覆盖物调整到合适视野 } }); } }); } clearAll(mapViews) { if (mapViews) { if (typeof mapViews.gridViews === 'object') { map.remove(mapViews.gridViews); } } this.clearText(mapViews); } clearText(mapViews) { if (mapViews) { if (typeof mapViews.dataTxt === 'object') { map.remove(mapViews.dataTxt); } if (typeof mapViews.dataLayer === 'object') { map.remove(mapViews.dataLayer); } if (typeof mapViews.rankTxt === 'object') { map.remove(mapViews.rankTxt); } if (typeof mapViews.rankLayer === 'object') { map.remove(mapViews.rankLayer); } } } // 绘制网格线 drawPolyline(gridInfo, event) { this.firstEvent = event; // 绘制网格 const points = gridInfo.map((v) => { return calculate.wgs84_To_Gcj02(v.longitude, v.latitude); // return [v.longitude, v.latitude]; }); // const gridPoints = gridMapUtil.parseGridPoint(points); // console.log('gridPoints:', gridPoints); const gridPoints = gridInfo.map((v, i) => { return { path: [ calculate.wgs84_To_Gcj02(v.point1Lon, v.point1Lat), calculate.wgs84_To_Gcj02(v.point2Lon, v.point2Lat), calculate.wgs84_To_Gcj02(v.point3Lon, v.point3Lat), calculate.wgs84_To_Gcj02(v.point4Lon, v.point4Lat) // [v.point1Lon, v.point1Lat], // [v.point2Lon, v.point2Lat], // [v.point3Lon, v.point3Lat], // [v.point4Lon, v.point4Lat] ] // eslint-disable-next-line no-undef .map((d) => new AMap.LngLat(d[0], d[1])), extData: { centerPoint: points[i], // gridPoints, gridCell: v } }; }); const gridViews = gridMapUtil.drawPolylines({ points: gridPoints, event }); return { gridViews, gridPoints, points }; } // 绘制监测数据值 drawDataText(points, gridDataDetail, textViews, isCustomColor, useColor) { const data = gridDataDetail.map((v, i) => { return { lnglat_GD: points[i], // data: v.pm25 ? (v.pm25 + 'μg/m³') : '' data: v.pm25 ? v.pm25 : '' }; }); // return gridMapUtil.drawGridTextLabel(data, textViews, labelsLayer, 'bottom'); return gridMapUtil.drawGridText({ points: data, textViews, anchor: 'top-center', type: 'data', isCustomColor, useColor }); } // 绘制监测数据排名文本 drawRankText(points, gridDataDetail, textViews, labelsLayer) { const data = gridDataDetail.map((v, i) => { return { lnglat_GD: points[i], // data: v.pm25 ? ('排名: ' + v.rank) : '' data: v.pm25 ? v.rank : '' }; }); // return gridMapUtil.drawGridTextLabel(data, textViews, labelsLayer, 'top'); return gridMapUtil.drawGridText({ points: data, textViews, anchor: 'bottom-center', type: 'rank' }); } // 绘制监测数据值对应网格颜色 drawColor({ gridViews, points, gridDataDetail, lastGridViews, customColor, style }) { // 根据数据筛选有数据的网格 const res = []; // 以及对应的中心点坐标 const pointsRes = []; // 网格按照其编号升序排列,然后计算编号和下表的偏差值 const offset = gridViews[0].getExtData().gridCell.cellIndex - 0; gridDataDetail.forEach((d) => { // 根据数据关联的网格编号,找到对应网格 const cellId = d.cellId; if (cellId > gridViews.length) { throw Error( '遥测数据的网格索引编号超出网格组范围,数据和网格组可能不对应' ); } res.push(gridViews[cellId - offset]); pointsRes.push(points[cellId - offset]); }); // 根据绘制颜色方式绘制网格 let resGridViews; if (customColor) { resGridViews = gridMapUtil.drawGridColorCustom( res, gridDataDetail, style.opacity ); } else { resGridViews = gridMapUtil.drawGridColor( res, gridDataDetail, 'PM25', style ); } if (lastGridViews) { map.remove(lastGridViews); } map.add(resGridViews); // map.setFitView(resGridViews); return { resGridViews, pointsRes }; } // 卫星网格配置准备 gridPrepare(gridInfo, event) { // clearText(mapViews); this.clearAll(this.mapViews); this.mapViews = this.drawPolyline(gridInfo, event); } // 绘制网格遥感数据值和网格颜色 drawGrid({ mapViews, data, grid = { useCustomColor: false, style: { opacity: 1, zIndex: 11 } }, dataTxt = { isShow: false, useCustomColor: false, useColor: false }, rankTxt = { isShow: false } }) { const _mapViews = mapViews ? mapViews : this.mapViews; this.gridDataDetail = data; const { resGridViews, pointsRes } = this.drawColor({ gridViews: _mapViews.gridViews, points: _mapViews.points, gridDataDetail: data, lastGridViews: _mapViews.lastGridViews, customColor: grid.useCustomColor, style: grid.style }); _mapViews.lastGridViews = resGridViews; _mapViews.lastPoints = pointsRes; // 数据标记 const { textViews: dtv } = this.drawDataText( _mapViews.lastPoints, data, _mapViews.dataTxt, dataTxt.useCustomColor, dataTxt.useColor ); _mapViews.dataTxt = dtv; const { textViews: rtv } = this.drawRankText( _mapViews.lastPoints, data, _mapViews.rankTxt, _mapViews.rankLayer ); _mapViews.rankTxt = rtv; if (dataTxt.isShow) { map.add(_mapViews.dataTxt); } if (rankTxt.isShow) { map.add(_mapViews.rankTxt); } } /** * 根据tag标签,展示已有的网格或绘制一组新的网格 * @param {Object} param0 { * tag, 标签 * gridDataDetail, 网格数据数组 * useCustomColor, 是否使用对比色 * opacity, 透明度,取值[0, 1] * zIndex, 地图显示层级 * showDataTxt, 是否显示数据文本 * showRankTxt, 是否显示排名文本 * extData, 自定义额外信息对象 * } */ drawTagGrid({ tag, data, grid, dataTxt, rankTxt, extData }) { if (!this.mapViewsMap.has(tag)) { const newMapViews = this._createNewMapViews({ extData }); this.infoMap.set(tag, extData); this.mapViewsMap.set(tag, newMapViews); this.gridDataDetailMap.set(tag, data); } const _mapViews = this.mapViewsMap.get(tag); this.drawGrid({ mapViews: _mapViews, data, grid, dataTxt, rankTxt }); } // 调整各类地图覆盖物的可见性 changeVisibility({ tags = [], showGridViews, showDataTxt, showRankTxt }) { let { _mapViewsList } = this._getMapViews(...tags); if (showGridViews != undefined) { if (showGridViews) { // map.add(this.mapViews.lastGridViews); _mapViewsList.forEach((v) => { if (v.lastGridViews) map.add(v.lastGridViews); }); } else { // map.remove(this.mapViews.lastGridViews); _mapViewsList.forEach((v) => { if (v.lastGridViews) map.remove(v.lastGridViews); }); } } if (showDataTxt != undefined) { if (showDataTxt) { // map.add(this.mapViews.dataTxt); _mapViewsList.forEach((v) => { if (v.dataTxt) map.add(v.dataTxt); }); } else { // map.remove(this.mapViews.dataTxt); _mapViewsList.forEach((v) => { if (v.dataTxt) map.remove(v.dataTxt); }); } } if (showRankTxt != undefined) { if (showRankTxt) { // map.add(this.mapViews.rankTxt); _mapViewsList.forEach((v) => { if (v.rankTxt) map.add(v.rankTxt); }); } else { // map.remove(this.mapViews.rankTxt); _mapViewsList.forEach((v) => { if (v.rankTxt) map.remove(v.rankTxt); }); } } } changeGridOpacity({ tag, isOpacity, opacityValue }) { let { _mapViewsList } = tag ? this._getMapViews(tag) : this._getMapViews(); _mapViewsList.forEach((v) => { if (v.lastGridViews) { v.lastGridViews.forEach((e) => { e.setOptions({ fillOpacity: typeof opacityValue === 'number' ? opacityValue : isOpacity ? 0.1 : 0.7 }); }); } }); } changeGridColor({ tag, useCustomColor, opacity, zIndex, isMixGridHighlight }) { let { _mapViewsList, _gridDataDetailList } = this._getMapViews(tag); if (_mapViewsList.length == _gridDataDetailList.length) { _mapViewsList.forEach((v, i) => { if (v.lastGridViews) { const lastGridDataDetail = _gridDataDetailList[i]; if (useCustomColor) { gridMapUtil.drawGridColorCustom( v.lastGridViews, lastGridDataDetail, { opacity, zIndex } ); } else { gridMapUtil.drawGridColor( v.lastGridViews, lastGridDataDetail, 'PM25', { opacity, zIndex, isMixGridHighlight } ); } } }); } } setGridEvent(name, event) { if (!this.events.has(name)) { this.events.set(name, []); } const list = this.events.get(name); if (list.length > 0) { const lastEvent = list[list.length - 1]; this.mapViews.gridViews.forEach((polygon) => { polygon.off(name, lastEvent); }); } this.events.get(name).push(event); this.mapViews.gridViews.forEach((polygon) => { polygon.on(name, event); }); } goBackGridEvent(name) { if (this.events.has(name)) { const eventList = this.events.get(name); //先移除原有的事件 const lastEvent = eventList.pop(); this.mapViews.gridViews.forEach((polygon) => { polygon.off(name, lastEvent); }); //获取上一个事件 const event = eventList.pop(); this.mapViews.gridViews.forEach((polygon) => { polygon.on(name, event); }); } } /** * 将多组网格进行融合 * 重叠的网格进行监测数据均值计算并重新计算对应颜色,形成新的一组融合网格 * @param {...String} tags 需要融合的网格标签,当为空时,默认融合所有网格 */ mixGrid(tags) { tags.sort((a, b) => { return a < b ? -1 : 1; }); const mixTag = tags.join('-'); if (this.mapViewsMap.has(mixTag)) { this.changeVisibility({ tag: mixTag, showGridViews: true }); } else { // const mixMapViews = this._createNewMapViews(); // 根据标签tag,获取对应多组网格数据 let { _gridDataDetailList } = this._getMapViews(...tags); const _dataMap = new Map(); // 将每组每个网格数据按照网格编号进行分类,相同网格的数组归集至一起 _gridDataDetailList.forEach((list) => { list.forEach((gdd) => { if (!_dataMap.has(gdd.cellId)) { _dataMap.set(gdd.cellId, { source: [], res: {} }); } _dataMap.get(gdd.cellId).source.push(gdd); }); }); // 计算每个网格下的数据均值 const resGridDataDetail = []; _dataMap.forEach((v, k) => { let total = 0, count = v.source.length; v.source.forEach((s) => { total += s.pm25; }); v.res = { isMixData: true, groupId: v.source[0].groupId, cellId: v.source[0].cellId, pm25: count == 0 ? null : Math.round((total / count) * 10) / 10, originData: v.source }; // 数据量超过1个时,表明该网格数据是融合的,展示高亮的样式 if (count > 1) { v.res.gridStyle = { strokeWeight: 2, strokeColor: 'blue' }; } resGridDataDetail.push(v.res); }); // 重新按照监测数据排序并标记排名 resGridDataDetail.sort((a, b) => { return b.pm25 - a.pm25; }); resGridDataDetail.forEach((gdd, i) => { gdd.rank = i + 1; }); this.drawTagGrid({ tag: mixTag, data: resGridDataDetail, grid: { style: { isMixGridHighlight: true } } }); } return mixTag; } _getMapViews(...tags) { let _mapViewsList = [], _gridDataDetailList = []; if (tags.length > 0) { tags.forEach((tag) => { if (this.mapViewsMap.has(tag) && this.gridDataDetailMap.has(tag)) { _mapViewsList.push(this.mapViewsMap.get(tag)); _gridDataDetailList.push(this.gridDataDetailMap.get(tag)); } }); } else { this.mapViewsMap.forEach((v) => { _mapViewsList.push(v); }); this.gridDataDetailMap.forEach((v) => { _gridDataDetailList.push(v); }); if (this.mapViews && this.gridDataDetail) { _mapViewsList.push(this.mapViews); _gridDataDetailList.push(this.gridDataDetail); } } return { _mapViewsList, _gridDataDetailList }; } _createNewMapViews({ extData }) { return { gridViews: gridMapUtil.drawPolylines({ points: this.mapViews.gridPoints, event: this.firstEvent }), gridPoints: JSON.parse(JSON.stringify(this.mapViews.gridPoints)), points: JSON.parse(JSON.stringify(this.mapViews.points)), extData }; } }