From bde043c8fd1a076f44c402dd56c62d401afbfb16 Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期四, 27 三月 2025 17:29:48 +0800
Subject: [PATCH] 1. 新增卫星遥测网格热力图计算逻辑

---
 src/main/kotlin/com/flightfeather/uav/biz/satellite/SatelliteGridUtil.kt |  101 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 97 insertions(+), 4 deletions(-)

diff --git a/src/main/kotlin/com/flightfeather/uav/biz/satellite/SatelliteGridUtil.kt b/src/main/kotlin/com/flightfeather/uav/biz/satellite/SatelliteGridUtil.kt
index 6010859..68b4dd6 100644
--- a/src/main/kotlin/com/flightfeather/uav/biz/satellite/SatelliteGridUtil.kt
+++ b/src/main/kotlin/com/flightfeather/uav/biz/satellite/SatelliteGridUtil.kt
@@ -3,6 +3,7 @@
 import com.flightfeather.uav.common.utils.MapUtil
 import com.flightfeather.uav.domain.entity.GridCell
 import kotlin.math.ceil
+import kotlin.math.floor
 
 /**
  * 鍗槦缃戞牸璁$畻宸ュ叿
@@ -49,26 +50,118 @@
         option: GridGroupOption,
         searchLength: Int,
     ): List<GridCell> {
-        return emptyList()
+        val hOffset = option.eachWidth;
+        val wOffset = 1;
+
+        val cellIdMin = 1
+        val cellIdMax = option.width * option.height
+
+        val searchWidth = 0 - searchLength
+        val searchHeight = 0 - searchLength
+
+        val result = mutableListOf<GridCell>()
+
+        val eachRange = getCellWidthRange(gridCellIndex, option.eachWidth, option.eachHeight)?: return emptyList()
+        val groupRange = getCellWidthRange(
+            ceil(gridCellIndex.toDouble() / (option.eachWidth * option.eachHeight)).toInt(),
+            option.width / option.eachWidth,
+            option.height / option.eachHeight
+        ) ?: return emptyList()
+
+        for (w in searchWidth..searchLength) {
+            // 鍏堣繘琛屾í鍚戠殑鍧愭爣鍙樻崲
+            var _cellId = gridCellIndex + w * wOffset;
+            if (_cellId < eachRange.first || _cellId > eachRange.second) {
+                val cellOffset = if (_cellId < eachRange.first) _cellId - eachRange.first else _cellId - eachRange.second
+
+                val groupOffset = if (cellOffset / option.eachWidth > 0) {
+                    ceil(cellOffset.toDouble() / option.eachWidth).toInt()
+                } else {
+                    floor(cellOffset.toDouble() / option.eachWidth).toInt()
+                }
+
+                val newEachRange =
+                    (eachRange.first + groupOffset * option.eachWidth * option.eachHeight) to
+                            (eachRange.second + groupOffset * option.eachWidth * option.eachHeight)
+
+                _cellId = if (groupOffset > 0) {
+                    newEachRange.first + cellOffset - wOffset
+                } else {
+                    newEachRange.second + cellOffset + wOffset;
+                }
+
+                val _groupId = ceil(_cellId.toDouble() / (option.eachWidth * option.eachHeight)).toInt()
+
+                if (_groupId < groupRange.first || _groupId > groupRange.second) {
+                    continue;
+                }
+            }
+
+            for (h in searchHeight..searchLength) {
+                if (w == 0 && h == 0) continue;
+
+                val _eachRange = getCellWidthRange(_cellId, option.eachWidth, option.eachHeight) ?: return emptyList()
+
+                val wOffset = _cellId - _eachRange.first;
+                var _resCellId = _cellId + h * hOffset;
+                if (_resCellId < cellIdMin || _resCellId > cellIdMax) continue;
+
+                val total = option.eachWidth * option.eachHeight;
+                val x = ceil(_cellId.toDouble() / total).toInt() - 1;
+                val eachCellIdMin = 1 + x * total;
+                val eachCellIdMax = total + x * total;
+                val topCell = eachCellIdMin + wOffset;
+                val bottomCell = eachCellIdMax - option.eachWidth + 1 + wOffset;
+                if (_resCellId < eachCellIdMin || _resCellId > eachCellIdMax) {
+                    val cellOffset = if (_resCellId < eachCellIdMin) {
+                        _resCellId - topCell
+                    } else {
+                        _resCellId - bottomCell;
+                    }
+
+                    val newTopCell = if (cellOffset > 0) {
+                        topCell + option.width * option.eachHeight
+                    } else {
+                        topCell - option.width * option.eachHeight;
+                    }
+
+                    val newBottomCell = if (cellOffset > 0) {
+                        bottomCell + option.width * option.eachHeight
+                    } else {
+                        bottomCell - option.width * option.eachHeight;
+                    }
+
+                    _resCellId = if (cellOffset > 0) {
+                        newTopCell + cellOffset - hOffset
+                    } else {
+                        newBottomCell + cellOffset + hOffset;
+                    }
+                }
+                gridCellList.find { it?.cellIndex == _resCellId }?.let { result.add(it) }
+            }
+        }
+
+        return result;
     }
 
     /**
+     * Fixme 2025.3.14: 鍛ㄨ竟缃戞牸鐨勬煡鎵撅紝鍚庣画閫氳繃灏嗙綉鏍肩敤鍧愭爣鐐圭殑琛ㄧず鏂瑰紡鏉ョ洿鎺ヨ绠�(x, y)
      * 鏍规嵁缃戞牸绱㈠紩锛岃幏鍙栧叾鎵�鍦ㄤ笢瑗挎柟鍚戠殑缃戞牸绱㈠紩鑼冨洿
      * @param cellIndex 缃戞牸绱㈠紩
      * @param width 缃戞牸瀹藉害锛屾寚涓滆タ鏂瑰悜涓婄殑缃戞牸鏁伴噺
      * @param height 缃戞牸楂樺害锛屾寚鍗楀寳鏂瑰悜涓婄殑缃戞牸鏁伴噺
      * @return 杩斿洖缃戞牸绱㈠紩鍊艰寖鍥�
      */
-    fun getCellWidthRange(cellIndex: Int, width: Int, height: Int): Pair<Double, Double>? {
+    fun getCellWidthRange(cellIndex: Int, width: Int, height: Int): Pair<Int, Int>? {
         val total = width * height;
-        val x = ceil(cellIndex.toDouble() / total) - 1;
+        val x = (ceil(cellIndex.toDouble() / total) - 1).toInt()
         val first = 1 + x * total
         val last = width + x * total;
         var scale = 0;
         while (scale < height) {
             val min = first + scale * width;
             val max = last + scale * width;
-            if (cellIndex >= min && cellIndex <= max) {
+            if (cellIndex in min..max) {
                 return min to max
             }
             scale++;

--
Gitblit v1.9.3