feiyu02
2024-05-31 da431c25dfe5122e4ed70372da36ede3e4eaec4a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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
                }
            }
        }
    }
}