src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt
@@ -15,6 +15,11 @@ config: V, private val tagClz: Class<T>, ) : BaseExceptionAnalysis<V, Y>(config) { enum class JudgeMethod(val des: String) { M1("å¨ä¸å®ç空é´åæ¶é´èå´å ï¼æ°æ®ç´¯è®¡åºç°N次å¼å¸¸åï¼è®¤ä¸ºè¯¥å¼å¸¸æç«"), M2("è¦æ±æ°æ®ä¸é´æè¿ç»åºç°N次å¼å¸¸åï¼è®¤ä¸ºè¯¥å¼å¸¸æç«"), } companion object { // è®°å½å¼å¸¸æ°æ®æ®µæ¶ï¼åå«åèµ·å§å快尾åé¢å¤è®°å½çæ°æ®ä¸ªæ°åç§»é private const val OFFSET = 10 @@ -40,6 +45,13 @@ * å¼å¸¸ç»æ */ protected val result = mutableListOf<Y>() /** * ä¸éç¨äºæ¤å¼å¸¸ç±»åççæµå å */ open var excludedFactor: List<FactorType> = emptyList() abstract var judgeMethod: JudgeMethod /** * ç«å³å¤æï¼å½åºç°å¼å¸¸æ¶ï¼ç¼åå¼å¸¸æ°æ®çåæ¶ï¼ç«å³å¯¹å·²æå¼å¸¸è¿è¡å¤ææ¯å¦æ»¡è¶³å¼å¸¸ç»æè¦æ± @@ -98,7 +110,7 @@ * @return */ open fun needCut(tag: T, hasException: Boolean?, data: BaseRealTimeData): Boolean { // é»è®¤å¤ææ¡ä»¶ä¸º å½å¼å¸¸ä¸åéå¤åºç°æ¶ï¼å½¢æå¼å¸¸ç»æ // é»è®¤å¤ææ¡ä»¶ä¸º å½å¼å¸¸ä¸åéå¤åºç°æ¶ return tag.exceptionExisted && hasException == false } @@ -116,9 +128,10 @@ val hasException = judge(lastData, data) config.factorFilter.selectedList.forEach { s -> val f = s.main tagMap[f]?.let { it.addHistoryData(data) // æé¤æ¤å¼å¸¸ç±»åä¸éç¨ççæµå å if (excludedFactor.contains(f)) return@forEach tagMap[f]?.let { it.eIndex++ // èµ·å§æ°æ® it.endData = data @@ -126,31 +139,13 @@ it.refreshWithNextException(data) } // 对äºå¼å¸¸ççæå嫿§è¡åç½®å¤æãåç«å³å¤æ // 1. åç½®å¤æï¼å½ç¸é»æ°æ®æ¶é´ä¸è¿ç»æ¶ï¼æè 满足èªå®ä¹æ¡ä»¶æ¶ï¼å¯¹ä¹åå·²æçå¼å¸¸è¿è¡è®°å½ï¼å½¢æå¼å¸¸ç»æ // if (afterExcCheck(isContinue, it, hasException[f])) { // // æ°æ®ä¸è¿ç»æ¶æè æ»¡è¶³ä¸»å¨æªææ¡ä»¶æ¶ï¼è®°å½å¼å¸¸æ åµ // recordException(s, it, data) // } // 2. ç«å³å¤æï¼å½åºç°å¼å¸¸æ¶ï¼ç¼åå¼å¸¸æ°æ®çåæ¶ï¼ç«å³å¯¹å·²æå¼å¸¸è¿è¡å¤ææ¯å¦æ»¡è¶³å¼å¸¸ç»æè¦æ± if (hasException[f] == true) { // æç §ä¸åçæ¹å¼è¿è¡å¼å¸¸å¤æ when (judgeMethod) { JudgeMethod.M1 -> judgeMethod1(hasException, f, it, data, s) JudgeMethod.M2 -> judgeMethod2(isContinue, hasException, f, it, data, s) } // afterExcCheck(isContinue, it, hasException[f]) if (needCut(it, hasException[f], data)) { it.refreshWithNextException(data) } // æå¼å¸¸åºç°æ¶ï¼è®°å½å¼å¸¸æ°æ® it.addExceptionData(data) // å½ç«å³å¤æéè¿æ¶ï¼å½¢æå¼å¸¸ç»æ if (immeExcCheck(it, f)) { recordException(s, it, data) } } // 3. æ°æ®æ£å¸¸ï¼æ ä»»ä½å¼å¸¸æ¶d // TODO("2025.6.3ï¼å ¶ä»åç±»çæ¤å¤å·æ°é»è¾å¾ 宿â) // else { // it.refreshWithNextException(data) // } it.addHistoryData(data) } } lastData = data @@ -164,6 +159,67 @@ } /** * æ°æ®å¼å¸¸å¤ææ¹å¼ä¸ * å¨ä¸å®ç空é´åæ¶é´èå´å ï¼æ°æ®ç´¯è®¡åºç°N次å¼å¸¸åï¼è®¤ä¸ºè¯¥å¼å¸¸æç« */ private fun judgeMethod1( hasException: MutableMap<FactorType, Boolean>, f: FactorType, tag: T, data: BaseRealTimeData, s: FactorFilter.SelectedFactor, ) { // åºç°å¼å¸¸ if (hasException[f] == true) { // å¤ææ°æ®å¨ç©ºé´åæ¶é´åå䏿¯å¦è¶ åºéå®èå´ï¼è¥è¶ åºåå é¤éççå¼å¸¸è®°å½ï¼å·æ°èµ·å§ç¹æ°æ® if (needCut(tag, hasException[f], data)) { tag.refreshWithNextException(data) } // è®°å½å¼å¸¸æ°æ® tag.addExceptionData(data) // å½ç«å³å¤æéè¿æ¶ï¼å½¢æå¼å¸¸ç»æ if (immeExcCheck(tag, f)) { recordException(s, tag, data) } } // æ°æ®æ£å¸¸ï¼å¹¶ä¸æ²¡æåå²å¼å¸¸æ°æ®æ¶ï¼å·æ°èµ·å§ç¹æ°æ® else if (!tag.exceptionExisted) { tag.refreshWithNextException(data) } } /** * æ°æ®å¼å¸¸å¤ææ¹å¼äº * è¦æ±æ°æ®ä¸é´æè¿ç»åºç°N次å¼å¸¸åï¼è®¤ä¸ºè¯¥å¼å¸¸æç« */ private fun judgeMethod2( isContinue: Boolean, hasException: MutableMap<FactorType, Boolean>, f: FactorType, tag: T, data: BaseRealTimeData, s: FactorFilter.SelectedFactor, ) { // å½ç¸é»æ°æ®æ¶é´ä¸è¿ç»æ¶ï¼å·æ°èµ·å§ç¹æ°æ®ï¼ç§»é¤åå²å¼å¸¸è®°å½ if (!isContinue) { tag.refreshWithNextException(data) } // åºç°å¼å¸¸ else if (hasException[f] == true) { // æå¼å¸¸åºç°æ¶ï¼è®°å½å¼å¸¸æ°æ® tag.addExceptionData(data) // å½ç«å³å¤æéè¿æ¶ï¼å½¢æå¼å¸¸ç»æ if (immeExcCheck(tag, f)) { recordException(s, tag, data) } } // æ°æ®æ£å¸¸ï¼å·æ°èµ·å§ç¹æ°æ®ï¼ç§»é¤åå²å¼å¸¸è®°å½ else { tag.refreshWithNextException(data) } } /** * å¼å¸¸ç»æï¼è®°å½å¼å¸¸ * 夿已æçå¼å¸¸æ°æ®æ¯å¦æ»¡è¶³å¼å¸¸æ¡ä»¶ï¼æ»¡è¶³åè®°å½ï¼ä¸æ»¡è¶³åç¥è¿ */ src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionDataExceed.kt
@@ -16,6 +16,8 @@ class ExceptionDataExceed(config: DataAnalysisConfig) : BaseExceptionContinuousSingle<ExceptionTag, DataAnalysisConfig, ExceptionResult>(config, ExceptionTag::class.java) { override var judgeMethod: JudgeMethod = JudgeMethod.M2 override fun getExceptionType(): ExceptionType = ExceptionType.TYPE2 override fun judgeException(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> { src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionValueMutation.kt
@@ -20,6 +20,8 @@ override fun getExceptionType(): ExceptionType = ExceptionType.TYPE4 override var judgeMethod: JudgeMethod = JudgeMethod.M2 override fun judgeException(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> { val res = mutableMapOf<FactorType, Boolean>() config.factorFilter.mainList().forEach { f -> src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionTag.kt
@@ -9,6 +9,9 @@ * @author feiyu02 */ open class ExceptionTag { companion object { const val MAX_HISTORY = 10 } // èµ·å§æ°æ®ä¸æ var sIndex = 0 @@ -37,8 +40,16 @@ fun addHistoryData(data: BaseRealTimeData) { historyData.add(data) if (historyData.size > 15) { historyData.removeAt(0) if (exceptionData.isNotEmpty()) { // ä¿è¯å岿°æ®å 嫿æå¼å¸¸æ°æ®ï¼å¼å¸¸æ°æ®å¯è½ä¸è¿ç»ï¼ï¼å¹¶ä¸å¨é¦ä¸ªå¼å¸¸æ°æ®ä¹åæå¤åä¿å10ä¸ªæ°æ® val i = historyData.indexOf(exceptionData.first()) if (i > MAX_HISTORY) { historyData = historyData.subList(i - MAX_HISTORY, historyData.size) } } else { if (historyData.size > MAX_HISTORY) { historyData = historyData.subList(historyData.size - MAX_HISTORY, historyData.size) } } } src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/SourceTraceController.kt
@@ -43,7 +43,7 @@ .withMain(FactorType.O3) .withMain(FactorType.PM25) .withMain(FactorType.PM10) .withMain(FactorType.VOC) // .withMain(FactorType.VOC) .withCombination( listOf( listOf(FactorType.PM25, FactorType.PM10), @@ -63,6 +63,8 @@ private val sceneInfoRep: SceneInfoRep private val sourceTraceRep: SourceTraceRep private val config: RTExcWindLevelConfig private val timer = Timer() private var timerTask: TimerTask? = null private val taskList = mutableListOf<BaseExceptionAnalysis<RTExcWindLevelConfig, PollutedClue>>() @@ -92,23 +94,27 @@ * è®¡ç®æ°ç䏿¡å®æ¶èµ°èªæ°æ® */ fun addOneData(data: BaseRealTimeData) { // println("====================>") // 计ç®å¼å¸¸ taskList.forEach { it.onNextData(data) } pollutedSummary.refreshLatestMonitorData(data) // é宿¶é´å æ²¡ææ°æ°æ®ä¼ å ¥ï¼åç»æå½åçè®¡ç® dealOnTimeout() } /** * è¶ æ¶å¤çï¼è¾é¿æ¶é´æ²¡ææ°æ°æ®è¿å ¥ï¼è¿è¡åå§åæä½ */ private fun dealOnTimeout() { val timer = Timer(true) timer.schedule(object : TimerTask() { // val timer = Timer() timerTask?.cancel() timer.purge() timerTask = object : TimerTask() { override fun run() { TODO("Not yet implemented") initTask() } }, 60 * 1000) timer.cancel() } timer.schedule(timerTask, 2 * 60 * 60 * 1000) } // æ°æ®çªåå¼å¸¸åè° src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/config/RTExcWindLevelConfig.kt
@@ -27,7 +27,7 @@ // æº¯æºæ©æ£åç§»è§åº¦ï¼åä½ï¼åº¦ï¼ var sourceTraceDegOffset = 120.0 // 宿¶çº¿ç´¢åææ¶é´é´é(åä½ï¼åé) var analysisPeriod = 15 var analysisPeriod = 5 // 宿¶åæé´éä¸ï¼ç«å³è¿è¡çº¿ç´¢åæçæå°çº¿ç´¢é(åä½ï¼ä¸ª) var analysisCount = 4 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRTExcChangeRate.kt
@@ -30,6 +30,8 @@ abstract var changeRate: MutableMap<FactorType, RTExcWindLevelConfig.WindLevelCondition> override var judgeMethod: JudgeMethod = JudgeMethod.M2 override fun getExceptionType(): ExceptionType { return ExceptionType.TYPE9 } src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRTExcWindLevel.kt
@@ -29,10 +29,14 @@ this.callback = callback } override var excludedFactor: List<FactorType> = listOf(FactorType.NO2) private var callback: NewPolluteClueCallback? = null abstract var windLevelCondition: RTExcWindLevelConfig.WindLevelCondition override var judgeMethod: JudgeMethod = JudgeMethod.M1 override fun getExceptionType(): ExceptionType { return ExceptionType.TYPE4 } src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt
@@ -32,6 +32,8 @@ return ExceptionType.TYPE4 } override var judgeMethod: JudgeMethod = JudgeMethod.M2 override fun judgeException(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> { val res = mutableMapOf<FactorType, Boolean>() config.factorFilter.mainList().forEach { f -> @@ -67,7 +69,7 @@ if (tag.exceptionData.isEmpty()) return false val se = tag.exceptionData.first() val ee = tag.exceptionData.last() val ee = data val sTime = LocalDateTime.ofInstant(se.dataTime?.toInstant(), ZoneId.systemDefault()) val eTime = LocalDateTime.ofInstant(ee.dataTime?.toInstant(), ZoneId.systemDefault()) src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedArea.kt
@@ -26,6 +26,8 @@ windLevelCondition: RTExcWindLevelConfig.WindLevelCondition?, ) : this() { distanceType = windLevelCondition?.distanceType distanceRange = distanceType?.disRange distanceDes = distanceType?.des windLevelCondition?.let { sourceTrace(historyData, exceptionData, config, it) } } @@ -40,6 +42,9 @@ // 污æå¯è½çåçè·ç¦» var distanceType: DistanceType? = null var distanceRange: Pair<Double, Double>? = null var distanceDes: String? = null /** * ååæº¯æº */ src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSummary.kt
@@ -64,6 +64,8 @@ // æ°å¢ä¸æ¡æ±¡æçº¿ç´¢ fun addClue(pollutedClue: PollutedClue) { // 彿º¯æºæªæ¾å°é£é©æºæ¶ï¼æ¤æ¬¡æº¯æºä¿¡æ¯ä¸ä½ä¸ºçº¿ç´¢ç»è®¡é¡¹ if (pollutedClue.pollutedSource?.sceneList?.isNotEmpty() == true) clueList.add(pollutedClue) // realTimeSummary() analysisOnClueCount() @@ -71,8 +73,7 @@ // æ°å¢ä¸æ¡æ±¡æçº¿ç´¢ fun addClueList(pollutedClues: List<PollutedClue>) { clueList.addAll(pollutedClues) analysisOnClueCount() pollutedClues.forEach { addClue(it) } } // å·æ°å½åææ°çèµ°èªçæµæ°æ® @@ -181,6 +182,7 @@ // 建议çèµ°èªè·¯çº¿ result.direction = AMapService.directionDriving(origin, destination) Thread.sleep(200) } // 线索åæå®æåï¼ç§»å¨è³åå²çº¿ç´¢å表 historyClueList.addAll(clueList) src/test/kotlin/com/flightfeather/uav/Test.kt
@@ -168,4 +168,37 @@ fun foo18() { println(-4.382398 in 4.0..Double.MAX_VALUE) } @Test fun foo19() { val timer = Timer(true) // var running = true val task = object : TimerTask() { override fun run() { println("task run") println(Date()) // running = false } } println(Date()) timer.schedule(task, 5000) task.cancel() timer.purge() val task2 = object : TimerTask() { override fun run() { println("task2 run") println(Date()) // running = false } } timer.schedule(task2, 4000) // while (running) { // // } val sc = Scanner(System.`in`) while (sc.hasNext()) { println(sc.nextLine()) } } } src/test/kotlin/com/flightfeather/uav/biz/sourcetrace/SourceTraceControllerTest.kt
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,76 @@ package com.flightfeather.uav.biz.sourcetrace import com.flightfeather.uav.common.utils.DateUtil import com.flightfeather.uav.domain.entity.Mission import com.flightfeather.uav.domain.entity.RealTimeDataVehicle import com.flightfeather.uav.domain.mapper.MissionMapper import com.flightfeather.uav.domain.repository.MissionRep import com.flightfeather.uav.domain.repository.SceneInfoRep import com.flightfeather.uav.domain.repository.SourceTraceRep import com.flightfeather.uav.lightshare.service.RealTimeDataService import org.junit.Test import org.junit.runner.RunWith 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 class SourceTraceControllerTest { @Autowired lateinit var sceneInfoRep: SceneInfoRep @Autowired lateinit var sourceTraceRep: SourceTraceRep @Autowired lateinit var missionMapper: MissionMapper @Autowired lateinit var realTimeDataService: RealTimeDataService @Test fun autoSourceTrace() { val sourceTraceController = SourceTraceController(sceneInfoRep, sourceTraceRep) val missions = missionMapper.selectByExample(Example(Mission::class.java).apply { createCriteria().andEqualTo("deviceType", "0a") .andLessThanOrEqualTo("startTime", "2024-11-07 15:00:00") orderBy("startTime").desc() }) missions.forEach { m -> val rtData = realTimeDataService.getSecondData( m?.deviceType, m?.deviceCode, DateUtil.instance.dateToString(m?.startTime, DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS), DateUtil.instance.dateToString(m?.endTime, DateUtil.DateStyle.YYYY_MM_DD_HH_MM_SS), null, 1, 10000 ) rtData.data?.forEach { d -> val rtdVehicle = d.toBaseRealTimeData(RealTimeDataVehicle::class.java) // Thread.sleep(500) sourceTraceController.addOneData(rtdVehicle) } sourceTraceController.initTask() } // val rtData = realTimeDataService.getSecondData( // "0a", // "0a0000000001", // "2025-01-06 13:32:00", // "2025-01-06 15:52:36", // null, // 1, // 10000 // ) // rtData.data?.forEach { d -> // val rtdVehicle = d.toBaseRealTimeData(RealTimeDataVehicle::class.java) //// Thread.sleep(500) // sourceTraceController.addOneData(rtdVehicle) // } } }