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
|
|
/**
|
* 数据变化速率异常
|
* @date 2025/6/10
|
* @author feiyu02
|
*/
|
abstract class BaseRTExcChangeRate(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 changeRate: MutableMap<FactorType, RTExcWindLevelConfig.WindLevelCondition>
|
|
override fun getExceptionType(): ExceptionType {
|
return ExceptionType.TYPE9
|
}
|
|
override fun judgeDataScale(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> {
|
val res = mutableMapOf<FactorType, Boolean>()
|
config.factorFilter.mainList().forEach { f ->
|
if (p?.getByFactorType(f) == null || n.getByFactorType(f) == null || n.windSpeed == null) {
|
res[f] = (false)
|
return@forEach
|
}
|
val nValue = n.getByFactorType(f)!!
|
val minValue = FactorType.getVMin(f)
|
res[f] = nValue >= minValue
|
}
|
return res
|
}
|
|
override fun judgeException(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> {
|
val res = mutableMapOf<FactorType, Boolean>()
|
config.factorFilter.mainList().forEach { f ->
|
if (p?.getByFactorType(f) == null || n.getByFactorType(f) == null || n.windSpeed == null) {
|
res[f] = (false)
|
return@forEach
|
}
|
|
val rate = changeRate[f]
|
|
if (rate != null && n.windSpeed!! in rate.windSpeed.first..rate.windSpeed.second) {
|
val pValue = p.getByFactorType(f)!!
|
val nValue = n.getByFactorType(f)!!
|
// 计算后一个数据相比于前一个数据的变化速率
|
val v = (nValue - pValue)
|
val b1 = v in rate.mutationRate.first..rate.mutationRate.second
|
println("因子:${f.des},速率:${v},${b1}")
|
res[f] = b1
|
} else {
|
res[f] = false
|
}
|
}
|
return res
|
}
|
|
override fun judgeExceptionCount(tag: ExceptionTag, factorType: FactorType?): Boolean {
|
return tag.exceptionData.size >= (changeRate[factorType]?.countLimit ?: 1)
|
}
|
|
override fun needCut(tag: ExceptionTag, hasException: Boolean?, data: BaseRealTimeData): Boolean {
|
// 按照时长和距离限制将异常截取
|
if (tag.exceptionData.isEmpty()) return false
|
|
val se = tag.exceptionData.first()
|
val ee = data
|
|
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, factorType: FactorType): Boolean {
|
// 异常出现等于限定次数时,就需要形成污染线索
|
return judgeExceptionCount(tag, factorType)
|
}
|
|
override fun newResult(tag: ExceptionTag, factor: FactorFilter.SelectedFactor): PollutedClue {
|
return PollutedClue(tag, factor, getExceptionType(), config, changeRate[factor.main])
|
}
|
|
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)
|
// }
|
}
|
|
override fun mergeExceptionResult() {
|
super.mergeExceptionResult()
|
latestExceptionResult
|
latestCombinedResult
|
callback?.let { func ->
|
latestExceptionResult.forEach {
|
func.invoke(it as PollutedClue)
|
}
|
latestCombinedResult.forEach {
|
func.invoke(it as PollutedClue)
|
}
|
}
|
}
|
}
|