From b2392458ebf42594b9fc5390fda40d7a0a12f923 Mon Sep 17 00:00:00 2001
From: riku <risaku@163.com>
Date: 星期三, 03 九月 2025 17:40:52 +0800
Subject: [PATCH] 调试自动生成网格融合图片功能(待完成)

---
 src/model/SatelliteGrid.js |  763 ++++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 579 insertions(+), 184 deletions(-)

diff --git a/src/model/SatelliteGrid.js b/src/model/SatelliteGrid.js
index 4bc2504..af3f0f7 100644
--- a/src/model/SatelliteGrid.js
+++ b/src/model/SatelliteGrid.js
@@ -1,7 +1,11 @@
+import { reactive } from 'vue';
 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';
+import { getGridDataDetailFactorValue } from '@/model/GridDataDetail';
+import { useGridStore } from '@/stores/grid-info';
+
+const gridStore = useGridStore();
 
 /**
  * 鍗槦閬ユ祴缃戞牸绠$悊
@@ -11,16 +15,33 @@
     this.name = name;
   }
 
-  // 鍦板浘缃戞牸鐩稿叧瀵硅薄
+  gridGroupId;
+
+  // 榛樿鍦板浘缃戞牸鐩稿叧瀵硅薄
   mapViews;
+  gridState;
+  gridDataDetail;
 
-  mapViewsList = [];
-
+  // 鍦板浘缃戞牸瀵硅薄Map缁撴瀯锛屽瓨鍌ㄥ搴攌ey涓嬬殑缃戞牸瀵硅薄銆佺綉鏍煎潗鏍囦俊鎭�
   mapViewsMap = new Map();
+  // 鍦板浘缃戞牸瀵硅薄鐨勫弬鏁扮姸鎬�
+  gridStateMap = new Map();
+  // 缃戞牸鏁版嵁Map缁撴瀯锛屽瓨鍌ㄥ搴攌ey涓嬬殑缃戞牸鐩戞祴鏁版嵁淇℃伅
+  gridDataDetailMap = new Map();
 
   districtPolygon;
 
+  firstEvent;
+
   events = new Map();
+
+  selectedFactorType;
+
+  setShowFactorType(e) {
+    this.selectedFactorType = e;
+    this.changeGridColor({ factorName: e.name });
+    this.changeText({ factorName: e.name });
+  }
 
   // 缁樺埗鍖哄幙杈圭晫
   drawDistrict(districtName, isNew) {
@@ -84,8 +105,6 @@
     }
   }
 
-  firstEvent;
-
   // 缁樺埗缃戞牸绾�
   drawPolyline(gridInfo, event) {
     this.firstEvent = event;
@@ -127,8 +146,7 @@
     const data = gridDataDetail.map((v, i) => {
       return {
         lnglat_GD: points[i],
-        // data: v.pm25 ? (v.pm25 + '渭g/m鲁') : ''
-        data: v.pm25 ? v.pm25 : ''
+        data: getGridDataDetailFactorValue(v, this.selectedFactorType.name)
       };
     });
     // return gridMapUtil.drawGridTextLabel(data, textViews, labelsLayer, 'bottom');
@@ -138,8 +156,54 @@
       anchor: 'top-center',
       type: 'data',
       isCustomColor,
-      useColor
+      useColor,
+      factorName: this.selectedFactorType.name
     });
+  }
+
+  changeText({ tags = [], factorName, isCustomColor, useColor, type }) {
+    let { _mapViewsList, _gridDataDetailList } = this._getMapViews(...tags);
+    if (_mapViewsList.length == _gridDataDetailList.length) {
+      _mapViewsList.forEach((v, i) => {
+        if (v.dataTxt) {
+          let dataList = [];
+          if (type == 'data' || type == undefined) {
+            dataList.push({
+              type: 'data',
+              data: _gridDataDetailList[i].map((v) => {
+                return {
+                  data: getGridDataDetailFactorValue(
+                    v,
+                    factorName ? factorName : this.selectedFactorType.name
+                  )
+                };
+              })
+            });
+          }
+          if (type == 'rank' || type == undefined) {
+            dataList.push({
+              type: 'rank',
+              data: _gridDataDetailList[i].map((v) => {
+                return {
+                  data: v.rank ? v.rank : ''
+                };
+              })
+            });
+          }
+
+          dataList.forEach((d) => {
+            gridMapUtil.changeGridText({
+              points: d.data,
+              textViews: d.type == 'data' ? v.dataTxt : v.rankTxt,
+              type: d.type,
+              isCustomColor,
+              useColor,
+              factorName: factorName ? factorName : this.selectedFactorType.name
+            });
+          });
+        }
+      });
+    }
   }
 
   // 缁樺埗鐩戞祴鏁版嵁鎺掑悕鏂囨湰
@@ -147,8 +211,7 @@
     const data = gridDataDetail.map((v, i) => {
       return {
         lnglat_GD: points[i],
-        // data: v.pm25 ? ('鎺掑悕: ' + v.rank) : ''
-        data: v.pm25 ? v.rank : ''
+        data: v.rank ? v.rank : ''
       };
     });
     // return gridMapUtil.drawGridTextLabel(data, textViews, labelsLayer, 'top');
@@ -156,7 +219,8 @@
       points: data,
       textViews,
       anchor: 'bottom-center',
-      type: 'rank'
+      type: 'rank',
+      factorName: this.selectedFactorType.name
     });
   }
 
@@ -166,14 +230,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,8 +248,8 @@
           '閬ユ祴鏁版嵁鐨勭綉鏍肩储寮曠紪鍙疯秴鍑虹綉鏍肩粍鑼冨洿锛屾暟鎹拰缃戞牸缁勫彲鑳戒笉瀵瑰簲'
         );
       }
-      res.push(gridViews[cellId - 1]);
-      pointsRes.push(points[cellId - 1]);
+      res.push(gridViews[cellId - offset]);
+      pointsRes.push(points[cellId - offset]);
     });
 
     // 鏍规嵁缁樺埗棰滆壊鏂瑰紡缁樺埗缃戞牸
@@ -192,16 +258,14 @@
       resGridViews = gridMapUtil.drawGridColorCustom(
         res,
         gridDataDetail,
-        opacity,
-        zIndex
+        this.selectedFactorType.name
       );
     } else {
       resGridViews = gridMapUtil.drawGridColor(
         res,
         gridDataDetail,
-        'PM25',
-        opacity,
-        zIndex
+        this.selectedFactorType.name,
+        style
       );
     }
 
@@ -209,7 +273,7 @@
       map.remove(lastGridViews);
     }
     map.add(resGridViews);
-    // map.setFitView(resGridViews);
+    map.setFitView(resGridViews);
 
     return { resGridViews, pointsRes };
   }
@@ -223,221 +287,191 @@
 
   // 缁樺埗缃戞牸閬ユ劅鏁版嵁鍊煎拰缃戞牸棰滆壊
   drawGrid({
-    gridDataDetail,
-    useCustomColor,
-    opacity,
-    zIndex,
-    showDataTxt,
-    showRankTxt,
-    useDataTxtColor,
-    mapViews
+    mapViews,
+    gridState,
+    data,
+    grid = {
+      useCustomColor: false,
+      style: { opacity: 1, zIndex: 11, isMixGridHighlight: false }
+    },
+    dataTxt = { isShow: false, useCustomColor: false, useColor: false },
+    rankTxt = { isShow: false }
   }) {
+    // 纭畾缁樺埗鐨勭綉鏍肩粍鍙婂叾鍙傛暟瀵硅薄
     const _mapViews = mapViews ? mapViews : this.mapViews;
-    // SatelliteProxy.clearText(mapViews);
+    const _gridState = gridState ? gridState : this.gridState;
+
+    // 鏍规嵁缃戞牸鏁版嵁缁樺埗瀵瑰簲鐨勭綉鏍�
     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;
+    // 鏇存柊缃戞牸鐘舵�佸弬鏁�
+    _gridState.showGrid = true;
+    _gridState.showGridCustomColor = false;
+    _gridState.gridOpacityValue = grid.style.opacity;
+    _gridState.gridZIndex = grid.style.zIndex;
+    _gridState.highlightFusionGrid = grid.style.isMixGridHighlight;
 
-    // 鏁版嵁鏍囪
-    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;
+    // 鏇存柊鏁版嵁鏂囨湰鐘舵�佸弬鏁�
+    _gridState.showData = dataTxt.isShow;
+    _gridState.showDataColor = dataTxt.useColor;
+    _gridState.showDataCustomColor = dataTxt.useCustomColor;
 
-    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;
+    // 鏇存柊鎺掑悕鏂囨湰鐘舵�佸弬鏁�
+    _gridState.showRank = rankTxt.isShow;
 
-    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 });
+      const newGridState = this._createNewGridState({ extData });
       this.mapViewsMap.set(tag, newMapViews);
+      map.on('zoomend', newMapViews.mapZoomEvent);
+      this.gridStateMap.set(tag, newGridState);
+      this.gridDataDetailMap.set(tag, data);
     }
     const _mapViews = this.mapViewsMap.get(tag);
+    const _gridState = this.gridStateMap.get(tag);
     this.drawGrid({
-      gridDataDetail,
-      useCustomColor,
-      opacity,
-      zIndex,
-      showDataTxt,
-      showRankTxt,
-      mapViews: _mapViews
+      mapViews: _mapViews,
+      gridState: _gridState,
+      data,
+      grid,
+      dataTxt,
+      rankTxt
+    });
+  }
+
+  /**
+   * 鏍规嵁鏍囩鍒犻櫎瀵瑰簲鐨勭綉鏍硷紝鍚屾椂绉婚櫎鍦板浘缂╂斁浜嬩欢绛�
+   * @param {*} tags 缃戞牸鏍囩鏁扮粍
+   */
+  deleteTagGrid(tags) {
+    this.changeVisibility({
+      tags,
+      showGridViews: false,
+      showDataTxt: false,
+      showRankTxt: false
+    });
+    tags.forEach((t) => {
+      const { mapZoomEvent } = this.mapViewsMap.get(t);
+      map.off('zoomend', mapZoomEvent);
+      this.mapViewsMap.delete(t);
+      this.gridDataDetailMap.delete(t);
+      this.gridStateMap.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, _gridStateList } = this._getMapViews(...tags);
+
     if (showGridViews != undefined) {
       if (showGridViews) {
-        // map.add(this.mapViews.lastGridViews);
-        _mapViewsList.forEach((v) => {
-          if (v.lastGridViews) map.add(v.lastGridViews);
+        _mapViewsList.forEach((v, i) => {
+          if (v.lastGridViews) {
+            map.add(v.lastGridViews);
+            _gridStateList[i].showGrid = true;
+          }
         });
       } else {
-        // map.remove(this.mapViews.lastGridViews);
-        _mapViewsList.forEach((v) => {
-          if (v.lastGridViews) map.remove(v.lastGridViews);
+        _mapViewsList.forEach((v, i) => {
+          if (v.lastGridViews) {
+            map.remove(v.lastGridViews);
+            _gridStateList[i].showGrid = false;
+            _gridStateList[i].showHeatMap = false;
+          }
         });
       }
     }
     if (showDataTxt != undefined) {
       if (showDataTxt) {
-        // map.add(this.mapViews.dataTxt);
-        _mapViewsList.forEach((v) => {
-          if (v.dataTxt) map.add(v.dataTxt);
+        _mapViewsList.forEach((v, i) => {
+          if (v.dataTxt) {
+            map.add(v.dataTxt);
+            _gridStateList[i].showData = true;
+          }
         });
       } else {
-        // map.remove(this.mapViews.dataTxt);
-        _mapViewsList.forEach((v) => {
-          if (v.dataTxt) map.remove(v.dataTxt);
+        _mapViewsList.forEach((v, i) => {
+          if (v.dataTxt) {
+            map.remove(v.dataTxt);
+            _gridStateList[i].showData = false;
+          }
         });
       }
     }
     if (showRankTxt != undefined) {
       if (showRankTxt) {
-        // map.add(this.mapViews.rankTxt);
-        _mapViewsList.forEach((v) => {
-          if (v.rankTxt) map.add(v.rankTxt);
+        _mapViewsList.forEach((v, i) => {
+          if (v.rankTxt) {
+            map.add(v.rankTxt);
+            _gridStateList[i].showRank = true;
+          }
         });
       } else {
-        // map.remove(this.mapViews.rankTxt);
-        _mapViewsList.forEach((v) => {
-          if (v.rankTxt) map.remove(v.rankTxt);
+        _mapViewsList.forEach((v, i) => {
+          if (v.rankTxt) {
+            map.remove(v.rankTxt);
+            _gridStateList[i].showRank = false;
+          }
         });
       }
     }
   }
 
   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);
-      });
-    }
-    _mapViewsList.forEach((v) => {
+    let { _mapViewsList, _gridStateList } = tag
+      ? this._getMapViews(tag)
+      : this._getMapViews();
+
+    _mapViewsList.forEach((v, i) => {
       if (v.lastGridViews) {
         v.lastGridViews.forEach((e) => {
           e.setOptions({
@@ -449,24 +483,112 @@
                   : 0.7
           });
         });
+        _gridStateList[i].gridOpacityValue = opacityValue;
       }
     });
   }
 
-  setGridEvent(name, event) {
+  changeGridColor({
+    tags = [],
+    factorName,
+    useCustomColor,
+    opacity,
+    zIndex,
+    isMixGridHighlight
+  }) {
+    let { _mapViewsList, _gridDataDetailList, _gridStateList } =
+      this._getMapViews(...tags);
+    if (_mapViewsList.length == _gridDataDetailList.length) {
+      _mapViewsList.forEach((v, i) => {
+        if (v.lastGridViews) {
+          const lastGridDataDetail = _gridDataDetailList[i];
+          const _gridState = _gridStateList[i];
+          if (useCustomColor != undefined)
+            _gridState.showGridCustomColor = useCustomColor;
+          if (useCustomColor) {
+            gridMapUtil.drawGridColorCustom(
+              v.lastGridViews,
+              lastGridDataDetail,
+              factorName ? factorName : this.selectedFactorType.name
+            );
+          } else {
+            if (opacity != undefined) _gridState.gridOpacityValue = opacity;
+            if (zIndex != undefined) _gridState.gridZIndex = zIndex;
+            if (isMixGridHighlight != undefined)
+              _gridState.highlightFusionGrid = isMixGridHighlight;
+            gridMapUtil.drawGridColor(
+              v.lastGridViews,
+              lastGridDataDetail,
+              factorName ? factorName : this.selectedFactorType.name,
+              { 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, polygon, extData: v.extData });
+        });
+      });
+    });
+  }
+
+  setDefaultGridClickEvent(tags) {
+    this.setGridEvent(
+      tags,
+      'click',
+      ({ gridCell, gridDataDetail, extData }) => {
+        gridStore.selectedGridCellAndDataDetail = {
+          gridCell,
+          gridDataDetail,
+          extData
+        };
+      }
+    );
+
+    //榧犳爣绉诲叆浜嬩欢
+    this.setGridEvent(tags, 'mouseover', ({ polygon }) => {
+      const ext = polygon.getExtData();
+      const originOption = polygon.getOptions();
+      ext.originOption = originOption;
+      polygon.setOptions({
+        strokeWeight: 2,
+        strokeColor: 'red'
+      });
+      polygon.setExtData(ext);
+    });
+
+    //榧犳爣绉诲嚭浜嬩欢
+    this.setGridEvent(tags, 'mouseout', ({ polygon }) => {
+      const ext = polygon.getExtData();
+      polygon.setOptions(ext.originOption);
     });
   }
 
@@ -485,4 +607,277 @@
       });
     }
   }
+
+  /**
+   * 灏嗗缁勭綉鏍艰繘琛岃瀺鍚�
+   * 閲嶅彔鐨勭綉鏍艰繘琛岀洃娴嬫暟鎹潎鍊艰绠楀苟閲嶆柊璁$畻瀵瑰簲棰滆壊锛屽舰鎴愭柊鐨勪竴缁勮瀺鍚堢綉鏍�
+   * @param {Array} tags 闇�瑕佽瀺鍚堢殑缃戞牸鏍囩锛屽綋涓虹┖鏃讹紝榛樿铻嶅悎鎵�鏈夌綉鏍�
+   */
+  mixGrid2({ tags, isMixGridHighlight = true, gridDataDetailList }) {
+    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({ tags: [mixTag], isMixGridHighlight });
+    } else {
+      gridDataDetailList.forEach((gdd) => {
+        // 缃戞牸鏁版嵁鏄瀺鍚堢殑锛屽睍绀洪珮浜殑鏍峰紡
+        if (gdd.mixData) {
+          gdd.gridStyle = {
+            strokeWeight: 2,
+            strokeColor: '#23dad1'
+          };
+        }
+      });
+      this.drawTagGrid({
+        tag: mixTag,
+        data: gridDataDetailList,
+        grid: {
+          style: {
+            isMixGridHighlight
+          }
+        },
+        extData: {
+          name: `璧拌埅铻嶅悎 - ${mixTag}`,
+          type: 1
+        }
+      });
+    }
+
+    return mixTag;
+  }
+
+  drawHeatGrid2(tag, headGridDataDetailList) {
+    const heatTag = `heat-${tag}`;
+    if (this.gridStateMap.has(tag)) {
+      this.gridStateMap.get(tag).showHeatMap = true;
+    }
+    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 = [],
+      _gridStateList = [];
+    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));
+          _gridStateList.push(this.gridStateMap.get(tag));
+        }
+      });
+    } else {
+      this.mapViewsMap.forEach((v) => {
+        _mapViewsList.push(v);
+      });
+      this.gridDataDetailMap.forEach((v) => {
+        _gridDataDetailList.push(v);
+      });
+      this.gridStateMap.forEach((v) => {
+        _gridStateList.push(v);
+      });
+      if (this.mapViews && this.gridDataDetail && this.gridState) {
+        _mapViewsList.push(this.mapViews);
+        _gridDataDetailList.push(this.gridDataDetail);
+        _gridStateList.push(this.gridState);
+      }
+    }
+
+    return { _mapViewsList, _gridDataDetailList, _gridStateList };
+  }
+
+  _createNewMapViews({ tag, 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,
+      show: true,
+      mapZoomEvent: () => {
+        const zoomLevel = map.getZoom();
+        if (zoomLevel >= 16.5) {
+          this.changeGridOpacity({ tag, opacityValue: 0.1 });
+        } else {
+          this.changeGridOpacity({ tag, opacityValue: 1 });
+        }
+        // console.log('mapZoomEvent', map.getZoom());
+      }
+    };
+  }
+
+  _createNewGridState({ extData }) {
+    return {
+      // 缃戞牸鍚嶇О
+      name: extData.name,
+      // 缃戞牸绫诲瀷锛�0锛氳蛋鑸綉鏍硷紱1锛氳蛋鑸瀺鍚堢綉鏍硷紱2锛氳蛋鑸儹鍔涘浘
+      type: extData.type,
+      // 缃戞牸鐩稿叧鍙傛暟
+      showGrid: true, // 鏄惁鏄剧ず缃戞牸
+      showGridCustomColor: false, // 鏄惁鏄剧ず瀵规瘮鑹�
+      gridOpacityValue: 1, // 缃戞牸閫忔槑搴�
+      gridZIndex: 11, // 缃戞牸z杞撮珮搴�
+
+      // 鎺掑悕鏂囨湰鐩稿叧鍙傛暟
+      showRank: false, // 鎺掑悕鏂囨湰鏄惁鏄剧ず
+
+      // 鏁版嵁鏂囨湰鐩稿叧鍙傛暟
+      showData: false, // 鏁版嵁鏂囨湰鏄惁鏄剧ず
+      showDataColor: false, // 鏁版嵁鏂囨湰鏄惁浣跨敤瀵瑰簲鐩戞祴鍥犲瓙鐨勬爣鍑嗛鑹�
+      showDataCustomColor: false, // 鏁版嵁鏂囨湰鏄惁浣跨敤瀵瑰簲鐩戞祴鍥犲瓙鐨勫姣旈鑹�
+
+      // 鏄惁鏄剧ず瀵瑰簲鐑姏鍥�
+      showHeatMap: false,
+
+      // 濡傛灉鏄瀺鍚堢綉鏍硷紝鏄惁楂樹寒鏄剧ず閲嶅彔缃戞牸
+      highlightFusionGrid: false,
+
+      // 濡傛灉鏄櫘閫氱殑璧拌埅缃戞牸锛屾槸鍚︽樉绀哄搴旂殑璧拌埅杞ㄨ抗
+      showUnderway: false,
+
+      // 鍙兘鐨勮嚜瀹氫箟棰濆鏁版嵁
+      extData
+    };
+  }
 }

--
Gitblit v1.9.3