feiyu02
2025-02-21 dacef58ee7c44dffdd40cb646435c2993ad7a217
src/main/kotlin/com/flightfeather/uav/biz/satellite/SatelliteGridManage.kt
@@ -1,10 +1,7 @@
package com.flightfeather.uav.biz.satellite
import com.flightfeather.uav.common.utils.MapUtil
import com.flightfeather.uav.domain.entity.BaseRealTimeData
import com.flightfeather.uav.domain.entity.GridCell
import com.flightfeather.uav.domain.entity.GridData
import com.flightfeather.uav.domain.entity.GridDataDetail
import com.flightfeather.uav.domain.entity.*
import kotlin.math.PI
import kotlin.math.sqrt
@@ -20,7 +17,9 @@
    /**
     * 根据正方形网格中心点坐标,计算4个顶点坐标
     * 网格中心点坐标按照从左到右、从上到下的顺序排列
     * @date 2025.1.8
     * @param points 网格中心坐标点数组
     * @return 网格4个顶点经纬度坐标
     */
    fun calGridVertex(points: List<Pair<Double, Double>>): List<GridVertex> {
        // 网格少于2个,则无法绘制
@@ -69,10 +68,11 @@
    /**
     * 拆分网格为细分网格,所有网格应该是相同边长的正方形
     * 根据相似矩形的原理,可以分别按比例得到每个细分网格的经纬度
     * @date 2025.1.17
     * @param gridCellList 原始网格数组
     * @param scale 拆分的系数,例如 2,表示将原有网格按边长的 1/2 拆分成 2 * 2 的4个网格
     * @param groupId 细分后的网格所属的网格组id
     * @return
     * @return 细分网格
     */
    fun splitGrid(gridCellList: List<GridCell?>, scale: Int, groupId:Int): List<GridCell?> {
        if (scale <= 0) throw IllegalArgumentException("网格拆分的数量不能小于1")
@@ -165,9 +165,11 @@
    /**
     * 拆分数据,将原始卫星网格遥测数据映射到对应细分网格上
     * @param subGridCellList 细分网格, 按照
     * @date 2025.2.7
     * @param subGridCellList 细分网格
     * @param subGridData 细分网格对应的数据索引
     * @param originGridDataDetailList 细分网格所属网格的原始网格数据
     * @return 映射后的细分网格遥测数据
     */
    fun splitData(
        subGridCellList: List<GridCell?>, subGridData: GridData, originGridDataDetailList: List<GridDataDetail?>
@@ -217,17 +219,71 @@
    }
    /**
     * 数据融合
     * 走航数据和卫星网格融合
     * 数据融合采用均值方式统计(暂时)
     * @date 2025.2.7
     * @param realTimeDataList 待融合的走航监测数据
     * @param gridData 融合后的数据组索引
     * @param gridCellList 待融合的卫星网格
     * @return 融合后的网格监测数据
     */
    fun dataFusion(realTimeDataList:List<BaseRealTimeData>, gridData: GridData, gridCellList: List<GridCell?>) {
        // 遍历走航监测数据,计算每个点所在网格,并形成网格值
    fun dataFusion(
        realTimeDataList: List<BaseRealTimeData>,
        gridData: GridData,
        gridCellList: List<GridCell?>,
    ): List<GridDataDetail> {
        // 遍历走航监测数据,计算每个点所在网格
        val dataMap = mutableMapOf<GridCell, MutableList<BaseRealTimeData>>()
        realTimeDataList.forEach {
            it.longitude
            it.latitude
            gridCellList.forEach {  }
            if (it.longitude == null || it.latitude == null) return@forEach
            searchGirdIn(it.longitude!!.toDouble() to it.latitude!!.toDouble(), gridCellList)?.let { cell ->
                if (!dataMap.containsKey(cell)) {
                    dataMap[cell] = mutableListOf()
                }
                dataMap[cell]?.add(it)
            }
        }
        // 统计每个网格中的均值
        // Fixme 2025.2.20 暂时默认以均值方式统计,后续调整为多种方式并支持用户选择
        val gridDataDetailList = mutableListOf<GridDataDetail>()
        dataMap.forEach { (k, v) ->
            val avgData = v.avg()
            val dataDetail = GridDataDetail().apply {
                dataId = gridData.id
                groupId = k.groupId
                cellId = k.cellIndex
                pm25 = avgData.pm25
                rank
            }
            gridDataDetailList.add(dataDetail)
        }
        return gridDataDetailList
    }
    /**
     * 计算坐标点在哪个卫星网格内
     * @date 2025.2.14
     * @param point 坐标点
     * @param gridCellList 卫星网格
     */
    fun searchGirdIn(point: Pair<Double, Double>, gridCellList: List<GridCell?>): GridCell? {
        for (i in gridCellList.indices) {
            val gridCell = gridCellList[i] ?: continue
            val polygon = listOf(
                gridCell.point1Lon.toDouble() to gridCell.point1Lat.toDouble(),
                gridCell.point2Lon.toDouble() to gridCell.point2Lat.toDouble(),
                gridCell.point3Lon.toDouble() to gridCell.point3Lat.toDouble(),
                gridCell.point4Lon.toDouble() to gridCell.point4Lat.toDouble(),
            )
            if (MapUtil.isPointInPolygon(point, polygon)) {
                return gridCell
            }
        }
        return null
    }
}