From eb3dd00b0b7fcda477229d518d250f9c842b790b Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期二, 21 十月 2025 17:45:44 +0800
Subject: [PATCH] 2025.10.21 1. 走航季度报告相关数据计算逻辑调整
---
src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt | 153 ++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 145 insertions(+), 8 deletions(-)
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt b/src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt
index e16d1f2..1066c78 100644
--- a/src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt
@@ -1,24 +1,32 @@
package com.flightfeather.uav.domain.entity
+import com.flightfeather.uav.biz.dataprocess.AvgPair
import com.flightfeather.uav.common.utils.DateUtil
-import com.flightfeather.uav.dataprocess.AvgPair
import com.flightfeather.uav.lightshare.bean.DataVo
+import com.flightfeather.uav.lightshare.bean.FactorStatistics
import com.flightfeather.uav.socket.bean.AirData
import com.flightfeather.uav.socket.eunm.FactorType
+import java.io.Serializable
import java.math.BigDecimal
import java.time.LocalDateTime
import java.time.ZoneId
-import java.time.ZoneOffset
+import java.time.temporal.ChronoUnit
import java.util.*
import javax.persistence.Column
+import javax.persistence.GeneratedValue
+import javax.persistence.GenerationType
import javax.persistence.Id
-import kotlin.math.*
+import kotlin.math.atan
+import kotlin.math.cos
+import kotlin.math.round
+import kotlin.math.sin
/**
* 瀹炴椂鐩戞祴鏁版嵁鍩虹被
*/
-open class BaseRealTimeData {
+open class BaseRealTimeData : Serializable {
@Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Int? = null
@Column(name = "device_code")
@@ -67,6 +75,9 @@
@Column(name = "NOI")
var noi: Float? = null
+ @Column(name = "NO")
+ var no: Float? = null
+
var velocity: Float? = null
@Column(name = "wind_speed")
@@ -106,11 +117,41 @@
add(AirData().apply { setData(FactorType.WIND_SPEED, windSpeed) })
add(AirData().apply { setData(FactorType.WIND_DIRECTION, windDirection) })
add(AirData().apply { setData(FactorType.HEIGHT, height) })
+ add(AirData().apply { setData(FactorType.NO, no) })
}
}
+
+ 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 -> dataTime?.time?.toFloat()
+ FactorType.WIND_SPEED -> windSpeed
+ FactorType.WIND_DIRECTION -> windDirection
+ FactorType.HEIGHT -> height
+ FactorType.NO -> no
+ else -> null
+ }
+ }
+
}
-fun List<RealTimeDataGrid>.avg(): RealTimeDataGridMin {
+fun List<BaseRealTimeData>.avg(onEach: (BaseRealTimeData) -> Unit = { }): BaseRealTimeData {
+ if (isEmpty()) {
+ return BaseRealTimeData()
+ }
//椋庡悜閲囩敤鍗曚綅鐭㈤噺娉曟眰鍙栧潎鍊�
var u = .0//涓滆タ鏂逛綅鍒嗛噺鎬诲拰
var v = .0//鍗楀寳鏂逛綅鍒嗛噺鎬诲拰
@@ -118,13 +159,14 @@
//闄ら鍚戝鐨勫叾浠栧洜瀛愰噰鐢ㄧ畻鏈钩鍧囨硶姹傚彇鍧囧��
val tmpList = mutableListOf<AvgPair>()
- repeat(17) {
+ repeat(18) {
tmpList.add(AvgPair(0f, 0))
}
forEach {
+ onEach(it)
//椋庡悜
- it.windDirection?.let {w ->
+ it.windDirection?.let { w ->
val r = Math.toRadians(w.toDouble())
u += sin(r)
v += cos(r)
@@ -233,10 +275,18 @@
this.c++
}
}
+ tmpList[17].apply {
+ it.no?.let {
+ t += it
+ this.c++
+ }
+ }
}
return RealTimeDataGridMin().apply {
- val time = LocalDateTime.ofInstant(get(0).dataTime?.toInstant(), ZoneId.systemDefault()).withSecond(0)
+ val time = LocalDateTime
+ .ofInstant(get(0).dataTime?.toInstant() ?: Date().toInstant(), ZoneId.systemDefault())
+ .withSecond(0)
deviceCode = get(0).deviceCode
dataTime = Date.from(time.atZone(ZoneId.systemDefault()).toInstant())
createTime = dataTime
@@ -257,11 +307,13 @@
velocity = tmpList[14].avg()
windSpeed = tmpList[15].avg()
height = tmpList[16].avg()
+ no = tmpList[17].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: 鐪熷疄瑙掑害澶勪簬绗竴璞¢檺锛屼慨姝e�间负+0掳
* avgU>0;avgV<0: 鐪熷疄瑙掑害澶勪簬绗簩璞¢檺锛屼慨姝e�间负+180掳
@@ -276,4 +328,89 @@
windDirection = round(a.toFloat())
}
}
+}
+
+/**
+ * 璁$畻瀹炴椂鐩戞祴鏁版嵁鍒楄〃鐨勭粺璁′俊鎭�
+ * 涓烘瘡绉嶇幆澧冨洜瀛愯绠楁渶灏忓�笺�佹渶澶у�煎拰骞冲潎鍊�
+ * @param granularity 鏁版嵁棰楃矑搴︼紝鍙�夊�间负SECOND, MINUTE, HOUR, 榛樿MINUTE
+ * @return 鍖呭惈鍚勭幆澧冨洜瀛愮粺璁′俊鎭殑FactorStatistics鍒楄〃
+ * 姣忎釜FactorStatistics瀵硅薄鍖呭惈鍥犲瓙绫诲瀷銆佹渶灏忓�笺�佹渶澶у�煎拰骞冲潎鍊�
+ */
+fun List<BaseRealTimeData>.calDataStatistics(granularity: String): List<FactorStatistics> {
+
+ // 妫�鏌ラ绮掑害鏄惁鏈夋晥
+ if (granularity !in listOf("SECOND", "MINUTE", "HOUR")) {
+ throw IllegalArgumentException("鏃犳晥鐨勯绮掑害鍙傛暟锛屽彲閫夊�间负SECOND, MINUTE, HOUR")
+ }
+
+ val groupedData = when (granularity) {
+ "SECOND" -> this
+ "MINUTE" -> groupBy { it.dataTime?.toInstant()?.truncatedTo(ChronoUnit.MINUTES) }.mapValues {
+ it.value.avg().apply {
+ dataTime = Date.from(it.key)
+ createTime = dataTime
+ }
+ }.values.toList()
+ "HOUR" -> groupBy { it.dataTime?.toInstant()?.truncatedTo(ChronoUnit.HOURS) }.mapValues {
+ it.value.avg().apply {
+ dataTime = Date.from(it.key)
+ createTime = dataTime
+ }
+ }.values.toList()
+ else -> throw IllegalArgumentException("鏃犳晥鐨勯绮掑害鍙傛暟锛屽彲閫夊�间负SECOND, MINUTE, HOUR")
+ }
+
+ // 鍒濆鍖栧悇鐜鍥犲瓙鐨勭粺璁″璞″垪琛�
+ val statistics = mutableListOf<FactorStatistics>()
+ listOf(
+ FactorType.NO2,
+ FactorType.CO,
+ FactorType.H2S,
+ FactorType.SO2,
+ FactorType.O3,
+ FactorType.PM25,
+ FactorType.PM10,
+ FactorType.VOC,
+ FactorType.NOI,
+ FactorType.VELOCITY,
+ FactorType.WIND_SPEED,
+ FactorType.HEIGHT,
+ FactorType.NO
+ ).forEach { statistics.add(FactorStatistics(it)) }
+
+ // 璁$畻骞冲潎鍊煎苟鍚屾椂鏇存柊鍚勫洜瀛愮殑鏈�灏忓�煎拰鏈�澶у��
+ val avgData = groupedData.avg { item ->
+ // 鏇存柊姣忎釜鍥犲瓙鐨勬渶灏忓拰鏈�澶у��
+ statistics[0].updateMinAndMaxValue(item.no2)
+ statistics[1].updateMinAndMaxValue(item.co)
+ statistics[2].updateMinAndMaxValue(item.h2s)
+ statistics[3].updateMinAndMaxValue(item.so2)
+ statistics[4].updateMinAndMaxValue(item.o3)
+ statistics[5].updateMinAndMaxValue(item.pm25)
+ statistics[6].updateMinAndMaxValue(item.pm10)
+ statistics[7].updateMinAndMaxValue(item.voc)
+ statistics[8].updateMinAndMaxValue(item.noi)
+ statistics[9].updateMinAndMaxValue(item.velocity)
+ statistics[10].updateMinAndMaxValue(item.windSpeed)
+ statistics[11].updateMinAndMaxValue(item.height)
+ statistics[12].updateMinAndMaxValue(item.no)
+ }
+
+ // 灏嗚绠楀緱鍒扮殑骞冲潎鍊艰缃埌瀵瑰簲鐨勭粺璁″璞′腑
+ statistics[0].avgValue = avgData.no2 ?: 0f
+ statistics[1].avgValue = avgData.co ?: 0f
+ statistics[2].avgValue = avgData.h2s ?: 0f
+ statistics[3].avgValue = avgData.so2 ?: 0f
+ statistics[4].avgValue = avgData.o3 ?: 0f
+ statistics[5].avgValue = avgData.pm25 ?: 0f
+ statistics[6].avgValue = avgData.pm10 ?: 0f
+ statistics[7].avgValue = avgData.voc ?: 0f
+ statistics[8].avgValue = avgData.noi ?: 0f
+ statistics[9].avgValue = avgData.velocity ?: 0f
+ statistics[10].avgValue = avgData.windSpeed ?: 0f
+ statistics[11].avgValue = avgData.height ?: 0f
+ statistics[12].avgValue = avgData.no ?: 0f
+
+ return statistics
}
\ No newline at end of file
--
Gitblit v1.9.3