From c7a16ca1b6fbcb0b82a4a09c2e75014624082e37 Mon Sep 17 00:00:00 2001 From: Riku <risaku@163.com> Date: 星期四, 27 三月 2025 22:45:48 +0800 Subject: [PATCH] 修复走航融合功能bug --- src/model/SatelliteGrid.js | 644 ++++++++++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 485 insertions(+), 159 deletions(-) diff --git a/src/model/SatelliteGrid.js b/src/model/SatelliteGrid.js index 4bc2504..d6f3c8c 100644 --- a/src/model/SatelliteGrid.js +++ b/src/model/SatelliteGrid.js @@ -10,15 +10,22 @@ constructor(name) { this.name = name; } - - // 鍦板浘缃戞牸鐩稿叧瀵硅薄 + // 榛樿鍦板浘缃戞牸鐩稿叧瀵硅薄 mapViews; - mapViewsList = []; + gridDataDetail; + infoMap = new Map(); + + // 鍦板浘缃戞牸瀵硅薄Map缁撴瀯锛屽瓨鍌ㄥ搴攌ey涓嬬殑缃戞牸瀵硅薄銆佺綉鏍煎潗鏍囦俊鎭� mapViewsMap = new Map(); + // 缃戞牸鏁版嵁Map缁撴瀯锛屽瓨鍌ㄥ搴攌ey涓嬬殑缃戞牸鐩戞祴鏁版嵁淇℃伅 + gridDataDetailMap = new Map(); + districtPolygon; + + firstEvent; events = new Map(); @@ -83,8 +90,6 @@ } } } - - firstEvent; // 缁樺埗缃戞牸绾� drawPolyline(gridInfo, event) { @@ -166,14 +171,16 @@ points, gridDataDetail, lastGridViews, - opacity, - zIndex, - customColor + customColor, + style }) { // 鏍规嵁鏁版嵁绛涢�夋湁鏁版嵁鐨勭綉鏍� const res = []; // 浠ュ強瀵瑰簲鐨勪腑蹇冪偣鍧愭爣 const pointsRes = []; + // 缃戞牸鎸夌収鍏剁紪鍙峰崌搴忔帓鍒楋紝鐒跺悗璁$畻缂栧彿鍜屼笅琛ㄧ殑鍋忓樊鍊� + const offset = gridViews[0].getExtData().gridCell.cellIndex - 0; + gridDataDetail.forEach((d) => { // 鏍规嵁鏁版嵁鍏宠仈鐨勭綉鏍肩紪鍙凤紝鎵惧埌瀵瑰簲缃戞牸 const cellId = d.cellId; @@ -182,26 +189,20 @@ '閬ユ祴鏁版嵁鐨勭綉鏍肩储寮曠紪鍙疯秴鍑虹綉鏍肩粍鑼冨洿锛屾暟鎹拰缃戞牸缁勫彲鑳戒笉瀵瑰簲' ); } - res.push(gridViews[cellId - 1]); - pointsRes.push(points[cellId - 1]); + res.push(gridViews[cellId - offset]); + pointsRes.push(points[cellId - offset]); }); // 鏍规嵁缁樺埗棰滆壊鏂瑰紡缁樺埗缃戞牸 let resGridViews; if (customColor) { - resGridViews = gridMapUtil.drawGridColorCustom( - res, - gridDataDetail, - opacity, - zIndex - ); + resGridViews = gridMapUtil.drawGridColorCustom(res, gridDataDetail); } else { resGridViews = gridMapUtil.drawGridColor( res, gridDataDetail, 'PM25', - opacity, - zIndex + style ); } @@ -223,167 +224,94 @@ // 缁樺埗缃戞牸閬ユ劅鏁版嵁鍊煎拰缃戞牸棰滆壊 drawGrid({ - gridDataDetail, - useCustomColor, - opacity, - zIndex, - showDataTxt, - showRankTxt, - useDataTxtColor, - mapViews + 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; - // SatelliteProxy.clearText(mapViews); + this.gridDataDetail = data; const { resGridViews, pointsRes } = this.drawColor({ gridViews: _mapViews.gridViews, points: _mapViews.points, - gridDataDetail: gridDataDetail, + gridDataDetail: data, lastGridViews: _mapViews.lastGridViews, - customColor: useCustomColor, - opacity: opacity, - zIndex: zIndex + customColor: grid.useCustomColor, + style: grid.style }); _mapViews.lastGridViews = resGridViews; _mapViews.lastPoints = pointsRes; // 鏁版嵁鏍囪 - const { textViews: dataTxt, labelsLayer: dataLayer } = this.drawDataText( + const { textViews: dtv } = this.drawDataText( _mapViews.lastPoints, - gridDataDetail, + data, _mapViews.dataTxt, - useCustomColor, - useDataTxtColor + dataTxt.useCustomColor, + dataTxt.useColor ); - _mapViews.dataTxt = dataTxt; - _mapViews.dataLayer = dataLayer; + _mapViews.dataTxt = dtv; - const { textViews: rankTxt, labelsLayer: rankLayer } = this.drawRankText( + const { textViews: rtv } = this.drawRankText( _mapViews.lastPoints, - gridDataDetail, + data, _mapViews.rankTxt, _mapViews.rankLayer ); - _mapViews.rankTxt = rankTxt; - _mapViews.rankLayer = rankLayer; + _mapViews.rankTxt = rtv; - if (showDataTxt) { + if (dataTxt.isShow) { map.add(_mapViews.dataTxt); } - if (showRankTxt) { + if (rankTxt.isShow) { map.add(_mapViews.rankTxt); } } - // - drawGrids({ - gridDataDetailList, - useCustomColor, - opacity, - zIndex, - showDataTxt, - showRankTxt - }) { - if (this.mapViewsList.length < gridDataDetailList.length) { - let index = this.mapViewsList.length; - while (index < gridDataDetailList.length) { - const newMapViews = { - 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)) - }; - this.mapViewsList.push(newMapViews); - } - } - - this.mapViewsList.forEach((m, i) => { - this.drawGrid({ - gridDataDetail: gridDataDetailList[i], - useCustomColor, - opacity, - zIndex, - showDataTxt, - showRankTxt, - mapViews: m - }); - }); - } - - drawNewGrid({ - gridDataDetail, - useCustomColor, - opacity, - zIndex, - showDataTxt, - showRankTxt - }) { - const newMapViews = { - 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)) - }; - this.mapViewsList.push(newMapViews); - this.drawGrid({ - gridDataDetail, - useCustomColor, - opacity, - zIndex, - showDataTxt, - showRankTxt, - mapViews: newMapViews - }); - } - drawTagGrid({ - tag, - gridDataDetail, - useCustomColor, - opacity, - zIndex, - showDataTxt, - showRankTxt - }) { + /** + * 鏍规嵁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 = { - 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)) - }; + 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({ - gridDataDetail, - useCustomColor, - opacity, - zIndex, - showDataTxt, - showRankTxt, - mapViews: _mapViews + mapViews: _mapViews, + data, + grid, + dataTxt, + rankTxt + }); + } + + deleteTagGrid(tags) { + this.changeVisibility({ tags, showGridViews: false }); + tags.forEach((t) => { + this.mapViewsMap.delete(t); + this.gridDataDetailMap.delete(t); }); } // 璋冩暣鍚勭被鍦板浘瑕嗙洊鐗╃殑鍙鎬� - changeVisibility({ tag, showGridViews, showDataTxt, showRankTxt }) { - let _mapViewsList = []; - if (this.mapViews) { - _mapViewsList.push(this.mapViews); - } - if (tag && this.mapViewsMap.has(tag)) { - _mapViewsList.push(this.mapViewsMap.get(tag)); - } else { - this.mapViewsMap.forEach((v) => { - _mapViewsList.push(v); - }); - } + changeVisibility({ tags = [], showGridViews, showDataTxt, showRankTxt }) { + let { _mapViewsList } = this._getMapViews(...tags); + if (showGridViews != undefined) { if (showGridViews) { // map.add(this.mapViews.lastGridViews); @@ -426,17 +354,8 @@ } changeGridOpacity({ tag, isOpacity, opacityValue }) { - let _mapViewsList = []; - if (this.mapViews) { - _mapViewsList.push(this.mapViews); - } - if (tag && this.mapViewsMap.has(tag)) { - _mapViewsList.push(this.mapViewsMap.get(tag)); - } else { - this.mapViewsMap.forEach((v) => { - _mapViewsList.push(v); - }); - } + let { _mapViewsList } = tag ? this._getMapViews(tag) : this._getMapViews(); + _mapViewsList.forEach((v) => { if (v.lastGridViews) { v.lastGridViews.forEach((e) => { @@ -453,20 +372,65 @@ }); } - setGridEvent(name, event) { + 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(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); + }); + }); }); } @@ -485,4 +449,366 @@ }); } } + + /** + * 灏嗗缁勭綉鏍艰繘琛岃瀺鍚� + * 閲嶅彔鐨勭綉鏍艰繘琛岀洃娴嬫暟鎹潎鍊艰绠楀苟閲嶆柊璁$畻瀵瑰簲棰滆壊锛屽舰鎴愭柊鐨勪竴缁勮瀺鍚堢綉鏍� + * @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) { + 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; + } + + drawHeatGrid2(tag, headGridDataDetailList) { + const heatTag = `heat-${tag}`; + if (this.mapViewsMap.has(heatTag)) { + this.changeVisibility({ + tags: [heatTag], + showGridViews: true + }); + } else { + this.drawTagGrid({ + tag: heatTag, + data: headGridDataDetailList, + 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 = []; + 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 + }; + } } -- Gitblit v1.9.3