package com.flightfeather.uav.biz.report
|
|
import com.flightfeather.uav.biz.sourcetrace.model.PollutedClue
|
import com.flightfeather.uav.common.utils.MapUtil
|
import com.flightfeather.uav.domain.entity.*
|
import com.flightfeather.uav.lightshare.bean.FactorStatistics
|
import com.flightfeather.uav.socket.eunm.FactorType
|
import com.flightfeather.uav.socket.sender.MsgType
|
import org.springframework.beans.BeanUtils
|
|
/**
|
* 走航溯源清单
|
* 包含时段内的走航任务汇总清单以及每次走航的数据汇总清单
|
* @date 2025/8/25 11:02
|
* @author feiyu
|
*/
|
class MissionInventory {
|
|
// 走航清单信息
|
class MissionInfo : Mission() {
|
// 首要污染物
|
// var mainFactor: String? = null
|
|
// 监测异常因子
|
var abnormalFactors: List<FactorType>? = null
|
|
// 溯源问题场景数
|
var sceneCount: Int = 0
|
|
// 溯源问题场景
|
var scenes: List<SceneInfo>? = null
|
|
// 走航涉及区域
|
var keyScene: List<SceneInfo>? = null
|
|
var exceptionCount: Int = 0
|
}
|
|
// 走航详情信息
|
class MissionDetail : Mission() {
|
// var keyScene: List<SceneInfo>? = null
|
var dataStatistics: List<FactorStatistics>? = null
|
// var exceptionCount: Int = 0
|
}
|
|
/**
|
* 生成走航任务清单
|
* 处理走航任务与污染线索数据,统计每个任务的异常因子、首要污染物和场景数量
|
* @param missionClues 包含走航任务和对应污染线索的Pair列表
|
* @return 包含统计信息的MissionInfo列表,每个元素包含任务基本信息及统计数据
|
*/
|
fun generateMissionList(missionClues: List<Pair<Mission, List<PollutedClue?>>>): List<MissionInfo> {
|
val result = missionClues.map { (mission, clue) ->
|
val factorMap = mutableMapOf<FactorType, Int>()
|
val abnormalFactors = mutableListOf<FactorType>()
|
var sceneCount = 0
|
clue.forEach {
|
if (it?.msgType == MsgType.PolClue.value) {
|
it.pollutedData?.statisticMap?.keys?.forEach { k ->
|
// 计算每个走航任务的所有异常因子
|
if (!abnormalFactors.contains(k)) {
|
abnormalFactors.add(k)
|
}
|
// 计算每个走航任务的首要污染物
|
if (!factorMap.containsKey(k)) {
|
factorMap[k] = 0
|
}
|
factorMap[k] = factorMap[k]!! + 1
|
}
|
// 计算每个走航任务的溯源场景数量
|
sceneCount += it.pollutedSource?.sceneList?.size ?: 0
|
}
|
}
|
val missionInfo = MissionInfo()
|
BeanUtils.copyProperties(mission, missionInfo)
|
missionInfo.apply {
|
// mainFactor = factorMap.maxByOrNull { it.value }?.key?.name
|
this.abnormalFactors = abnormalFactors
|
this.sceneCount = sceneCount
|
}
|
}
|
return result
|
}
|
|
fun generateMissionInfo(
|
keyScenes: List<SceneInfo?>,
|
mission: Mission,
|
pollutedClues: List<PollutedClue?>,
|
data: List<BaseRealTimeData>,
|
minDis: Double = 100.0,
|
): MissionInfo {
|
val factorMap = mutableMapOf<FactorType, Int>()
|
val abnormalFactors = mutableListOf<FactorType>()
|
var sceneCount = 0
|
val scenes = mutableListOf<SceneInfo>()
|
// 提取途径关键场景信息(计算走航路线是否与关键场景距离较近)
|
val relatedScenes = mutableListOf<SceneInfo>()
|
data.forEach { d ->
|
// 跳过缺少经纬度的数据点
|
if (d.longitude == null || d.latitude == null) {
|
return@forEach
|
}
|
// 转换为GCJ02坐标系
|
val point = MapUtil.wgs84ToGcj02(d.longitude!!.toDouble() to d.latitude!!.toDouble())
|
keyScenes.forEach ks@{ k ->
|
// 跳过缺少经纬度的场景
|
if (k?.longitude == null || k.latitude == null) {
|
return@ks
|
}
|
// 检查是否未添加过
|
if (!relatedScenes.contains(k)) {
|
// 计算距离
|
val distance = MapUtil.getDistance(
|
k.longitude!!.toDouble(),
|
k.latitude!!.toDouble(),
|
point.first,
|
point.second
|
)
|
// 检查是否距离小于阈值
|
if (distance < minDis) {
|
relatedScenes.add(k)
|
}
|
}
|
}
|
}
|
pollutedClues.forEach {
|
if (it?.msgType == MsgType.PolClue.value) {
|
it.pollutedData?.statisticMap?.keys?.forEach { k ->
|
// 计算每个走航任务的所有异常因子
|
if (!abnormalFactors.contains(k)) {
|
abnormalFactors.add(k)
|
}
|
// 计算每个走航任务的首要污染物
|
if (!factorMap.containsKey(k)) {
|
factorMap[k] = 0
|
}
|
factorMap[k] = factorMap[k]!! + 1
|
}
|
// 计算每个走航任务的溯源场景数量
|
sceneCount += it.pollutedSource?.sceneList?.size ?: 0
|
it.pollutedSource?.sceneList?.forEach { s->
|
if (scenes.find { s1 -> s1.guid == s.guid } == null) {
|
scenes.add(s)
|
}
|
}
|
}
|
}
|
|
// 异常数据点数量统计
|
val clues = pollutedClues.filter { it?.msgType == MsgType.PolClue.value }
|
|
val missionInfo = MissionInfo()
|
BeanUtils.copyProperties(mission, missionInfo)
|
missionInfo.apply {
|
// mainFactor = factorMap.maxByOrNull { it.value }?.key?.name
|
this.abnormalFactors = abnormalFactors
|
this.sceneCount = sceneCount
|
this.scenes = scenes
|
keyScene = relatedScenes
|
exceptionCount = clues.size
|
}
|
|
return missionInfo
|
}
|
|
/**
|
* 生成走航任务详细信息
|
* 整合走航任务基本信息、关键场景、数据统计和异常数量,生成完整的任务详情报告
|
* @param keyScenes 关键场景列表,用于分析走航是否经过该区域
|
* @param mission 走航任务基本信息对象,包含任务ID、名称、时间等元数据
|
* @param pollutedClues 污染线索列表,用于提取关键场景信息
|
* @param data 实时监测数据列表,用于计算环境因子统计信息
|
* @param minDis 最小距离,用于判断走航是否经过关键场景
|
* @return 包含详细信息的MissionDetail对象,包括:
|
* - 任务基本信息(继承自Mission类)
|
* - 关键场景列表(TYPE19和TYPE20类型的场景)
|
* - 环境因子统计数据(平均值、最小值、最大值)
|
* - 异常数据点数量
|
*/
|
fun generateMissionDetail(
|
keyScenes: List<SceneInfo?>,
|
mission: Mission,
|
pollutedClues: List<PollutedClue?>,
|
data: List<BaseRealTimeData>,
|
minDis: Double = 100.0,
|
): MissionDetail {
|
// 创建任务详情对象并复制基本信息
|
val missionDetail = MissionDetail()
|
BeanUtils.copyProperties(mission, missionDetail)
|
|
// 提取途径关键场景信息(计算走航路线是否与关键场景距离较近)
|
// val relatedScenes = mutableListOf<SceneInfo>()
|
// data.forEach { d ->
|
// // 跳过缺少经纬度的数据点
|
// if (d.longitude == null || d.latitude == null) {
|
// return@forEach
|
// }
|
// // 转换为GCJ02坐标系
|
// val point = MapUtil.wgs84ToGcj02(d.longitude!!.toDouble() to d.latitude!!.toDouble())
|
// keyScenes.forEach ks@{ k ->
|
// // 跳过缺少经纬度的场景
|
// if (k?.longitude == null || k.latitude == null) {
|
// return@ks
|
// }
|
// // 检查是否未添加过
|
// if (!relatedScenes.contains(k)) {
|
// // 计算距离
|
// val distance = MapUtil.getDistance(
|
// k.longitude!!.toDouble(),
|
// k.latitude!!.toDouble(),
|
// point.first,
|
// point.second
|
// )
|
// // 检查是否距离小于阈值
|
// if (distance < minDis) {
|
// relatedScenes.add(k)
|
// }
|
// }
|
// }
|
// }
|
// 存储与任务相关联的关键场景信息
|
// missionDetail.keyScene = relatedScenes
|
|
// 计算环境因子统计数据(平均值、最小值、最大值)
|
missionDetail.dataStatistics = data.calDataStatistics()
|
|
// 异常数据点数量统计
|
// val clues = pollutedClues.filter { it?.msgType == MsgType.PolClue.value }
|
// missionDetail.exceptionCount = clues.size
|
|
return missionDetail
|
}
|
}
|