src/main/kotlin/com/flightfeather/uav/biz/satellite/SatelliteDataMix.kt
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,127 @@ 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 } } src/main/kotlin/com/flightfeather/uav/domain/repository/SatelliteGridAnalysisRep.kt
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,17 @@ package com.flightfeather.uav.domain.repository import com.flightfeather.uav.domain.mapper.GridDataDetailMapper import com.flightfeather.uav.domain.mapper.GridDataMapper /** * * @date 2024/12/31 * @author feiyu02 */ class SatelliteGridAnalysisRep( private val gridDataMapper: GridDataMapper, private val gridDataDetailMapper: GridDataDetailMapper, ) { } src/main/kotlin/com/flightfeather/uav/domain/repository/SatelliteGridRep.kt
@@ -52,6 +52,10 @@ }) } fun fetchGridData(gridData: GridData): List<GridData?> { return gridDataMapper.select(gridData) } fun fetchGridDataDetail(dataId: Int, groupId: Int?, cellId: Int?): List<GridDataDetail?> { return gridDataDetailMapper.selectByExample(Example(GridDataDetail::class.java).apply { createCriteria().andEqualTo("dataId", dataId) src/main/kotlin/com/flightfeather/uav/lightshare/eunm/SatelliteDataType.kt
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,13 @@ package com.flightfeather.uav.lightshare.eunm /** * 嫿饿µæ°æ®ç±»å * @date 2024/12/31 * @author feiyu02 */ enum class SatelliteDataType(val value: Int) { // åå§æ°æ® Original(0), // èåæ°æ® Mix(1) } src/main/kotlin/com/flightfeather/uav/lightshare/service/SatelliteTelemetryService.kt
@@ -14,7 +14,7 @@ import javax.servlet.http.HttpServletResponse /** * * 嫿饿µç¸å ³serviceæå¡æ¥å£ * @date 2024/12/5 * @author feiyu02 */ @@ -28,6 +28,11 @@ fun fetchGridDataDetail(dataId: Int, groupId: Int?, cellId: Int?): List<GridDataDetail?> /** * æ°æ®èå */ fun mixGridData(dataIdList: List<Int>): List<GridData?> @Throws(BizException::class) fun importGridData(groupId: Int, dataTime: LocalDateTime?, update: Boolean, file: MultipartFile): GridDataImportResult? src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/SatelliteTelemetryServiceImpl.kt
@@ -1,5 +1,6 @@ package com.flightfeather.uav.lightshare.service.impl import com.flightfeather.uav.biz.satellite.SatelliteDataMix import com.flightfeather.uav.common.exception.BizException import com.flightfeather.uav.common.utils.FileExchange import com.flightfeather.uav.domain.entity.GridAod @@ -14,6 +15,7 @@ import com.flightfeather.uav.lightshare.service.SatelliteTelemetryService import com.github.pagehelper.PageHelper import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import org.springframework.web.multipart.MultipartFile import java.io.ByteArrayInputStream import java.io.File @@ -21,6 +23,7 @@ import java.time.ZoneId import java.util.* import javax.servlet.http.HttpServletResponse import kotlin.math.round /** * @@ -28,7 +31,10 @@ * @author feiyu02 */ @Service class SatelliteTelemetryServiceImpl(private val satelliteGridRep: SatelliteGridRep) : SatelliteTelemetryService { class SatelliteTelemetryServiceImpl( private val satelliteGridRep: SatelliteGridRep, private val satelliteDataMix: SatelliteDataMix, ) : SatelliteTelemetryService { private val fileExchange = FileExchange() override fun fetchGridGroup(areaVo: AreaVo, page: Int?, perPage: Int?): Pair<DataHead, List<GridGroup?>> { @@ -50,7 +56,27 @@ } override fun fetchGridDataDetail(dataId: Int, groupId: Int?, cellId: Int?): List<GridDataDetail?> { return satelliteGridRep.fetchGridDataDetail(dataId, groupId, cellId) val res = satelliteGridRep.fetchGridDataDetail(dataId, groupId, cellId) res.forEach { if (it?.pm25 != null) { it.pm25 = round(it.pm25 * 100) / 100 } } return res } @Transactional override fun mixGridData(dataIdList: List<Int>): List<GridData?> { if (dataIdList.isEmpty()) throw BizException("èåæéæ°æ®idä¸è½ä¸ºç©º") // 1. æ ¹æ®æ°æ®ä¸»é®idæ°ç»ï¼æ¥è¯¢è¯¥ç»å䏿¯å¦å·²ææ°æ®èåè®°å½ val exist = satelliteGridRep.fetchGridData(GridData().apply { type = 1 mixDataId = dataIdList.joinToString(",") }) // 2. è¥èåæ°æ®å·²åå¨ï¼ç´æ¥è¿å return exist.ifEmpty { listOf(satelliteDataMix.mixData(dataIdList).first) } } override fun importGridData(groupId: Int, dataTime: LocalDateTime?, update: Boolean, file: MultipartFile): GridDataImportResult? { src/main/kotlin/com/flightfeather/uav/lightshare/web/SatelliteTelemetryController.kt
@@ -54,6 +54,11 @@ @ApiParam("ç½æ ¼åå æ ¼id") @RequestParam(required = false) cellId: Int?, ) = resPack { satelliteTelemetryService.fetchGridDataDetail(dataId, groupId, cellId) } @ApiOperation(value = "夿¬¡èµ°èªæ°æ®è¿è¡èå计ç®") @PostMapping("/grid/data/mix") fun mixGridData( @ApiParam("åå§æ°æ®idæ°ç»") @RequestBody dataIdList: List<Int> ) = resPack { satelliteTelemetryService.mixGridData(dataIdList) } @ApiOperation(value = "å¯¼å ¥å«æé¥æµPM2.5ç»ææ°æ®") @PostMapping("/import/grid/data") src/test/kotlin/com/flightfeather/uav/UAVApplicationTests.kt
@@ -1,5 +1,7 @@ package com.flightfeather.uav import com.flightfeather.uav.domain.entity.GridDataDetail import com.flightfeather.uav.domain.mapper.GridDataDetailMapper import com.flightfeather.uav.lightshare.service.RealTimeDataService import org.junit.Test import org.junit.runner.RunWith @@ -7,6 +9,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.test.context.junit4.SpringRunner import tk.mybatis.mapper.entity.Example @RunWith(SpringRunner::class) @SpringBootTest @@ -15,6 +18,27 @@ @Autowired lateinit var realTimeDataService: RealTimeDataService @Autowired lateinit var gridDataDetailMapper: GridDataDetailMapper /** * å·æ°æ¯ç»æ°æ®çæ°æ®æå */ @Test fun refreshDataRank() { for (i in 29..39) { val dataDetailList = gridDataDetailMapper.selectByExample(Example(GridDataDetail::class.java).apply { createCriteria().andEqualTo("dataId", i) orderBy("pm25").desc() }) dataDetailList.forEachIndexed { i, d -> d?.rank = i + 1 gridDataDetailMapper.updateByPrimaryKey(d) } println("finish --${i}") } } @Test fun contextLoads() { } src/test/kotlin/com/flightfeather/uav/lightshare/service/impl/SatelliteTelemetryServiceImplTest.kt
@@ -2,6 +2,7 @@ import com.flightfeather.uav.domain.entity.GridDataDetail import com.flightfeather.uav.domain.mapper.GridDataDetailMapper import com.flightfeather.uav.lightshare.service.SatelliteTelemetryService import org.junit.Assert.* import org.junit.Test import org.junit.runner.RunWith @@ -15,23 +16,10 @@ class SatelliteTelemetryServiceImplTest { @Autowired lateinit var gridDataDetailMapper: GridDataDetailMapper lateinit var satelliteTelemetryService: SatelliteTelemetryService /** * å·æ°æ¯ç»æ°æ®çæ°æ®æå */ @Test fun refreshDataRank() { for (i in 1..25) { val dataDetailList = gridDataDetailMapper.selectByExample(Example(GridDataDetail::class.java).apply { createCriteria().andEqualTo("dataId", i) orderBy("pm25").desc() }) dataDetailList.forEachIndexed { i, d -> d?.rank = i + 1 gridDataDetailMapper.updateByPrimaryKey(d) } println("finish --${i}") } fun mixGridData() { satelliteTelemetryService.mixGridData(listOf(24, 25)) } }