package com.flightfeather.uav.biz.dataanalysis
|
|
import com.flightfeather.uav.biz.dataanalysis.model.DataAnalysisConfig
|
import com.flightfeather.uav.domain.entity.BaseRealTimeData
|
|
/**
|
* 连续类型的异常分析基类,适用于当前数据与相邻数据之间有关联关系的情况
|
*/
|
abstract class BaseExceptionContinuous(config: DataAnalysisConfig) : BaseExceptionAnalysis(config) {
|
|
companion object {
|
// 记录异常数据段时,分别向起始前和末尾后额外记录的数据个数偏移量
|
private const val OFFSET = 10
|
}
|
|
// 起始数据下标
|
protected var sIndex = mutableListOf<Int>()
|
|
// 起始数据对象
|
protected var startData = mutableListOf<BaseRealTimeData?>()
|
|
// 末尾数据下标
|
protected var eIndex = mutableListOf<Int>()
|
|
// 末尾数据对象
|
protected var lastData: BaseRealTimeData? = null
|
|
// 异常数据段
|
protected var exceptionData = mutableListOf<MutableList<BaseRealTimeData>>()
|
|
// 起始数据与末尾数据间隔
|
open var durationCount = 1
|
protected var existException = mutableListOf<Boolean>()
|
|
/**
|
* 判断是否满足异常条件
|
*/
|
abstract fun judgeException(p: BaseRealTimeData?, n: BaseRealTimeData): List<Boolean>
|
|
/**
|
* 判断异常出现的连续时长是否满足条件
|
*/
|
abstract fun judgeDuration(sIndex: Int, eIndex: Int): Boolean
|
|
override fun init() {
|
super.init()
|
lastData = null
|
repeat(config.factorCount) {
|
startData.add(null)
|
sIndex.add(0)
|
eIndex.add(-1)
|
existException.add(false)
|
exceptionData.add(mutableListOf())
|
}
|
}
|
|
override fun onNextData(data: BaseRealTimeData) {
|
val isContinue = isContinuous(lastData, data)
|
val hasException = judgeException(lastData, data)
|
repeat(config.factorCount) { i ->
|
eIndex[i]++
|
// 起始数据
|
if (lastData == null) {
|
refreshAfterCheckResult(i, data)
|
}
|
// 判断相邻数据是否连续并且是否满足异常判断
|
if (!isContinue) {
|
checkResult()
|
// 数据不连续时,记录异常情况
|
if (eIndex[i] - sIndex[i] >= durationCount) {
|
refreshAfterCheckResult(i, data)
|
}
|
} else {
|
if (hasException[i]) {
|
existException[i] = true
|
exceptionData[i].add(data)
|
} else {
|
// 异常不再重复出现时,记录异常情况
|
checkResult()
|
if (eIndex[i] - sIndex[i] >= durationCount) {
|
refreshAfterCheckResult(i, data)
|
}
|
}
|
}
|
}
|
lastData = data
|
}
|
|
override fun onDone() {
|
checkResult()
|
}
|
|
fun refreshAfterCheckResult(i:Int, data: BaseRealTimeData) {
|
sIndex[i] = eIndex[i]
|
startData[i] = data
|
exceptionData[i].clear()
|
exceptionData[i].add(data)
|
}
|
|
/**
|
* 检查连续异常结束时,是否符合异常存储条件
|
*/
|
open fun checkResult(index: Int? = null) {
|
if (index != null) {
|
if (existException[index] && judgeDuration(sIndex[index], eIndex[index])) {
|
startData[index]?.let {
|
resultList.add(newResult(it, lastData, index, exceptionData[index]))
|
}
|
existException[index] = false
|
}
|
} else {
|
repeat(config.factorCount) { i ->
|
if (existException[i] && judgeDuration(sIndex[i], eIndex[i])) {
|
startData[i]?.let {
|
resultList.add(newResult(it, lastData, i, exceptionData[i]))
|
}
|
existException[i] = false
|
}
|
}
|
}
|
}
|
}
|