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);
|
} 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
|
);
|
} 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 {Array} tags 需要融合的网格标签,当为空时,默认融合所有网格
|
*/
|
mixGrid(tags, isMixGridHighlight) {
|
tags.sort((a, b) => {
|
return a < b ? -1 : 1;
|
});
|
const mixTag = tags.join('-');
|
if (this.mapViewsMap.has(mixTag)) {
|
this.changeVisibility({
|
tags: [mixTag],
|
showGridViews: true
|
});
|
this.changeGridColor({ tag: mixTag, isMixGridHighlight });
|
} 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:
|
isMixGridHighlight == undefined ? true : isMixGridHighlight
|
}
|
},
|
extData: {
|
name: `走航融合 - ${mixTag}`,
|
type: 1
|
}
|
});
|
}
|
|
return mixTag;
|
}
|
|
/**
|
* 绘制热力图网格
|
* @param {string} tag
|
*/
|
drawHeatGrid(tag) {
|
|
}
|
|
_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
|
};
|
}
|
}
|