src/main/kotlin/com/flightfeather/uav/model/epw/EPWDataPrep.kt
@@ -1,11 +1,16 @@
package com.flightfeather.uav.model.epw
import com.flightfeather.uav.common.utils.DateUtil
import com.flightfeather.uav.common.utils.GsonUtils
import com.flightfeather.uav.lightshare.bean.CompanySOP
import com.flightfeather.uav.lightshare.bean.DataVo
import com.flightfeather.uav.model.BaseDataPrep
import com.flightfeather.uav.socket.bean.AirData
import com.flightfeather.uav.socket.bean.AirDataPackage
import com.flightfeather.uav.socket.eunm.FactorType
import kotlin.math.max
import kotlin.math.min
import kotlin.math.round
import kotlin.math.sqrt
class EPWDataPrep : BaseDataPrep<DataVo, CompanySOP>() {
@@ -20,6 +25,8 @@
    private val calTypes =
//        emptyList<String>()
        WeightType.prep
    private val lastData = mutableListOf<DataVo>()
    override fun mDataPrep(mDataList: List<DataVo>): List<DataVo> {
        mDataList.forEach {
@@ -40,6 +47,9 @@
//        }
        var i = ncal
        if (lastData.isNotEmpty()) {
            i = 0
        }
        while (i < mDataList.size) {
            for (y in mDataList[i].values?.indices ?: 0..0) {
                val it = mDataList[i].values?.get(y) ?: continue
@@ -49,9 +59,16 @@
                it.factorData ?: continue
                if (it.factorData!! > vMax) {
                    val list = mDataList.subList(i - ncal, i)
                    val lastDataIndex = i
                    val thisIndex = if (i-ncal<0) 0 else i - ncal
                    val list = mutableListOf<DataVo>()
                    if (lastDataIndex < lastData.size) {
                        list.addAll(lastData.subList(lastDataIndex, lastData.lastIndex + 1))
                    }
                    list.addAll(mDataList.subList(thisIndex, i))
                    // 去除无效值的平均
                    val avg = average(list, it.factorName)
                    val avg = average(list, it.factorName) ?: continue
                    // 去除无效值的标准差
                    val std = standardDeviation(avg.first, list, it.factorName)
                    // 合理最大值
@@ -73,6 +90,12 @@
            i++
        }
        lastData.clear()
        val s = if ((mDataList.lastIndex - ncal + 1) < 0) 0 else mDataList.lastIndex - ncal + 1
        mDataList.subList(s, mDataList.lastIndex + 1).forEach {
            lastData.add(it.copy())
        }
        return mDataList
    }
@@ -80,20 +103,96 @@
        return sopList
    }
    fun mDataPrep2(dataPackage: AirDataPackage): List<DataVo> {
        val vo = dataPackage.toDataVo()
        return mDataPrep2(listOf(vo))
    }
    fun mDataPrep2(mDataList: List<DataVo>): List<DataVo> {
        var i = ncal
        if (lastData.isNotEmpty()) {
            i = 0
        }
        while (i < mDataList.size) {
            for (y in mDataList[i].values?.indices ?: 0..0) {
                val it = mDataList[i].values?.get(y) ?: continue
                if (!calTypes.contains(it.factorName)) continue
                val vMax = FactorType.getVMax(it.factorName) ?: continue
//                it.factorData ?: continue
                if (it.factorData!! > vMax) {
                    val lastDataIndex = i
                    val thisIndex = if (i-ncal<0) 0 else i - ncal
                    val list = mutableListOf<DataVo>()
                    if (lastDataIndex < lastData.size) {
                        list.addAll(lastData.subList(lastDataIndex, lastData.lastIndex + 1))
                    }
                    list.addAll(mDataList.subList(thisIndex, i))
                    // 去除无效值的平均,当所有数据都是无效值时,暂不做处理
                    average(list, it.factorName)?.let { avg ->
                        // 去除无效值的标准差
                        val std = standardDeviation(avg.first, list, it.factorName)
                        // 合理最大值
                        val max = max(avg.first + std * nstd, avg.first + avg.first * xratio)
                        // 合理最小值
                        val min = min(avg.first - std * nstd, avg.first / (1 + xratio))
                        // 数据不处于合理范围并且有效个数达标时,采用计算所得均值代替原始值
                        if (avg.second > max(ncal / 5, 2)
                            && (it.factorData!! < min || it.factorData!! > max)
                        ) {
                            // 原始数据
//                        it.factorData = null
                            it.factorData = avg.first
                        }
                    }
                }
            }
            i++
        }
        // 将新数据的至多最后15个保存下来(已经过预处理),用于下一次的判断
        val newList = mutableListOf<DataVo>()
        val s = if ((mDataList.lastIndex - ncal + 1) < 0) 0 else mDataList.lastIndex - ncal + 1
        mDataList.subList(s, mDataList.lastIndex + 1).forEach {
            newList.add(it.copy())
        }
        // 当新数据与旧数据采样时间差超过1分钟时,认为两组数据已无关联性,清空旧数据
        if (lastData.isNotEmpty() && newList.isNotEmpty()) {
            val lastTime = DateUtil.instance.StringToDate(lastData.last().time)
            val thisTime = DateUtil.instance.StringToDate(newList.first().time)
            if (thisTime?.time?.minus(lastTime?.time ?: 0) ?: 0 >= (60 * 1000)) {
                lastData.clear()
            }
        }
        lastData.addAll(newList)
        // 确保保存的数据最多只有最新的15个
        while (lastData.size > ncal) {
            lastData.removeAt(0)
        }
        return mDataList
    }
    /**
     * 去除无效值的平均
     * @param list 监测数据
     * @return 均值和有效数据个数
     */
    private fun average(list: List<DataVo>, factorName:String?): Pair<Double, Int> {
    private fun average(list: List<DataVo>, factorName:String?): Pair<Double, Int>? {
        var t = 0.0
        var c = 0
        list.forEach {
            for (i in it.values?.indices ?: 0..0) {
                val f = it.values?.get(i)
                if (f?.factorName == factorName) {
                    if (f?.factorData != null) {
                        t += f.factorData!!
                    val range = FactorType.getRange(f?.factorName) ?: continue
                    //判断数据是否在合理范围内
                    if (f?.factorData ?: 0.0 in range.first..range.second) {
                        t += f?.factorData!!
                        c++
                    }
                    break
@@ -104,10 +203,14 @@
        val avg = if (c == 0) {
            0.0
        } else {
            t / c
            round(t / c * 1000) / 1000
        }
        return Pair(avg, c)
        return if (c == 0) {
            null
        } else {
            Pair(avg, c)
        }
    }
    /**
@@ -120,8 +223,9 @@
            for (i in it.values?.indices ?: 0..0) {
                val f = it.values?.get(i)
                if (f?.factorName == factorName) {
                    if (f?.factorData != null) {
                        t += (f.factorData!! - avg) * (f.factorData!! - avg)
                    val range = FactorType.getRange(f?.factorName) ?: continue
                    if (f?.factorData ?: 0.0 in range.first..range.second) {
                        t += (f?.factorData!! - avg) * (f.factorData!! - avg)
                        c++
                    }
                    break