src/main/kotlin/com/flightfeather/uav/biz/satellite/SatelliteGridManage.kt
@@ -16,27 +16,32 @@
    /**
     * 根据正方形网格中心点坐标,计算4个顶点坐标
     * 网格中心点坐标按照从左到右、从上到下的顺序排列
     * @param points 网格中心坐标点数组
     */
    fun calGridVertex(points: List<Pair<Double, Double>>): List<GridVertex> {
        // 网格少于2个,则无法绘制
        if (points.size < 2) return emptyList()
        val p1 = points[0];
        val p2 = points[1];
        // 获取前两个网格
        // Fixme 2025.01.10: 目前先简化逻辑,按照前两个点是左右排布,且点p2在点p1的东边
        val p1 = points[0]
        val p2 = points[1]
        // 两中心点间的角度
        val angle = MapUtil.getAngle(p1.first, p1.second, p2.first, p2.second);
        val angle = MapUtil.getAngle(p1.first, p1.second, p2.first, p2.second)
        // 两中心点间的距离
        val dis = MapUtil.getDistance(p1.first, p1.second, p2.first, p2.second);
        val dis = MapUtil.getDistance(p1.first, p1.second, p2.first, p2.second)
        // 网格正方形对角线的一半长度
        val halfDiagonal = sqrt((dis / 2) * (dis / 2) * 2);
        val halfDiagonal = sqrt((dis / 2) * (dis / 2) * 2)
        // 计算首个正方形各顶点相对于中心点的角度,得到正方形各顶点的坐标
        val angle1 = MapUtil.plusAngle(angle, 45.0);
        val gp1 = MapUtil.getPointByLen(p1, halfDiagonal, angle1 * PI / 180);
        val angle2 = MapUtil.plusAngle(angle1, 90.0);
        val gp2 = MapUtil.getPointByLen(p1, halfDiagonal, angle2 * PI / 180);
        val angle3 = MapUtil.plusAngle(angle2, 90.0);
        val gp3 = MapUtil.getPointByLen(p1, halfDiagonal, angle3 * PI / 180);
        val angle4 = MapUtil.plusAngle(angle3, 90.0);
        val gp4 = MapUtil.getPointByLen(p1, halfDiagonal, angle4 * PI / 180);
        // 4个顶点按照从左上角开始,顺时针方向的顺序进行排列
        val angle1 = MapUtil.plusAngle(angle, 45.0 + 180.0)
        val gp1 = MapUtil.getPointByLen(p1, halfDiagonal, angle1 * PI / 180)
        val angle2 = MapUtil.plusAngle(angle1, 90.0)
        val gp2 = MapUtil.getPointByLen(p1, halfDiagonal, angle2 * PI / 180)
        val angle3 = MapUtil.plusAngle(angle2, 90.0)
        val gp3 = MapUtil.getPointByLen(p1, halfDiagonal, angle3 * PI / 180)
        val angle4 = MapUtil.plusAngle(angle3, 90.0)
        val gp4 = MapUtil.getPointByLen(p1, halfDiagonal, angle4 * PI / 180)
        // 计算4个顶点分别与中心点的经纬度差值
        val dx1 = gp1.first - p1.first
        val dy1 = gp1.second - p1.second
@@ -59,10 +64,83 @@
    }
    /**
     * 拆分网格
     * 拆分网格为细分网格
     * 根据相似矩形的原理,可以分别按比例得到每个细分网格的经纬度
     * @param gridCellList 原始网格数组
     * @param scale 拆分的系数,例如 2,表示将原有网格按边长的 1/2 拆分成 2 * 2 的4个网格
     */
    fun splitGrid(gridCellList: List<GridCell?>): List<GridCell> {
        TODO()
    fun splitGrid(gridCellList: List<GridCell>, scale: Int): List<GridCell> {
        if (scale <= 0) throw IllegalArgumentException("网格拆分的数量不能小于1")
        // 拆分系数为1,则表示不拆分
        if (scale == 1) return gridCellList
        if (gridCellList.isEmpty()) return emptyList()
        val newGridCellList = mutableListOf<GridCell>()
        // 根据函数[calGridVertex]生成的网格4个顶点坐标,以上北下南左西右东方向为标准
        // 计算首个网格中心坐标点分别和4个顶点的经纬度差值
        val p = gridCellList[0]
        // (通过近似平面坐标系的方式)根据单个原始网格的4个顶点坐标,分别确定以下三组坐标点之间的经纬度单位偏移量
        val p1 = p.point1Lon to p.point1Lat
        val p2 = p.point2Lon to p.point2Lat
        val p3 = p.point3Lon to p.point3Lat
        val p4 = p.point4Lon to p.point4Lat
        // p1、p3的经纬度单位差值
        val dx1 = (p3.first - p1.first) / scale.toBigDecimal()
        val dy1 = (p3.second - p1.second) / scale.toBigDecimal()
        // p1、p2的经纬度单位差值
        val dx2 = (p2.first - p1.first) / scale.toBigDecimal()
        val dy2 = (p2.second - p1.second) / scale.toBigDecimal()
        // p3、p4的经纬度单位差值
        val dx3 = (p4.first - p3.first) / scale.toBigDecimal()
        val dy3 = (p4.second - p3.second) / scale.toBigDecimal()
        // 中心点和p1的经纬度单位差值
        val dxC = (p.longitude - p1.first) / scale.toBigDecimal()
        val dyC = (p.latitude - p1.second) / scale.toBigDecimal()
        // 网格行循环
        for (row in 0 until scale) {
            val newGridCell1 = GridCell()
            // 确定每一行首个细分网格的中心坐标和4个顶点坐标
            // 左上角顶点根据所在行数在原始网格顶点基础上增加偏移量
            newGridCell1.point1Lon = p1.first + dx1 * row.toBigDecimal()
            newGridCell1.point1Lat = p1.second + dy1 * row.toBigDecimal()
            // 左下角顶点根据所在行数在原始网格顶点基础上增加偏移量(比左上角顶点多一个偏移)
            newGridCell1.point3Lon = p1.first + dx1 * (row + 1).toBigDecimal()
            newGridCell1.point3Lat = p1.second + dy1 * (row + 1).toBigDecimal()
            // 右上角顶点在细分网格左上角的基础上增加相应的偏移量
            newGridCell1.point2Lon = newGridCell1.point1Lon + dx2
            newGridCell1.point2Lat = newGridCell1.point1Lat + dy2
            // 右下角顶点在细分网格左下角的基础上增加相应的偏移量
            newGridCell1.point4Lon = newGridCell1.point3Lon + dx3
            newGridCell1.point4Lat = newGridCell1.point3Lat + dy3
            // 中心点在细分网格左上角的基础上增加固定偏移量
            newGridCell1.longitude = newGridCell1.point1Lon + dxC
            newGridCell1.latitude = newGridCell1.point1Lat + dyC
            // 加入结果集合
            newGridCellList.add(newGridCell1)
            // 网格列循环(从第2列开始)
            for (col in 1 until scale) {
                val newGridCell = GridCell()
                newGridCell.point1Lon = newGridCell1.point1Lon + dx2 * col.toBigDecimal()
                newGridCell.point1Lat = newGridCell1.point1Lat + dy2 * col.toBigDecimal()
                newGridCell.point2Lon = newGridCell1.point2Lon + dx2 * col.toBigDecimal()
                newGridCell.point2Lat = newGridCell1.point2Lat + dy2 * col.toBigDecimal()
                newGridCell.point3Lon = newGridCell1.point3Lon + dx3 * col.toBigDecimal()
                newGridCell.point3Lat = newGridCell1.point3Lat + dy3 * col.toBigDecimal()
                newGridCell.point4Lon = newGridCell1.point4Lon + dx3 * col.toBigDecimal()
                newGridCell.point4Lat = newGridCell1.point4Lat + dy3 * col.toBigDecimal()
                newGridCell.longitude = newGridCell.point1Lon + dxC
                newGridCell.latitude = newGridCell.point1Lat + dyC
                newGridCellList.add(newGridCell)
            }
        }
        return newGridCellList
    }
}