| | |
| | | // 根据绘制颜色方式绘制网格 |
| | | let resGridViews; |
| | | if (customColor) { |
| | | resGridViews = gridMapUtil.drawGridColorCustom( |
| | | res, |
| | | gridDataDetail, |
| | | style.opacity |
| | | ); |
| | | resGridViews = gridMapUtil.drawGridColorCustom(res, gridDataDetail); |
| | | } else { |
| | | resGridViews = gridMapUtil.drawGridColor( |
| | | res, |
| | |
| | | if (useCustomColor) { |
| | | gridMapUtil.drawGridColorCustom( |
| | | v.lastGridViews, |
| | | lastGridDataDetail, |
| | | { opacity, zIndex } |
| | | lastGridDataDetail |
| | | ); |
| | | } else { |
| | | gridMapUtil.drawGridColor( |
| | |
| | | } |
| | | } |
| | | |
| | | setGridEvent(name, event) { |
| | | setGridEvent(tags, name, event) { |
| | | const { _mapViewsList, _gridDataDetailList } = this._getMapViews(...tags); |
| | | |
| | | 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); |
| | | _mapViewsList.forEach((v) => { |
| | | v.gridViews.forEach((polygon) => { |
| | | polygon.off(name, lastEvent); |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | this.events.get(name).push(event); |
| | | this.mapViews.gridViews.forEach((polygon) => { |
| | | polygon.on(name, event); |
| | | _mapViewsList.forEach((v, i) => { |
| | | const gridDataDetailList = _gridDataDetailList[i]; |
| | | v.gridViews.forEach((polygon) => { |
| | | const { gridCell } = polygon.getExtData(); |
| | | const cellIndex = gridCell.cellIndex; |
| | | const gridDataDetail = gridDataDetailList.find( |
| | | (v) => v.cellId == cellIndex |
| | | ); |
| | | polygon.on(name, (e) => { |
| | | event(gridCell, gridDataDetail); |
| | | }); |
| | | }); |
| | | }); |
| | | } |
| | | |
| | |
| | | /** |
| | | * 将多组网格进行融合 |
| | | * 重叠的网格进行监测数据均值计算并重新计算对应颜色,形成新的一组融合网格 |
| | | * @param {...String} tags 需要融合的网格标签,当为空时,默认融合所有网格 |
| | | * @param {Array} tags 需要融合的网格标签,当为空时,默认融合所有网格 |
| | | */ |
| | | mixGrid(tags) { |
| | | mixGrid(tags, isMixGridHighlight) { |
| | | tags.sort((a, b) => { |
| | | return a < b ? -1 : 1; |
| | | }); |
| | | const mixTag = tags.join('-'); |
| | | if (this.mapViewsMap.has(mixTag)) { |
| | | this.changeVisibility({ |
| | | tag: mixTag, |
| | | tags: [mixTag], |
| | | showGridViews: true |
| | | }); |
| | | this.changeGridColor({ tag: mixTag, isMixGridHighlight }); |
| | | } else { |
| | | // const mixMapViews = this._createNewMapViews(); |
| | | // 根据标签tag,获取对应多组网格数据 |
| | |
| | | data: resGridDataDetail, |
| | | grid: { |
| | | style: { |
| | | isMixGridHighlight: true |
| | | isMixGridHighlight: |
| | | isMixGridHighlight == undefined ? true : isMixGridHighlight |
| | | } |
| | | }, |
| | | extData: { |
| | | name: `走航融合 - ${mixTag}`, |
| | | type: 1 |
| | | } |
| | | }); |
| | | } |
| | |
| | | return mixTag; |
| | | } |
| | | |
| | | /** |
| | | * 绘制热力图网格 |
| | | * @param {string} tag |
| | | */ |
| | | drawHeatGrid(tag) { |
| | | if (!this.mapViewsMap.has(tag) || !this.gridDataDetailMap.has(tag)) { |
| | | return; |
| | | } |
| | | |
| | | const heatTag = `heat-${tag}`; |
| | | if (this.mapViewsMap.has(heatTag)) { |
| | | this.changeVisibility({ |
| | | tags: [heatTag], |
| | | showGridViews: true |
| | | }); |
| | | } else { |
| | | const _mapViews = this.mapViewsMap.get(tag); |
| | | const _gridDataDetail = this.gridDataDetailMap.get(tag); |
| | | // const groupId = _gridDataDetail[0].groupId; |
| | | // const cellId = _gridDataDetail.cellId; |
| | | |
| | | const originCellIdList = _gridDataDetail.map((v) => v.cellId); |
| | | let headGridDataDetailList = []; |
| | | |
| | | const width = 120; |
| | | const height = 90; |
| | | const eachwidth = 10; |
| | | const eachheight = 10; |
| | | |
| | | const searchLength = 3; |
| | | |
| | | const _dataMap = new Map(); |
| | | |
| | | _gridDataDetail.forEach((gdd) => { |
| | | const searchRes = this.search( |
| | | gdd, |
| | | width, |
| | | height, |
| | | eachwidth, |
| | | eachheight, |
| | | searchLength |
| | | ); |
| | | if (searchRes.find(v=> v.cellId == 1670)) { |
| | | console.log(); |
| | | |
| | | } |
| | | searchRes.forEach((e) => { |
| | | if (originCellIdList.indexOf(e.cellId) == -1) { |
| | | if (!_dataMap.has(e.cellId)) { |
| | | _dataMap.set(e.cellId, { |
| | | source: [], |
| | | res: {} |
| | | }); |
| | | } |
| | | _dataMap.get(e.cellId).source.push(e); |
| | | } |
| | | }); |
| | | }); |
| | | |
| | | _dataMap.forEach((v, k) => { |
| | | let total = 0, |
| | | count = v.source.length; |
| | | v.source.forEach((s) => { |
| | | total += s.pm25; |
| | | }); |
| | | v.res = { |
| | | isHeatData: true, |
| | | groupId: v.source[0].groupId, |
| | | cellId: v.source[0].cellId, |
| | | pm25: count == 0 ? null : Math.round((total / count) * 10) / 10, |
| | | originData: v.source |
| | | }; |
| | | headGridDataDetailList.push(v.res); |
| | | }); |
| | | headGridDataDetailList = headGridDataDetailList.concat(_gridDataDetail); |
| | | |
| | | // 重新按照监测数据排序并标记排名 |
| | | headGridDataDetailList.sort((a, b) => { |
| | | return b.pm25 - a.pm25; |
| | | }); |
| | | headGridDataDetailList.forEach((gdd, i) => { |
| | | gdd.rank = i + 1; |
| | | }); |
| | | |
| | | this.drawTagGrid({ |
| | | tag: heatTag, |
| | | data: headGridDataDetailList, |
| | | // grid: { |
| | | // style: { |
| | | // isMixGridHighlight: |
| | | // isMixGridHighlight == undefined ? true : isMixGridHighlight |
| | | // } |
| | | // }, |
| | | extData: { |
| | | name: `走航热力图 - ${heatTag}`, |
| | | type: 2 |
| | | } |
| | | }); |
| | | } |
| | | |
| | | return heatTag; |
| | | } |
| | | |
| | | search(gdd, width, height, eachwidth, eachheight, searchLength) { |
| | | function getCellWidthRange(cellId, width, height) { |
| | | const total = width * height; |
| | | const x = Math.ceil(cellId / total) - 1; |
| | | let first = 1 + x * total, |
| | | last = width + x * total; |
| | | |
| | | let scale = 0; |
| | | while (scale < height) { |
| | | const min = first + scale * width; |
| | | const max = last + scale * width; |
| | | if (cellId >= min && cellId <= max) { |
| | | return [min, max]; |
| | | } |
| | | scale++; |
| | | } |
| | | } |
| | | |
| | | const cellId = gdd.cellId; |
| | | // const minData = gdd.pm25 / 2 |
| | | const dataOffset = (gdd.pm25 - gdd.pm25 / 2) / 3; |
| | | |
| | | const hOffset = eachwidth; |
| | | const wOffset = 1; |
| | | |
| | | const cellIdMin = 1; |
| | | const cellIdMax = width * height; |
| | | |
| | | let searchWidth = 0 - searchLength, |
| | | searchHeight = 0 - searchLength; |
| | | |
| | | const result = []; |
| | | |
| | | const eachRange = getCellWidthRange(cellId, eachwidth, eachheight); |
| | | const groupRange = getCellWidthRange( |
| | | Math.ceil(cellId / (eachwidth * eachheight)), |
| | | width / eachwidth, |
| | | height / eachheight |
| | | ); |
| | | |
| | | for (let w = searchWidth; w <= searchLength; w++) { |
| | | // 先进行横向的坐标变换 |
| | | let _cellId = cellId + w * wOffset; |
| | | if (_cellId < eachRange[0] || _cellId > eachRange[1]) { |
| | | const cellOffset = |
| | | _cellId < eachRange[0] |
| | | ? _cellId - eachRange[0] |
| | | : _cellId - eachRange[1]; |
| | | |
| | | const groupOffset = Math[cellOffset / eachwidth > 0 ? 'ceil' : 'floor']( |
| | | cellOffset / eachwidth |
| | | ); |
| | | |
| | | const newEachRange = eachRange.map( |
| | | (r) => r + groupOffset * eachwidth * eachheight |
| | | ); |
| | | |
| | | _cellId = |
| | | groupOffset > 0 |
| | | ? newEachRange[0] + cellOffset - wOffset |
| | | : newEachRange[1] + cellOffset + wOffset; |
| | | |
| | | const _groupId = Math.ceil(_cellId / (eachwidth * eachheight)); |
| | | |
| | | if (_groupId < groupRange[0] || _groupId > groupRange[1]) { |
| | | continue; |
| | | } |
| | | } |
| | | |
| | | for (let h = searchHeight; h <= searchLength; h++) { |
| | | if (w == 0 && h == 0) continue; |
| | | |
| | | const _eachRange = getCellWidthRange(_cellId, eachwidth, eachheight); |
| | | // if (_eachRange == undefined) { |
| | | // console.log(); |
| | | |
| | | // } |
| | | const wOffset = _cellId - _eachRange[0]; |
| | | let _resCellId = _cellId + h * hOffset; |
| | | if (_resCellId < cellIdMin || _resCellId > cellIdMax) continue; |
| | | |
| | | const total = eachwidth * eachheight; |
| | | const x = Math.ceil(_cellId / total) - 1; |
| | | const eachCellIdMin = 1 + x * total; |
| | | const eachCellIdMax = total + x * total; |
| | | const topCell = eachCellIdMin + wOffset; |
| | | const bottomCell = eachCellIdMax - eachwidth + 1 + wOffset; |
| | | if (_resCellId < eachCellIdMin || _resCellId > eachCellIdMax) { |
| | | const cellOffset = |
| | | _resCellId < eachCellIdMin |
| | | ? _resCellId - topCell |
| | | : _resCellId - bottomCell; |
| | | |
| | | const newTopCell = |
| | | cellOffset > 0 |
| | | ? topCell + width * eachheight |
| | | : topCell - width * eachheight; |
| | | const newBottomCell = |
| | | cellOffset > 0 |
| | | ? bottomCell + width * eachheight |
| | | : bottomCell - width * eachheight; |
| | | |
| | | _resCellId = |
| | | cellOffset > 0 |
| | | ? newTopCell + cellOffset - hOffset |
| | | : newBottomCell + cellOffset + hOffset; |
| | | } |
| | | result.push({ |
| | | groupId: gdd.groupId, |
| | | cellId: _resCellId, |
| | | pm25: gdd.pm25 - Math.max(Math.abs(w), Math.abs(h)) * dataOffset |
| | | }); |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | _getMapViews(...tags) { |
| | | let _mapViewsList = [], |
| | | _gridDataDetailList = []; |