feiyu02
2021-11-10 db7243622e8b5f4cc23de5594b2d973562f0b2a3
1. 添加网格化数据分钟均值计算逻辑
已修改3个文件
已添加2个文件
242 ■■■■■ 文件已修改
src/main/kotlin/com/flightfeather/uav/dataprocess/AverageUtil.kt 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/dataprocess/AvgPair.kt 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/domain/entity/RealTimeDataGrid.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/kotlin/com/flightfeather/uav/dataprocess/AverageUtil.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
package com.flightfeather.uav.dataprocess
/**
 * å‡å€¼è®¡ç®—工具,将一组连续数据转换为自定义周期的均值数据
 * è¦æ±‚传入的数据按照时间顺序排列,
 * @param onTag å®šä¹‰æ•°æ®æ ‡ç­¾èŽ·å–å›žè°ƒå‡½æ•°ï¼Œå½“å½“å‰æ•°æ®æ ‡ç­¾ä¸Žä¸Šä¸ªæ•°æ®æ ‡ç­¾ä¸åŒæ—¶ï¼Œå³è®¤ä¸ºä¸Šä¸€ç»„æ•°æ®ä¸ºåŒä¸€ç»„æ•°æ®ï¼Œéœ€æ±‚å‡ºå‡å€¼
 * @param onAvg å®šä¹‰å‡å€¼è®¡ç®—方法
 */
class AverageUtil<T : Any>(var onTag: (d: T) -> String, var onAvg: (list: List<T>) -> T) {
    // ç¼“存最新的tag
    private var lastTag: String? = null
    // ä¸´æ—¶æ•°æ®ç¼“å­˜
    private val dataSet = mutableListOf<T>()
    // è½¬æ¢ç»“æžœ
    private val result = mutableListOf<T>()
    /**
     * å°†æ•°æ®é›†è½¬æ¢ä¸ºå‡å€¼æ•°æ®
     * @param list åŽŸå§‹æ•°æ®
     * @return å‡å€¼æ•°æ®
     */
    fun avg(list: List<T>): List<T> {
        // åˆå§‹åŒ–所有变量
        clear()
        // è®¡ç®—均值
        list.forEach {
            val tag = onTag(it)
            // ç¬¬ä¸€æ¡æ•°æ®å’Œtag相同时,将数据放入临时缓存列表
            if (lastTag == null || tag == lastTag) {
                dataSet.add(it)
            }
            // å½“tag不同时,计算之前数据的均值,同时情况临时数据缓存,添加当前的新数据
            else {
                result.add(onAvg(dataSet))
                dataSet.clear()
                dataSet.add(it)
            }
            lastTag = tag
        }
        // åˆ—表循环结束后,若缓存列表中仍有数据,则计算最后一个均值
        if (dataSet.isNotEmpty()) {
            result.add(onAvg(dataSet))
        }
        return result
    }
    private fun clear() {
        lastTag = null
        dataSet.clear()
        result.clear()
    }
}
src/main/kotlin/com/flightfeather/uav/dataprocess/AvgPair.kt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
package com.flightfeather.uav.dataprocess
data class AvgPair(
    var t: Float, var c: Int
){
    fun avg(): Float = if (c == 0) {
        0f
    } else {
        t / c
    }
}
src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt
@@ -1,13 +1,19 @@
package com.flightfeather.uav.domain.entity
import com.flightfeather.uav.common.utils.DateUtil
import com.flightfeather.uav.dataprocess.AvgPair
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.time.ZoneOffset
import java.util.*
import javax.persistence.Column
import javax.persistence.Id
import kotlin.math.cos
import kotlin.math.sin
/**
 * å®žæ—¶ç›‘测数据基类
@@ -103,4 +109,153 @@
            add(AirData().apply { setData(FactorType.HEIGHT, height) })
        }
    }
}
fun List<RealTimeDataGrid>.avg(): RealTimeDataGrid {
    //风向采用单位矢量法求取均值
    var u = 0f//东西方位分量总和
    var v = 0f//南北方位分量总和
    var c = 0//风向数据计数
    //除风向外的其他因子采用算术平均法求取均值
    val tmpList = mutableListOf<AvgPair>()
    repeat(17) {
        tmpList.add(AvgPair(0f, 0))
    }
    forEach {
        //风向
        it.windDirection?.let {w ->
            u += sin(w)
            v += cos(w)
            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 RealTimeDataGrid().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()
    }
}
src/main/kotlin/com/flightfeather/uav/domain/entity/RealTimeDataGrid.java
@@ -6,4 +6,5 @@
@Table(name = "real_time_data_grid")
public class RealTimeDataGrid extends BaseRealTimeData {
}
src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/RealTimeDataServiceImpl.kt
@@ -4,6 +4,7 @@
import com.flightfeather.uav.common.utils.ExcelUtil
import com.flightfeather.uav.common.utils.FileExchange
import com.flightfeather.uav.common.utils.GsonUtils
import com.flightfeather.uav.dataprocess.AverageUtil
import com.flightfeather.uav.domain.entity.*
import com.flightfeather.uav.domain.mapper.RealTimeDataGridMapper
import com.flightfeather.uav.domain.mapper.RealTimeDataMapper
@@ -276,17 +277,28 @@
        var total = -1
        var count = 0
        val minFormatter = SimpleDateFormat("yyyy-MM-dd HH:mm")
        val averageUtil = AverageUtil<RealTimeDataGrid>({d ->
            minFormatter.format(d.dataTime)
        },{list ->
            list.avg()
        })
        while (total == -1 || page <= total) {
            println("------start------")
            val res = getOriginData("0d0000000001", "2021-07-05 19:47:01", "2021-11-05 00:00:00", page, 50000)
            res.head?.let {
                total = it.totalPage
            }
            val p = PageHelper.startPage<RealTimeDataGrid>(page, 50000)
            val res = realTimeDataGridMapper.selectByExample(Example(RealTimeDataGrid::class.java).apply {
                createCriteria().andBetween("dataTime", "2021-06-01 00:00:00", "2021-11-05 00:00:00")
            })
            total = p.pages
            if (page == 1) {
                println("总页数:$total")
            }
            println("当前页数:$page")
            res.data?.forEach {
            averageUtil.avg(res).forEach {
            }