package com.flightfeather.uav.biz.satellite
|
|
import com.flightfeather.uav.domain.entity.GridData
|
import com.flightfeather.uav.domain.entity.GridDataDetail
|
import com.flightfeather.uav.domain.mapper.GridDataDetailMapper
|
import com.flightfeather.uav.domain.mapper.GridDataMapper
|
import com.flightfeather.uav.lightshare.eunm.SatelliteDataType
|
import org.springframework.beans.BeanUtils
|
import org.springframework.stereotype.Component
|
import tk.mybatis.mapper.entity.Example
|
import java.util.Date
|
|
/**
|
* 卫星遥测数据融合
|
* @date 2024/12/31
|
* @author feiyu02
|
*/
|
@Component
|
class SatelliteDataMix(
|
private val gridDataMapper: GridDataMapper,
|
private val gridDataDetailMapper: GridDataDetailMapper,
|
) {
|
|
/**
|
* 融合卫星遥测数据
|
* @param dataIdList 每期卫星遥测数据的主键id数组,表示需要将这几组数据进行数据融合
|
*/
|
fun mixData(dataIdList: List<Int>): Pair<GridData?, List<GridDataDetail>> {
|
if (dataIdList.isEmpty()) return null to emptyList()
|
|
// 获取原始数据
|
val originalDataList = gridDataMapper.selectByExample(Example(GridData::class.java).apply {
|
createCriteria().andIn("id", dataIdList).andEqualTo("type", SatelliteDataType.Original.value)
|
})
|
if (originalDataList.isEmpty()) return null to emptyList()
|
|
// 获取具体原始网格数据
|
val dataDetailList = mutableListOf<List<GridDataDetail?>>()
|
originalDataList.forEach {
|
val res = gridDataDetailMapper.selectByExample(Example(GridDataDetail::class.java).apply {
|
createCriteria().andEqualTo("dataId", it?.id)
|
orderBy("cellId")
|
})
|
dataDetailList.add(res)
|
}
|
|
// 创建融合数据索引信息
|
val firstGridData = originalDataList.first()
|
val avgGridData = GridData().apply {
|
groupId = firstGridData?.groupId
|
dataTime = Date()
|
type = SatelliteDataType.Mix.value.toByte()
|
mixDataId = dataIdList.joinToString(",")
|
}
|
gridDataMapper.insert(avgGridData)
|
|
// 计算均值
|
val avgResult = calculateAvg(avgGridData.id, dataDetailList)
|
gridDataDetailMapper.insertList(avgResult)
|
|
return avgGridData to avgResult
|
}
|
|
/**
|
* 将多组原始卫星遥测网格PM2.5数据进行融合,计算每个网格的均值
|
* @param dataId 融合数据主键id
|
* @param dataDetailList 原始卫星遥测数据数组
|
*/
|
fun calculateAvg(dataId: Int, dataDetailList: List<List<GridDataDetail?>>): List<GridDataDetail> {
|
if (dataDetailList.isEmpty()) return emptyList()
|
|
// 获取首组网格数据,作为后续生成融合数据的依据
|
val first = dataDetailList.first()
|
|
// 每个单元格数据监测值总量
|
val totalList = mutableListOf<Float>()
|
// 每个单元格数据总数
|
val countList = mutableListOf<Int>()
|
|
// 统计各网格的数据监测值总量和数据总数
|
dataDetailList.forEach {
|
it.forEachIndexed { i, d ->
|
if (i < totalList.size) {
|
if (d?.pm25 != null) {
|
totalList[i] += d.pm25
|
countList[i]++
|
}
|
} else {
|
if (d?.pm25 != null) {
|
totalList.add(d.pm25)
|
countList.add(1)
|
} else {
|
totalList.add(0f)
|
countList.add(0)
|
}
|
}
|
}
|
}
|
|
// 计算每个网格的均值
|
val avgResult = mutableListOf<GridDataDetail>()
|
first.forEachIndexed { i, d ->
|
val total = totalList[i]
|
val count = countList[i]
|
val avg = if (count == 0) {
|
null
|
} else {
|
total / count
|
}
|
val avgData = GridDataDetail().apply {
|
this.dataId = dataId
|
groupId = d?.groupId
|
cellId = d?.cellId
|
pm25 = avg
|
}
|
avgResult.add(avgData)
|
}
|
|
// 刷新排名属性
|
avgResult.sortByDescending { it.pm25 }
|
avgResult.forEachIndexed { i, d ->
|
d.rank = i + 1
|
}
|
|
return avgResult
|
}
|
}
|