package com.flightfeather.uav.biz.sourcetrace.exceptiontype
|
|
import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag
|
import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType
|
import com.flightfeather.uav.biz.sourcetrace.RealTimeAnalysisConfig
|
import com.flightfeather.uav.common.utils.MapUtil
|
import com.flightfeather.uav.domain.entity.BaseRealTimeData
|
import com.flightfeather.uav.socket.eunm.FactorType
|
import java.time.Duration
|
import java.time.LocalDateTime
|
import java.time.ZoneId
|
|
/**
|
* 量级突变异常溯源
|
* @date 2025/5/13
|
* @author feiyu02
|
*/
|
@Deprecated("2025.5.29, 逻辑与业务不匹配,后续删除")
|
class RealTimeExceptionValueMutation : BaseRealTimeException<ExceptionTag> {
|
|
constructor(config: RealTimeAnalysisConfig) : super(config, ExceptionTag::class.java)
|
|
constructor(config: RealTimeAnalysisConfig, callback: NewExceptionCallback) : super(config, callback, ExceptionTag::class.java)
|
|
/**
|
* 本异常的连续发生次数会根据异常的程度变化
|
* 当突变的量级超过设定值1倍时,连续发生次数要求减少1倍
|
*/
|
private var special = false
|
|
override fun getExceptionType(): ExceptionType {
|
return ExceptionType.TYPE4
|
}
|
|
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) {
|
res[f] = (false)
|
return@forEach
|
}
|
val pValue = p.getByFactorType(f)!!
|
val nValue = n.getByFactorType(f)!!
|
// 计算后一个数据相比于前一个数据的变化率
|
val r = (nValue - pValue) / pValue
|
// 当变化率为正数(即数据上升时),且大于设定值时,认为是异常情况
|
val b1 = r >= (2 * config.mutationRate)
|
val b2 = r >= config.mutationRate
|
if (b1) special = true
|
res[f] = (b1 || b2)
|
}
|
|
return res
|
}
|
|
override fun judgeExceptionCount(tag: ExceptionTag, factorType: FactorType?): Boolean {
|
val count = tag.exceptionData.size
|
|
val b1 = special && count >= (config.mutationNum / 2)
|
val b2 = count >= config.mutationNum
|
special = false
|
return b1 || b2
|
}
|
|
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
|
}
|
}
|