| | |
| | | import com.flightfeather.uav.common.utils.MapUtil |
| | | import com.flightfeather.uav.domain.entity.GridCell |
| | | import kotlin.math.ceil |
| | | import kotlin.math.floor |
| | | |
| | | /** |
| | | * 卫星网格计算工具 |
| | |
| | | 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++; |