feiyu02
2025-03-21 da67648220f86993fac22b8199165995df3d8563
src/model/SatelliteGrid.js
@@ -196,11 +196,7 @@
    // 根据绘制颜色方式绘制网格
    let resGridViews;
    if (customColor) {
      resGridViews = gridMapUtil.drawGridColorCustom(
        res,
        gridDataDetail,
        style.opacity
      );
      resGridViews = gridMapUtil.drawGridColorCustom(res, gridDataDetail);
    } else {
      resGridViews = gridMapUtil.drawGridColor(
        res,
@@ -383,8 +379,7 @@
          if (useCustomColor) {
            gridMapUtil.drawGridColorCustom(
              v.lastGridViews,
              lastGridDataDetail,
              { opacity, zIndex }
              lastGridDataDetail
            );
          } else {
            gridMapUtil.drawGridColor(
@@ -399,20 +394,35 @@
    }
  }
  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);
        });
      });
    });
  }
@@ -435,18 +445,19 @@
  /**
   * 将多组网格进行融合
   * 重叠的网格进行监测数据均值计算并重新计算对应颜色,形成新的一组融合网格
   * @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,获取对应多组网格数据
@@ -501,8 +512,13 @@
        data: resGridDataDetail,
        grid: {
          style: {
            isMixGridHighlight: true
            isMixGridHighlight:
              isMixGridHighlight == undefined ? true : isMixGridHighlight
          }
        },
        extData: {
          name: `走航融合 - ${mixTag}`,
          type: 1
        }
      });
    }
@@ -510,6 +526,227 @@
    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 = [];