package com.flightfeather.uav.biz.sourcetrace.exceptiontype
|
|
import com.flightfeather.uav.biz.FactorFilter
|
import com.flightfeather.uav.biz.dataanalysis.BaseExceptionContinuous
|
import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag
|
import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType
|
import com.flightfeather.uav.biz.sourcetrace.config.RTExcWindLevelConfig
|
import com.flightfeather.uav.biz.sourcetrace.model.PollutedClue
|
import com.flightfeather.uav.common.utils.MapUtil
|
import com.flightfeather.uav.domain.entity.BaseRealTimeData
|
import com.flightfeather.uav.lightshare.eunm.ExceptionStatusType
|
import com.flightfeather.uav.socket.eunm.FactorType
|
import java.time.Duration
|
import java.time.LocalDateTime
|
import java.time.ZoneId
|
|
|
// 异常数据生成回调类
|
typealias NewPolluteClueCallback = (ex: PollutedClue) -> Unit
|
/**
|
* 不同风速下,数据突变异常基类
|
* @date 2025/5/29
|
* @author feiyu02
|
*/
|
abstract class BaseRTExcWindLevel(config: RTExcWindLevelConfig) :
|
BaseExceptionContinuous<ExceptionTag, RTExcWindLevelConfig, PollutedClue>(config, ExceptionTag::class.java) {
|
|
constructor(config: RTExcWindLevelConfig, callback: NewPolluteClueCallback) : this(config){
|
this.callback = callback
|
}
|
|
private var callback: NewPolluteClueCallback? = null
|
|
abstract var windLevelCondition: RTExcWindLevelConfig.WindLevelCondition
|
|
override fun getExceptionType(): ExceptionType {
|
return ExceptionType.TYPE4
|
}
|
|
override fun judgeException(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> {
|
val res = mutableMapOf<FactorType, Boolean>()
|
println()
|
config.factorFilter.mainList().forEach { f ->
|
if (p?.getByFactorType(f) == null || n.getByFactorType(f) == null || n.windSpeed == null) {
|
res[f] = (false)
|
return@forEach
|
}
|
|
val con = windLevelCondition
|
|
if (n.windSpeed!! in con.windSpeed.first..con.windSpeed.second) {
|
println("风速:${n.windSpeed},[${con.windSpeed.first} - ${con.windSpeed.second}]")
|
val pValue = p.getByFactorType(f)!!
|
val nValue = n.getByFactorType(f)!!
|
// 计算后一个数据相比于前一个数据的变化率
|
val r = (nValue - pValue) / pValue
|
val b1 = r >= con.mutationRate.first && r < con.mutationRate.second
|
println("因子:${f.des},幅度:${r},限定:${con.mutationRate.first},${b1}")
|
res[f] = b1
|
} else {
|
res[f] = false
|
}
|
}
|
|
|
return res
|
}
|
|
override fun judgeExceptionCount(tag: ExceptionTag): Boolean {
|
return tag.exceptionData.size >= windLevelCondition.countLimit
|
}
|
|
override fun needCut(tag: ExceptionTag, hasException: Boolean?): Boolean {
|
// 按照时长和距离限制将异常截取
|
if (tag.exceptionData.isEmpty()) return false
|
|
val se = tag.exceptionData.first()
|
val ee = tag.exceptionData.last()
|
|
val sTime = LocalDateTime.ofInstant(se.dataTime?.toInstant(), ZoneId.systemDefault())
|
val eTime = LocalDateTime.ofInstant(ee.dataTime?.toInstant(), ZoneId.systemDefault())
|
val duration = Duration.between(sTime, eTime).toMinutes()
|
// 数据采样的时长超过限制时,需要截取
|
val b1 = duration > config.timeLimit
|
|
// 走航数据的距离超过限制时,需要截取
|
val b2 = if (se.longitude == null || se.latitude == null || ee.longitude == null || ee.latitude == null) {
|
false
|
} else {
|
val distance = MapUtil.getDistance(
|
se.longitude!!.toDouble(), se.latitude!!.toDouble(), ee.longitude!!
|
.toDouble(), ee.latitude!!.toDouble()
|
)
|
distance > config.distanceLimit
|
}
|
|
return b1 || b2
|
}
|
|
override fun immeExcCheck(tag: ExceptionTag): Boolean {
|
// 异常出现等于限定次数时,就需要形成污染线索
|
return tag.exceptionData.size == windLevelCondition.countLimit
|
}
|
|
override fun newResult(
|
start: BaseRealTimeData,
|
end: BaseRealTimeData?,
|
factor: FactorFilter.SelectedFactor,
|
exceptionData: List<BaseRealTimeData>,
|
): PollutedClue {
|
return PollutedClue(start, end, factor, exceptionData, getExceptionType(), config, windLevelCondition)
|
}
|
|
override fun onNewException(
|
tag: ExceptionTag,
|
factor: FactorFilter.SelectedFactor,
|
exceptionStatus: ExceptionStatusType,
|
) {
|
super.onNewException(tag, factor, exceptionStatus)
|
callback?.let { func ->
|
val exc = tag.exceptionResult.last()
|
func.invoke(exc as PollutedClue)
|
}
|
}
|
}
|