feiyu02
2025-09-12 61871594dfa0a5ac2c4d895d9ec4034feba57094
src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/DataAnalysisServiceImpl.kt
@@ -3,6 +3,7 @@
import com.flightfeather.uav.biz.FactorFilter
import com.flightfeather.uav.biz.dataanalysis.ExceptionAnalysisController
import com.flightfeather.uav.biz.dataanalysis.model.ExceptionResult
import com.flightfeather.uav.biz.report.MissionGridFusion
import com.flightfeather.uav.biz.report.MissionInventory
import com.flightfeather.uav.biz.report.MissionRiskArea
import com.flightfeather.uav.biz.report.MissionSummary
@@ -10,14 +11,15 @@
import com.flightfeather.uav.common.exception.BizException
import com.flightfeather.uav.common.location.LocationRoadNearby
import com.flightfeather.uav.common.utils.GsonUtils
import com.flightfeather.uav.domain.entity.BaseRealTimeData
import com.flightfeather.uav.domain.entity.Mission
import com.flightfeather.uav.domain.entity.SceneInfo
import com.flightfeather.uav.domain.entity.*
import com.flightfeather.uav.domain.mapper.MissionMapper
import com.flightfeather.uav.domain.repository.*
import com.flightfeather.uav.lightshare.bean.AreaVo
import com.flightfeather.uav.lightshare.bean.GridDataDetailMixVo
import com.flightfeather.uav.lightshare.eunm.PollutionDegree
import com.flightfeather.uav.lightshare.eunm.SceneType
import com.flightfeather.uav.lightshare.service.DataAnalysisService
import com.flightfeather.uav.lightshare.service.SatelliteDataCalculateService
import com.flightfeather.uav.socket.eunm.FactorType
import com.flightfeather.uav.socket.sender.MsgType
import org.springframework.stereotype.Service
@@ -39,7 +41,9 @@
    private val locationRoadNearby: LocationRoadNearby,
    private val segmentInfoRep: SegmentInfoRep,
    private val sourceTraceRep: SourceTraceRep,
    private val sceneInfoRep: SceneInfoRep
    private val sceneInfoRep: SceneInfoRep,
    private val satelliteGridRep: SatelliteGridRep,
    private val satelliteDataCalculateService: SatelliteDataCalculateService
) : DataAnalysisService {
    /**
@@ -115,10 +119,25 @@
     * @see generateMissionList 重载方法,处理已关联的数据对
     */
    override fun generateMissionList(startTime: Date, endTime: Date, areaVo: AreaVo): List<MissionInventory.MissionInfo> {
        val missionClues = missionRep.findByAreaAndTime(areaVo, startTime, endTime).filterNotNull().map {
            it to sourceTraceRep.fetchList(it.deviceCode, it.startTime, it.endTime, MsgType.PolClue) as List<PollutedClue?>
//        val missionClues = missionRep.findByAreaAndTime(areaVo, startTime, endTime).filterNotNull().map {
//            it to sourceTraceRep.fetchList(it.deviceCode, it.startTime, it.endTime, MsgType.PolClue) as List<PollutedClue?>
//        }
//        return generateMissionList(missionClues)
        val missionCluesData = missionRep.findByAreaAndTime(areaVo, startTime, endTime).filterNotNull().map {
            Triple(
                it,
                sourceTraceRep.fetchList(it.deviceCode, it.startTime, it.endTime, MsgType.PolClue) as List<PollutedClue?>,
                realTimeDataRep.fetchData(it)
            )
        }
        return generateMissionList(missionClues)
        val keyScenes = sceneInfoRep.findBySceneTypes(
            listOf(
                SceneType.TYPE19.value,
                SceneType.TYPE20.value,
                SceneType.TYPE21.value
            )
        )
        return generateMissionInfo(keyScenes, missionCluesData)
    }
    /**
@@ -130,6 +149,15 @@
     */
    override fun generateMissionList(missionClues: List<Pair<Mission, List<PollutedClue?>>>): List<MissionInventory.MissionInfo> {
        return MissionInventory().generateMissionList(missionClues)
    }
    override fun generateMissionInfo(
        keyScenes: List<SceneInfo?>,
        missionCluesData: List<Triple<Mission, List<PollutedClue?>, List<BaseRealTimeData>>>,
    ): List<MissionInventory.MissionInfo> {
        return missionCluesData.map {
            MissionInventory().generateMissionInfo(keyScenes, it.first, it.second, it.third)
        }
    }
    /**
@@ -204,4 +232,68 @@
    ): List<MissionRiskArea.ClueByArea> {
        return MissionRiskArea().generateClueByRiskArea(keyScenes, pollutedClues)
    }
    override fun generateGridFusion(
        factorTypes: List<FactorType>,
        startTime: Date,
        endTime: Date,
        areaVo: AreaVo,
    ): List<MissionGridFusion.GridFusionByAQI> {
        val gridLen = 100
        // 查询100米网格的具体网格数据
        val gridGroup = satelliteGridRep.fetchGridGroup(GridGroup().apply {
            type = "sub"
            length = gridLen.toDouble()
            provinceCode = areaVo.provinceCode
            cityCode = areaVo.cityCode
            districtCode = areaVo.districtCode
        }).firstOrNull() ?: throw BizException("未查询到100米网格")
        val gridCells = satelliteGridRep.fetchGridCell(gridGroup.id).filterNotNull()
        // 查询范围内的所有走航任务
        val missions = missionRep.findByAreaAndTime(areaVo, startTime, endTime)
        // 根据空气质量等级分类
        val missionGroups = missions.groupBy { PollutionDegree.getByDes(it?.pollutionDegree ?: "") }
        // 查询每个等级下的走航任务对应的网格数据(如果没有数据则剔除该任务)
        val gridDataDetailList = missionGroups.mapNotNull { (degree, missionList) ->
            // 筛选出有网格融合数据的走航任务(同时获取对应的融合数据id列表)
            val gridDataIds = mutableListOf<Int>()
            val validMissions = missionList.filter {mission ->
                val gridData = satelliteGridRep.fetchGridData(GridData().apply { missionCode = mission?.missionCode }).firstOrNull()
                val res = gridData != null
                if (res) gridDataIds.add(gridData?.id ?: 0)
                res
            }
            // 合并每个等级下的网格数据
            val gridDataDetailMixVos = satelliteDataCalculateService.mixUnderwayGridData(gridGroup.id, gridDataIds)
            // 统计每个走航任务的走航详情信息
            val missionCluesData = validMissions.filterNotNull().map {
                Triple(
                    it,
                    sourceTraceRep.fetchList(it.deviceCode, it.startTime, it.endTime, MsgType.PolClue) as List<PollutedClue?>,
                    realTimeDataRep.fetchData(it)
                )
            }
            val keyScenes = sceneInfoRep.findBySceneTypes(
                listOf(
                    SceneType.TYPE19.value,
                    SceneType.TYPE20.value,
                    SceneType.TYPE21.value
                )
            )
            val missionInfos = generateMissionInfo(keyScenes, missionCluesData)
            return@mapNotNull Triple(degree, missionInfos, gridDataDetailMixVos)
        }.filter { it.second.isNotEmpty() }
        return generateGridFusion(factorTypes, gridLen, gridCells, gridDataDetailList)
    }
    override fun generateGridFusion(
        factorTypes: List<FactorType>,
        gridLen: Int,
        gridCells: List<GridCell>,
        dataList: List<Triple<PollutionDegree, List<MissionInventory.MissionInfo>, List<GridDataDetailMixVo>>>,
    ): List<MissionGridFusion.GridFusionByAQI> {
        return MissionGridFusion(sceneInfoRep).generateGridFusion(factorTypes, gridLen, gridCells, dataList)
    }
}