feiyu02
2024-08-27 9ed0b1847912221197697791d69e01ccae17f5b9
src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt
@@ -1,9 +1,20 @@
package com.flightfeather.uav.domain.entity
import com.flightfeather.uav.biz.dataprocess.AvgPair
import com.flightfeather.uav.common.utils.DateUtil
import com.flightfeather.uav.lightshare.bean.DataVo
import com.flightfeather.uav.socket.bean.AirData
import com.flightfeather.uav.socket.eunm.FactorType
import java.math.BigDecimal
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.*
import javax.persistence.Column
import javax.persistence.Id
import kotlin.math.atan
import kotlin.math.cos
import kotlin.math.round
import kotlin.math.sin
/**
 * 实时监测数据基类
@@ -58,6 +69,9 @@
    @Column(name = "NOI")
    var noi: Float? = null
    @Column(name = "NO")
    var no: Float? = null
    var velocity: Float? = null
    @Column(name = "wind_speed")
@@ -67,4 +81,244 @@
    var windDirection: Float? = null
    var height: Float? = null
    fun toDataVo() = DataVo().apply {
        this.time = DateUtil.instance.dateToString(dataTime, DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS)
        this.deviceCode = this@BaseRealTimeData.deviceCode
        this.lng = longitude?.toDouble()
        this.lat = latitude?.toDouble()
        this.values = mutableListOf<AirData>().apply {
            add(AirData().apply { setData(FactorType.NO2, no2) })
            add(AirData().apply { setData(FactorType.CO, co) })
            add(AirData().apply { setData(FactorType.H2S, h2s) })
            add(AirData().apply { setData(FactorType.SO2, so2) })
            add(AirData().apply { setData(FactorType.O3, o3) })
            add(AirData().apply { setData(FactorType.PM25, pm25) })
            add(AirData().apply { setData(FactorType.PM10, pm10) })
            add(AirData().apply { setData(FactorType.TEMPERATURE, temperature) })
            add(AirData().apply { setData(FactorType.HUMIDITY, humidity) })
            add(AirData().apply { setData(FactorType.VOC, voc) })
            add(AirData().apply { setData(FactorType.NOI, noi) })
            add(AirData().apply { setData(FactorType.LNG, lng) })
            add(AirData().apply { setData(FactorType.LAT, lat) })
            add(AirData().apply { setData(FactorType.VELOCITY, velocity) })
            add(AirData().apply {
                setData(FactorType.TIME, dataTime?.time?.toDouble())
                statusList = listOf(time ?: "")
            })
            add(AirData().apply { setData(FactorType.WIND_SPEED, windSpeed) })
            add(AirData().apply { setData(FactorType.WIND_DIRECTION, windDirection) })
            add(AirData().apply { setData(FactorType.HEIGHT, height) })
        }
    }
    fun getByFactorIndex(i: Int): Float? {
        return when (i) {
            0 -> no2
            1 -> co
            2 -> h2s
            3 -> so2
            4 -> o3
            5 -> pm25
            6 -> pm10
            7 -> voc
            else -> null
        }
    }
    fun getByFactorType(type: FactorType?): Float? {
        return when (type) {
            FactorType.NO2 -> no2
            FactorType.CO -> co
            FactorType.H2S -> h2s
            FactorType.SO2 -> so2
            FactorType.O3 -> o3
            FactorType.PM25 -> pm25
            FactorType.PM10 -> pm10
            FactorType.TEMPERATURE -> temperature
            FactorType.HUMIDITY -> humidity
            FactorType.VOC -> voc
            FactorType.NOI -> noi
            FactorType.LNG -> longitude?.toFloat()
            FactorType.LAT -> latitude?.toFloat()
            FactorType.VELOCITY -> velocity
//            FactorType.TIME -> noi
            FactorType.WIND_SPEED -> windSpeed
            FactorType.WIND_DIRECTION -> windDirection
            FactorType.HEIGHT -> height
            else -> null
        }
    }
}
fun List<BaseRealTimeData>.avg(): BaseRealTimeData {
    //风向采用单位矢量法求取均值
    var u = .0//东西方位分量总和
    var v = .0//南北方位分量总和
    var c = 0//风向数据计数
    //除风向外的其他因子采用算术平均法求取均值
    val tmpList = mutableListOf<AvgPair>()
    repeat(17) {
        tmpList.add(AvgPair(0f, 0))
    }
    forEach {
        //风向
        it.windDirection?.let {w ->
            val r = Math.toRadians(w.toDouble())
            u += sin(r)
            v += cos(r)
            c++
        }
        //其余因子
        tmpList[0].apply {
            it.latitude?.let {
                t += it.toFloat()
                this.c++
            }
        }
        tmpList[1].apply {
            it.longitude?.let {
                t += it.toFloat()
                this.c++
            }
        }
        tmpList[2].apply {
            it.altitude?.let {
                t += it
                this.c++
            }
        }
        tmpList[3].apply {
            it.no2?.let {
                t += it
                this.c++
            }
        }
        tmpList[4].apply {
            it.co?.let {
                t += it
                this.c++
            }
        }
        tmpList[5].apply {
            it.h2s?.let {
                t += it
                this.c++
            }
        }
        tmpList[6].apply {
            it.so2?.let {
                t += it
                this.c++
            }
        }
        tmpList[7].apply {
            it.o3?.let {
                t += it
                this.c++
            }
        }
        tmpList[8].apply {
            it.pm25?.let {
                t += it
                this.c++
            }
        }
        tmpList[9].apply {
            it.pm10?.let {
                t += it
                this.c++
            }
        }
        tmpList[10].apply {
            it.temperature?.let {
                t += it
                this.c++
            }
        }
        tmpList[11].apply {
            it.humidity?.let {
                t += it
                this.c++
            }
        }
        tmpList[12].apply {
            it.voc?.let {
                t += it
                this.c++
            }
        }
        tmpList[13].apply {
            it.noi?.let {
                t += it
                this.c++
            }
        }
        tmpList[14].apply {
            it.velocity?.let {
                t += it
                this.c++
            }
        }
        tmpList[15].apply {
            it.windSpeed?.let {
                t += it
                this.c++
            }
        }
        tmpList[16].apply {
            it.height?.let {
                t += it
                this.c++
            }
        }
    }
    return RealTimeDataGridMin().apply {
        val time = LocalDateTime.ofInstant(get(0).dataTime?.toInstant(), ZoneId.systemDefault()).withSecond(0)
        deviceCode = get(0).deviceCode
        dataTime = Date.from(time.atZone(ZoneId.systemDefault()).toInstant())
        createTime = dataTime
        latitude = tmpList[0].avg().toBigDecimal()
        longitude = tmpList[1].avg().toBigDecimal()
        altitude = tmpList[2].avg()
        no2 = tmpList[3].avg()
        co = tmpList[4].avg()
        h2s = tmpList[5].avg()
        so2 = tmpList[6].avg()
        o3 = tmpList[7].avg()
        pm25 = tmpList[8].avg()
        pm10 = tmpList[9].avg()
        temperature = tmpList[10].avg()
        humidity = tmpList[11].avg()
        voc = tmpList[12].avg()
        noi = tmpList[13].avg()
        velocity = tmpList[14].avg()
        windSpeed = tmpList[15].avg()
        height = tmpList[16].avg()
        if (c != 0) {
            val avgU = u / c
            val avgV = v / c
            var a = atan(avgU / avgV)
            a = Math.toDegrees(a)
            /**
             * avgU>0;avgV>0: 真实角度处于第一象限,修正值为+0°
             * avgU>0;avgV<0: 真实角度处于第二象限,修正值为+180°
             * avgU<0;avgV<0: 真实角度处于第三象限,修正值为+180°
             * avgU<0;avgV>0: 真实角度处于第四象限,修正值为+360°
             */
            a += if (avgV > 0) {
                if (avgU > 0) 0 else 360
            } else {
                180
            }
            windDirection = round(a.toFloat())
        }
    }
}