From f7bdafb7cddd049bbb1bbf265fa006683b4ac693 Mon Sep 17 00:00:00 2001 From: feiyu02 <risaku@163.com> Date: 星期三, 11 六月 2025 17:08:35 +0800 Subject: [PATCH] 1. 新增动态污染溯源新的判定逻辑(待完成) --- src/test/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSourceTest.kt | 31 +- src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionValueMutation.kt | 2 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRealTimeException.kt | 10 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/SourceTraceController.kt | 21 +- src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedData.kt | 9 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt | 109 ++++++++-- src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt | 22 + src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionSlideAverage.kt | 4 src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionTag.kt | 10 + src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/config/RTExcWindLevelConfig.kt | 74 +++--- src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionDataExceed.kt | 12 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt | 2 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionSlideAverage.kt | 2 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RTExcChangeRate.kt | 114 +++++++++++ src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedClue.kt | 48 +++- src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt | 12 src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionContinuous.kt | 10 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRTExcWindLevel.kt | 22 + src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedArea.kt | 55 ++++- src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionType.kt | 1 src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSummary.kt | 30 +- 21 files changed, 418 insertions(+), 182 deletions(-) diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt index d43f689..2a95915 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionAnalysis.kt @@ -18,10 +18,10 @@ /** * 鐢熸垚涓�鏉″紓甯稿垎鏋愮粨鏋� */ - abstract fun newResult( - start: BaseRealTimeData, - end: BaseRealTimeData?, - factor: FactorFilter.SelectedFactor, - exceptionData: List<BaseRealTimeData>, - ): Y +// abstract fun newResult( +// start: BaseRealTimeData, +// end: BaseRealTimeData?, +// factor: FactorFilter.SelectedFactor, +// exceptionData: List<BaseRealTimeData>, +// ): Y } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt index ce55583..2bfe2be 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt @@ -37,7 +37,7 @@ /** * 绔嬪嵆鍒ゆ柇锛氬綋鍑虹幇寮傚父鏃讹紝缂撳瓨寮傚父鏁版嵁鐨勫悓鏃讹紝绔嬪嵆瀵瑰凡鏈夊紓甯歌繘琛屽垽鏂槸鍚︽弧瓒冲紓甯哥粨鏋滆姹� */ - open fun immeExcCheck(tag: T): Boolean { + open fun immeExcCheck(tag: T, factorType: FactorType): Boolean { return false } @@ -61,11 +61,11 @@ * 鍒ゆ柇寮傚父鍑虹幇鐨勮繛缁釜鏁版槸鍚︽弧瓒虫潯浠� * @param tag 寮傚父鏁版嵁瀵硅薄 */ - abstract fun judgeExceptionCount(tag: T): Boolean + abstract fun judgeExceptionCount(tag: T, factorType: FactorType?): Boolean /** * 寮傚父鏁版嵁鐨勬埅鍙栧垽鏂� - * @return 榛樿涓嶉渶瑕佹埅鍙� + * @return */ open fun needCut(tag: T, hasException: Boolean?): Boolean { // 榛樿鍒ゆ柇鏉′欢涓� 褰撳紓甯镐笉鍐嶉噸澶嶅嚭鐜版椂锛屽舰鎴愬紓甯哥粨鏋� @@ -87,6 +87,8 @@ config.factorFilter.selectedList.forEach { s -> val f = s.main tagMap[f]?.let { + it.addHistoryData(data) + it.eIndex++ // 璧峰鏁版嵁 it.endData = data @@ -105,7 +107,7 @@ // 鏈夊紓甯稿嚭鐜版椂锛岃褰曞紓甯告暟鎹� it.addExceptionData(data) // 褰撶珛鍗冲垽鏂�氳繃鏃讹紝褰㈡垚寮傚父缁撴灉 - if (immeExcCheck(it)) { + if (immeExcCheck(it, f)) { recordException(s, it, data) } } @@ -141,13 +143,13 @@ ) { val tag = tagMap[factor?.main] if (factor != null && tag != null) { - if (tag.exceptionExisted && judgeExceptionCount(tag)) { + if (tag.exceptionExisted && judgeExceptionCount(tag, factor.main)) { onNewException(tag, factor, exceptionStatus) } } else { config.factorFilter.selectedList.forEach { f -> val tag1 = tagMap[f.main] ?: return@forEach - if (tag1.exceptionExisted && judgeExceptionCount(tag1)) { + if (tag1.exceptionExisted && judgeExceptionCount(tag1, null)) { onNewException(tag1, f, exceptionStatus) } } @@ -159,7 +161,8 @@ */ open fun onNewException(tag: T, factor: FactorFilter.SelectedFactor, exceptionStatus: ExceptionStatusType) { if (tag.startData == null) return - val ex = newResult(tag.startData!!, tag.endData, factor, tag.exceptionData) +// val ex = newResult(tag.startData!!, tag.endData, factor, tag.exceptionData) + val ex = newResult(tag, factor) .apply { status = exceptionStatus.value } // 寮傚父宸插垱寤烘椂锛屾洿鏂板紓甯镐俊鎭� if (tag.exceptionCreated) { @@ -177,4 +180,9 @@ } } + /** + * 鐢熸垚涓�鏉″紓甯稿垎鏋愮粨鏋� + */ + abstract fun newResult(tag:T, factor: FactorFilter.SelectedFactor): Y + } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionContinuous.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionContinuous.kt index a2e4282..bbd22fa 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionContinuous.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionContinuous.kt @@ -15,13 +15,9 @@ abstract class ExceptionContinuous(config: DataAnalysisConfig) : BaseExceptionContinuous<ExceptionTag, DataAnalysisConfig, ExceptionResult>(config, ExceptionTag::class.java) { - override fun newResult( - start: BaseRealTimeData, - end: BaseRealTimeData?, - factor: FactorFilter.SelectedFactor, - exceptionData: List<BaseRealTimeData>, - ): ExceptionResult { + override fun newResult(tag:ExceptionTag, factor: FactorFilter.SelectedFactor): ExceptionResult { val eType = getExceptionType() - return ExceptionResult(start, end, factor, exceptionData, config.mission.missionCode, eType) + return ExceptionResult(tag.startData!!, tag.endData, factor, tag.exceptionData, config.mission.missionCode, + eType) } } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionDataExceed.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionDataExceed.kt index 96c4d5e..05265fc 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionDataExceed.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionDataExceed.kt @@ -33,17 +33,13 @@ return res } - override fun judgeExceptionCount(tag: ExceptionTag): Boolean { + override fun judgeExceptionCount(tag: ExceptionTag, factorType: FactorType?): Boolean { return true } - override fun newResult( - start: BaseRealTimeData, - end: BaseRealTimeData?, - factor: FactorFilter.SelectedFactor, - exceptionData: List<BaseRealTimeData>, - ): ExceptionResult { + override fun newResult(tag: ExceptionTag, factor: FactorFilter.SelectedFactor): ExceptionResult { val eType = getExceptionType() - return ExceptionResult(start, end, factor, exceptionData, config.mission.missionCode, eType) + return ExceptionResult(tag.startData!!, tag.endData, factor, tag.exceptionData, config.mission.missionCode, + eType) } } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionSlideAverage.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionSlideAverage.kt index 7cfcd1f..21bede2 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionSlideAverage.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionSlideAverage.kt @@ -201,7 +201,9 @@ } - override fun newResult( + + + fun newResult( start: BaseRealTimeData, end: BaseRealTimeData?, factor: FactorFilter.SelectedFactor, diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionValueMutation.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionValueMutation.kt index 082db5e..bb399d7 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionValueMutation.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/exceptiontype/ExceptionValueMutation.kt @@ -40,7 +40,7 @@ return res } - override fun judgeExceptionCount(tag: ExceptionTag): Boolean { + override fun judgeExceptionCount(tag: ExceptionTag, factorType: FactorType?): Boolean { // 棣栦釜鏁版嵁娌℃湁鍓嶄竴涓暟鎹弬鐓э紝涓嶇畻寮傚父鍊硷紝鏈�鍚庝竴涓暟鎹槸鍒ゆ柇缁撴潫鐨勬甯稿�硷紝鍥犳寮傚父鏁版嵁涓暟鐨勮绠椾笅鏍囦负sIndex鍜宔Index val sIndex = tag.sIndex val eIndex = tag.eIndex - 1 diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionTag.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionTag.kt index 7886a5d..3124bc8 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionTag.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionTag.kt @@ -24,6 +24,9 @@ // 寮傚父鏁版嵁娈� var exceptionData = mutableListOf<BaseRealTimeData>() + // 杩戞鏃堕棿鍐呯殑鍘嗗彶鏁版嵁 + var historyData = mutableListOf<BaseRealTimeData>() + // 鏄惁瀛樺湪寮傚父 var exceptionExisted = false @@ -32,6 +35,13 @@ var exceptionResult = mutableListOf<BaseExceptionResult>() + fun addHistoryData(data: BaseRealTimeData) { + historyData.add(data) + if (historyData.size > 20) { + historyData.removeAt(0) + } + } + fun addExceptionData(data: BaseRealTimeData){ exceptionExisted = true exceptionData.add(data) diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionType.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionType.kt index 4e8a1f6..dac7f89 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionType.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/model/ExceptionType.kt @@ -10,4 +10,5 @@ TYPE6(6, "鍗曟棩瓒呮爣娆℃暟涓磋繎澶勭綒寮傚父"), TYPE7(7, "婊戝姩骞冲潎鍊肩獊鍙樺紓甯�"), TYPE8(8, "鏈夋晥鐜囧紓甯�"), + TYPE9(9, "鍙樺寲閫熺巼寮傚父"), } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/SourceTraceController.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/SourceTraceController.kt index cefe129..662cd6b 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/SourceTraceController.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/SourceTraceController.kt @@ -35,23 +35,23 @@ else RTExcWindLevelConfig( FactorFilter.builder() -// .withMain(FactorType.NO2) - .withMain(FactorType.CO) -// .withMain(FactorType.H2S) -// .withMain(FactorType.SO2) -// .withMain(FactorType.O3) +// .withMain(FactorType.NO2) +// .withMain(FactorType.CO) +// .withMain(FactorType.H2S) +// .withMain(FactorType.SO2) +// .withMain(FactorType.O3) .withMain(FactorType.PM25) .withMain(FactorType.PM10) .withMain(FactorType.VOC) .create() ) - pollutedSummary = PollutedSummary(config){ summaryCallback(it)} + pollutedSummary = PollutedSummary(config) { summaryCallback(it) } newTask() } constructor(sceneInfoRep: SceneInfoRep) : this(sceneInfoRep, null) - private val pollutedSummary:PollutedSummary + private val pollutedSummary: PollutedSummary private val sceneInfoRep: SceneInfoRep @@ -71,6 +71,7 @@ add(RTExcWindLevel1_1(config) { exceptionCallback(it) }.also { it.init() }) add(RTExcWindLevel4(config) { exceptionCallback(it) }.also { it.init() }) add(RTExcWindLevel6(config) { exceptionCallback(it) }.also { it.init() }) + add(RTExcChangeRate(config) { exceptionCallback(it) }.also { it.init() }) } } @@ -102,11 +103,11 @@ // 婧簮姹℃煋婧愪俊鎭� ex.searchScenes(sceneInfoRep) - // 璁板綍姹℃煋绾跨储 - pollutedSummary.addClue(ex) - // 骞挎挱姹℃煋婧簮寮傚父缁撴灉 UnderwayWebSocketSender.broadcast(MsgType.PolClue.value, ex) + + // 璁板綍姹℃煋绾跨储 + pollutedSummary.addClue(ex) } private fun summaryCallback(ex: PollutedSummary.AnalysisResult) { diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/config/RTExcWindLevelConfig.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/config/RTExcWindLevelConfig.kt index 271388a..ff5b96e 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/config/RTExcWindLevelConfig.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/config/RTExcWindLevelConfig.kt @@ -3,6 +3,7 @@ import com.flightfeather.uav.biz.FactorFilter import com.flightfeather.uav.biz.dataanalysis.BaseAnalysisConfig import com.flightfeather.uav.biz.sourcetrace.model.DistanceType +import com.flightfeather.uav.socket.eunm.FactorType /** * @@ -22,7 +23,14 @@ var distanceLimit = 3000 // 闄愬畾鏃堕棿鍐咃紙鍗曚綅锛氬垎閽燂級 var timeLimit = 3 + // 婧簮鎵╂暎鍋忕Щ瑙掑害锛堝崟浣嶏細搴︼級 + var sourceTraceDegOffset = 60.0 + // 瀹氭椂绾跨储鍒嗘瀽鏃堕棿闂撮殧(鍗曚綅锛氬垎閽�) + var analysisPeriod = 15 + // 瀹氭椂鍒嗘瀽闂撮殧涓紝绔嬪嵆杩涜绾跨储鍒嗘瀽鐨勬渶灏忕嚎绱㈤噺(鍗曚綅锛氫釜) + var analysisCount = 4 + /****鏁版嵁绐佸彉*****************************************************************************/ // 0 - 1绾ч var windLevelCondition1 = WindLevelCondition( .0 to 1.5, @@ -56,42 +64,32 @@ 3 ) - // 婧簮鎵╂暎鍋忕Щ瑙掑害锛堝崟浣嶏細搴︼級 - var sourceTraceDegOffset = 120.0 - - // 瀹氭椂绾跨储鍒嗘瀽鏃堕棿闂撮殧(鍗曚綅锛氬垎閽�) - var analysisPeriod = 15 - // 瀹氭椂鍒嗘瀽闂撮殧涓紝绔嬪嵆杩涜绾跨储鍒嗘瀽鐨勬渶灏忕嚎绱㈤噺(鍗曚綅锛氫釜) - var analysisCount = 2 - - - -// // 0 - 1绾ч -// var windLevelCondition1 = WindLevelCondition( -// .0 to 1.5, -// listOf(0.5 to DistanceType.TYPE1, 0.2 to DistanceType.TYPE2,), -// listOf(1, 1) -// ) -// -// // 0 - 1绾ч -// var windLevelCondition1_1 = WindLevelCondition( -// .0 to 1.5, -// 0.2 to DistanceType.TYPE2, -// 1 -// ) -// -// // 2 - 4绾ч -// var windLevelCondition2 = WindLevelCondition( -// 1.6 to 7.9, -// listOf(0.2 to DistanceType.TYPE3), -//// listOf(3) -// listOf(1) -// ) -// -// // 5 - 6绾ч -// var windLevelCondition3 = WindLevelCondition( -// 8.0 to 13.8, -// listOf(0.1 to DistanceType.TYPE4), -// listOf(3) -// ) + /****鏁版嵁鍙樺寲閫熺巼*****************************************************************************/ + var changeRateCondition = WindLevelCondition( + .0 to Double.MAX_VALUE, + 0.1 to Double.MAX_VALUE, + DistanceType.TYPE1, + 3 + ) + // 鐩戞祴鍥犲瓙鍦ㄤ竴涓洃娴嬪懆鏈燂紙4绉掞級鍐呮甯稿彉鍖栫殑閲忕骇鑼冨洿 + var changeRate = mutableMapOf( + FactorType.PM25 to WindLevelCondition( + .0 to Double.MAX_VALUE, + 4.0 to Double.MAX_VALUE, + DistanceType.TYPE1, + 3 + ), + FactorType.PM10 to WindLevelCondition( + .0 to Double.MAX_VALUE, + 4.0 to Double.MAX_VALUE, + DistanceType.TYPE1, + 3 + ), + FactorType.VOC to WindLevelCondition( + .0 to Double.MAX_VALUE, + 6.0 to Double.MAX_VALUE, + DistanceType.TYPE1, + 1 + ), + ) } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRTExcWindLevel.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRTExcWindLevel.kt index 779d121..f78fd15 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRTExcWindLevel.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRTExcWindLevel.kt @@ -66,7 +66,7 @@ return res } - override fun judgeExceptionCount(tag: ExceptionTag): Boolean { + override fun judgeExceptionCount(tag: ExceptionTag, factorType: FactorType?): Boolean { return tag.exceptionData.size >= windLevelCondition.countLimit } @@ -97,20 +97,24 @@ return b1 || b2 } - override fun immeExcCheck(tag: ExceptionTag): Boolean { + override fun immeExcCheck(tag: ExceptionTag, factorType: FactorType): Boolean { // 寮傚父鍑虹幇绛変簬闄愬畾娆℃暟鏃讹紝灏遍渶瑕佸舰鎴愭薄鏌撶嚎绱� return tag.exceptionData.size == windLevelCondition.countLimit } - override fun newResult( - start: BaseRealTimeData, - end: BaseRealTimeData?, - factor: FactorFilter.SelectedFactor, - exceptionData: List<BaseRealTimeData>, - ): PollutedClue { - return PollutedClue(start, end, factor, exceptionData, getExceptionType(), config, windLevelCondition) + override fun newResult(tag: ExceptionTag, factor: FactorFilter.SelectedFactor): PollutedClue { + return PollutedClue(tag, factor, getExceptionType(), config, windLevelCondition) } +// override fun newResult( +// start: BaseRealTimeData, +// end: BaseRealTimeData?, +// factor: FactorFilter.SelectedFactor, +// exceptionData: List<BaseRealTimeData>, +// ): PollutedClue { +// return PollutedClue(start, end, factor, exceptionData, getExceptionType(), config, windLevelCondition) +// } + override fun onNewException( tag: ExceptionTag, factor: FactorFilter.SelectedFactor, diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRealTimeException.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRealTimeException.kt index d4c0232..962969f 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRealTimeException.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/BaseRealTimeException.kt @@ -55,14 +55,10 @@ // lastData = data // } - override fun newResult( - start: BaseRealTimeData, - end: BaseRealTimeData?, - factor: FactorFilter.SelectedFactor, - exceptionData: List<BaseRealTimeData>, - ): RealTimeExceptionResult { + + override fun newResult(tag:T, factor: FactorFilter.SelectedFactor): RealTimeExceptionResult { val eType = getExceptionType() - return RealTimeExceptionResult(start, end, factor, exceptionData, eType) + return RealTimeExceptionResult(tag.startData!!, tag.endData, factor, tag.exceptionData, eType) } override fun onNewException(tag: T, factor: FactorFilter.SelectedFactor, exceptionStatus: ExceptionStatusType) { diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RTExcChangeRate.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RTExcChangeRate.kt new file mode 100644 index 0000000..c6360d3 --- /dev/null +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RTExcChangeRate.kt @@ -0,0 +1,114 @@ +package com.flightfeather.uav.biz.sourcetrace.exceptiontype + +import com.flightfeather.uav.biz.FactorFilter +import com.flightfeather.uav.biz.dataanalysis.BaseExceptionContinuous +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType +import com.flightfeather.uav.biz.sourcetrace.config.RTExcWindLevelConfig +import com.flightfeather.uav.biz.sourcetrace.model.PollutedClue +import com.flightfeather.uav.common.utils.MapUtil +import com.flightfeather.uav.domain.entity.BaseRealTimeData +import com.flightfeather.uav.lightshare.eunm.ExceptionStatusType +import com.flightfeather.uav.socket.eunm.FactorType +import java.time.Duration +import java.time.LocalDateTime +import java.time.ZoneId + +/** + * 鏁版嵁鍙樺寲閫熺巼寮傚父 + * @date 2025/6/10 + * @author feiyu02 + */ +class RTExcChangeRate(config: RTExcWindLevelConfig) : + BaseExceptionContinuous<ExceptionTag, RTExcWindLevelConfig, PollutedClue>(config, ExceptionTag::class.java) { + + constructor(config: RTExcWindLevelConfig, callback: NewPolluteClueCallback) : this(config){ + this.callback = callback + } + + private var callback: NewPolluteClueCallback? = null + + override fun getExceptionType(): ExceptionType { + return ExceptionType.TYPE9 + } + + override fun judgeException(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> { + val res = mutableMapOf<FactorType, Boolean>() + config.factorFilter.mainList().forEach { f -> + if (p?.getByFactorType(f) == null || n.getByFactorType(f) == null || n.windSpeed == null) { + res[f] = (false) + return@forEach + } + + val rate = config.changeRate[f] + + val pValue = p.getByFactorType(f)!! + val nValue = n.getByFactorType(f)!! + // 璁$畻鍚庝竴涓暟鎹浉姣斾簬鍓嶄竴涓暟鎹殑鍙樺寲閫熺巼 + val v = (nValue - pValue) + + val b1 = if (rate != null) { + v >= rate.mutationRate.first + } else { + false + } +// val r = (nValue - pValue) / pValue +// val b1 = r >= con.mutationRate.first && r < con.mutationRate.second + println("鍥犲瓙锛�${f.des}锛岄�熺巼锛�${v}锛�${b1}") + res[f] = b1 + } + return res + } + + override fun judgeExceptionCount(tag: ExceptionTag, factorType: FactorType?): Boolean { + return tag.exceptionData.size >= (config.changeRate[factorType]?.countLimit ?: 1) + } + + override fun needCut(tag: ExceptionTag, hasException: Boolean?): Boolean { + // 鎸夌収鏃堕暱鍜岃窛绂婚檺鍒跺皢寮傚父鎴彇 + if (tag.exceptionData.isEmpty()) return false + + val se = tag.exceptionData.first() + val ee = tag.exceptionData.last() + + val sTime = LocalDateTime.ofInstant(se.dataTime?.toInstant(), ZoneId.systemDefault()) + val eTime = LocalDateTime.ofInstant(ee.dataTime?.toInstant(), ZoneId.systemDefault()) + val duration = Duration.between(sTime, eTime).toMinutes() + // 鏁版嵁閲囨牱鐨勬椂闀胯秴杩囬檺鍒舵椂锛岄渶瑕佹埅鍙� + val b1 = duration > config.timeLimit + + // 璧拌埅鏁版嵁鐨勮窛绂昏秴杩囬檺鍒舵椂锛岄渶瑕佹埅鍙� + val b2 = if (se.longitude == null || se.latitude == null || ee.longitude == null || ee.latitude == null) { + false + } else { + val distance = MapUtil.getDistance( + se.longitude!!.toDouble(), se.latitude!!.toDouble(), ee.longitude!! + .toDouble(), ee.latitude!!.toDouble() + ) + distance > config.distanceLimit + } + + return b1 || b2 + } + + override fun immeExcCheck(tag: ExceptionTag, factorType: FactorType): Boolean { + // 寮傚父鍑虹幇绛変簬闄愬畾娆℃暟鏃讹紝灏遍渶瑕佸舰鎴愭薄鏌撶嚎绱� + return judgeExceptionCount(tag, factorType) + } + + override fun newResult(tag: ExceptionTag, factor: FactorFilter.SelectedFactor): PollutedClue { + return PollutedClue(tag, factor, getExceptionType(), config, config.changeRate[factor.main]) + } + + override fun onNewException( + tag: ExceptionTag, + factor: FactorFilter.SelectedFactor, + exceptionStatus: ExceptionStatusType, + ) { + super.onNewException(tag, factor, exceptionStatus) + callback?.let { func -> + val exc = tag.exceptionResult.last() + func.invoke(exc as PollutedClue) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionSlideAverage.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionSlideAverage.kt index 5aa8052..f08fce0 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionSlideAverage.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionSlideAverage.kt @@ -144,7 +144,7 @@ } - override fun newResult( + fun newResult( start: BaseRealTimeData, end: BaseRealTimeData?, factor: FactorFilter.SelectedFactor, diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt index 81bc08a..4c36a09 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/exceptiontype/RealTimeExceptionValueMutation.kt @@ -53,7 +53,7 @@ return res } - override fun judgeExceptionCount(tag: ExceptionTag): Boolean { + override fun judgeExceptionCount(tag: ExceptionTag, factorType: FactorType?): Boolean { val count = tag.exceptionData.size val b1 = special && count >= (config.mutationNum / 2) diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedArea.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedArea.kt index 2d0a968..563466a 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedArea.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedArea.kt @@ -20,18 +20,22 @@ */ constructor( + historyData: List<BaseRealTimeData>, exceptionData: List<BaseRealTimeData>, config: RTExcWindLevelConfig, - windLevelCondition: RTExcWindLevelConfig.WindLevelCondition, + windLevelCondition: RTExcWindLevelConfig.WindLevelCondition?, ) : this() { - distanceType = windLevelCondition.distanceType - sourceTrace(exceptionData, config, windLevelCondition) + distanceType = windLevelCondition?.distanceType + windLevelCondition?.let { sourceTrace(historyData, exceptionData, config, it) } } var address: String? = null - // 姹℃煋鑼冨洿鍖哄煙(缁忕含搴﹀杈瑰舰) + // 姹℃煋鑼冨洿鎵囧舰鍖哄煙(缁忕含搴﹀杈瑰舰) var polygon: List<Pair<Double, Double>>? = null + + // 杩戣窛绂绘薄鏌撳渾褰㈠尯鍩� + var closePolygon: List<Pair<Double, Double>>? = null // 姹℃煋鍙兘鐨勫彂鐢熻窛绂� var distanceType: DistanceType? = null @@ -40,6 +44,7 @@ * 鍙嶅悜婧簮 */ private fun sourceTrace( + historyData: List<BaseRealTimeData>, exceptionData: List<BaseRealTimeData>, config: RTExcWindLevelConfig, windLevelCondition: RTExcWindLevelConfig.WindLevelCondition, @@ -53,7 +58,7 @@ val pair = avgData.longitude!!.toDouble() to avgData.latitude!!.toDouble() polygon = calSector( - avgData.windSpeed!!.toDouble(), + avgData.windDirection!!.toDouble(), pair, windLevelCondition.distanceType.disRange, config.sourceTraceDegOffset @@ -61,6 +66,8 @@ // 灏嗗潗鏍囪浆鎹负gcj02锛堢伀鏄熷潗鏍囩郴锛夛紝鍥犱负姹℃煋婧愬満鏅俊鎭兘涓烘鍧愭爣绯� MapUtil.wgs84ToGcj02(it) } + + closePolygon = closeSourceTrace(historyData, pair) try { val address = AMapService.reGeo(pair) @@ -92,7 +99,13 @@ val result = mutableListOf<Pair<Double, Double>>() if (distanceRange.first == .0) { - result.add(center) +// result.add(center) + var startDeg = 0 + while (startDeg <= 360) { + val p = MapUtil.getPointByLen(center, 50.0, startDeg * PI / 180) + result.add(p) + startDeg++ + } } else { // 浠庡紑濮嬭搴﹀惊鐜绠楀潗鏍囩偣鑷崇粨鏉熻搴︼紝姝ラ暱1掳 var startDeg = sDeg @@ -101,16 +114,30 @@ result.add(p) startDeg++ } + if (distanceRange.second > .0) { + // 姝ゅ闇�瑕佷粠缁撴潫瑙掑害寮�濮嬪弽鍚戝惊鐜绠楄嚦寮�濮嬭搴︼紝姝ラ暱1掳锛屼娇寰椾袱缁勫潗鏍囩偣鎸夐『搴忔帓鍒楋紝鍙粯鍒跺搴旂殑澶氳竟褰� + startDeg = eDeg + while (startDeg >= sDeg) { + val p = MapUtil.getPointByLen(center, distanceRange.second, startDeg * PI / 180) + result.add(p) + startDeg-- + } + } } - if (distanceRange.second > .0) { - // 姝ゅ闇�瑕佷粠缁撴潫瑙掑害寮�濮嬪弽鍚戝惊鐜绠楄嚦寮�濮嬭搴︼紝姝ラ暱1掳锛屼娇寰椾袱缁勫潗鏍囩偣鎸夐『搴忔帓鍒楋紝鍙粯鍒跺搴旂殑澶氳竟褰� - var startDeg = eDeg - while (startDeg >= sDeg) { - val p = MapUtil.getPointByLen(center, distanceRange.second, startDeg * PI / 180) - result.add(p) - startDeg-- - } + return result + } + + private fun closeSourceTrace( + historyData: List<BaseRealTimeData>, + center: Pair<Double, Double>, + ): List<Pair<Double, Double>> { + val result = mutableListOf<Pair<Double, Double>>() + var startDeg = 0 + while (startDeg <= 360) { + val p = MapUtil.getPointByLen(center, 50.0, startDeg * PI / 180) + result.add(p) + startDeg++ } return result diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedClue.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedClue.kt index 6775572..53fbd07 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedClue.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedClue.kt @@ -2,6 +2,7 @@ import com.flightfeather.uav.biz.FactorFilter import com.flightfeather.uav.biz.dataanalysis.BaseExceptionResult +import com.flightfeather.uav.biz.dataanalysis.model.ExceptionTag import com.flightfeather.uav.biz.dataanalysis.model.ExceptionType import com.flightfeather.uav.biz.sourcetrace.config.RTExcWindLevelConfig import com.flightfeather.uav.common.utils.DateUtil @@ -18,19 +19,34 @@ */ class PollutedClue() : BaseExceptionResult() { +// constructor( +// start: BaseRealTimeData, +// end: BaseRealTimeData?, +// factor: FactorFilter.SelectedFactor, +// exceptionData: List<BaseRealTimeData>, +// eType: ExceptionType, +// config: RTExcWindLevelConfig, +// windLevelCondition: RTExcWindLevelConfig.WindLevelCondition?, +// ) : this() { +// if (exceptionData.isEmpty()) return +// pollutedData = PollutedData(start, end, factor, exceptionData, eType, windLevelCondition) +// pollutedArea = PollutedArea(exceptionData, config, windLevelCondition) +// } + constructor( - start: BaseRealTimeData, - end: BaseRealTimeData?, - factor: FactorFilter.SelectedFactor, - exceptionData: List<BaseRealTimeData>, - eType: ExceptionType, - config: RTExcWindLevelConfig, - windLevelCondition: RTExcWindLevelConfig.WindLevelCondition - ) : this() { - this.factor = factor - if (exceptionData.isEmpty()) return - pollutedData = PollutedData(start, end, factor, exceptionData, eType, windLevelCondition) - pollutedArea = PollutedArea(exceptionData, config, windLevelCondition) + tag: ExceptionTag, factor: FactorFilter.SelectedFactor, eType: ExceptionType, config: RTExcWindLevelConfig, + windLevelCondition: RTExcWindLevelConfig.WindLevelCondition?, + ) :this() +// this( +// tag.startData!!, tag.endData, factor, tag.exceptionData, eType, config, +// windLevelCondition +// ) + { + if (tag.exceptionData.isEmpty()) return + pollutedData = PollutedData( + tag.startData!!, tag.endData, factor, tag.exceptionData, tag.historyData, eType, windLevelCondition + ) + pollutedArea = PollutedArea(tag.historyData, tag.exceptionData, config, windLevelCondition) } /** @@ -43,13 +59,13 @@ var pollutedSource: PollutedSource? = null - private var factor: FactorFilter.SelectedFactor? = null - /** * 鏌ユ壘绯荤粺鍐呴儴婧簮鑼冨洿鍐呯殑姹℃煋浼佷笟 */ fun searchScenes(sceneInfoRep: SceneInfoRep) { - if (pollutedArea == null || factor == null) return - pollutedSource = PollutedSource().also { it.searchScenes(pollutedArea!!, sceneInfoRep, factor!!) } + if (pollutedArea == null || pollutedData == null) return + pollutedSource = PollutedSource().also { + it.searchScenes(pollutedArea!!, sceneInfoRep, pollutedData!!) + } } } \ No newline at end of file diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedData.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedData.kt index 56190ed..4a599d7 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedData.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedData.kt @@ -28,8 +28,9 @@ end: BaseRealTimeData?, factor: FactorFilter.SelectedFactor, exceptionData: List<BaseRealTimeData>, + historyData: List<BaseRealTimeData>, eType: ExceptionType, - windLevelCondition: RTExcWindLevelConfig.WindLevelCondition, + windLevelCondition: RTExcWindLevelConfig.WindLevelCondition?, ) : this() { exception = eType.des exceptionType = eType.value @@ -47,14 +48,15 @@ endData = end windSpeed = exceptionData.first().windSpeed?.toDouble() - percentage = windLevelCondition.mutationRate.first - times = windLevelCondition.countLimit + percentage = windLevelCondition?.mutationRate?.first + times = windLevelCondition?.countLimit dataList.add(start) exceptionData.forEach { dataList.add(it) } dataVoList.addAll(dataList.map { it.toDataVo() }) + historyDataList.addAll(historyData.map { it.toDataVo() }) calPer() } @@ -87,6 +89,7 @@ // 鍙戠敓娆℃暟 var times: Int? = null + var historyDataList = mutableListOf<DataVo>() // 寮傚父鐩戞祴鏁版嵁 var dataList: MutableList<BaseRealTimeData> = mutableListOf() var dataVoList: MutableList<DataVo> = mutableListOf() diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt index 7817607..d74ceaa 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt @@ -1,6 +1,5 @@ package com.flightfeather.uav.biz.sourcetrace.model -import com.flightfeather.uav.biz.FactorFilter import com.flightfeather.uav.common.utils.MapUtil import com.flightfeather.uav.domain.entity.SceneInfo import com.flightfeather.uav.domain.repository.SceneInfoRep @@ -10,7 +9,7 @@ import com.flightfeather.uav.socket.eunm.FactorType import org.springframework.beans.BeanUtils import org.springframework.web.context.ContextLoader -import kotlin.math.min +import kotlin.math.round /** * 姹℃煋鏉ユ簮 @@ -26,33 +25,29 @@ */ // 婧簮浼佷笟 - var sceneList:List<SceneInfoVo?>? = null + var sceneList: List<SceneInfoVo?>? = null - init { + // 婧簮鎺ㄧ悊缁撹 + var conclusion: String? = null - } - - fun searchScenes(pollutedArea: PollutedArea, factor: FactorFilter.SelectedFactor) { + fun searchScenes(pollutedArea: PollutedArea, pollutedData: PollutedData) { ContextLoader.getCurrentWebApplicationContext()?.getBean(SceneInfoRep::class.java)?.run { - searchScenes(pollutedArea, this, factor) + searchScenes(pollutedArea, this, pollutedData) } } /** * 鏌ユ壘绯荤粺鍐呴儴婧簮鑼冨洿鍐呯殑姹℃煋浼佷笟 */ - fun searchScenes(pollutedArea: PollutedArea, sceneInfoRep: SceneInfoRep, factor: FactorFilter.SelectedFactor) { + fun searchScenes(pollutedArea: PollutedArea, sceneInfoRep: SceneInfoRep, pollutedData: PollutedData) { // Fixme 2025.5.14: 姹℃煋婧愮殑鍧愭爣鏄珮寰峰湴鍥惧潗鏍囩郴锛堢伀鏄熷潗鏍囩郴锛夛紝鑰岃蛋鑸暟鎹槸WGS84鍧愭爣绯� // 鎸夌収鍖哄煙妫�绱㈠唴閮ㄦ薄鏌撴簮淇℃伅 - // 1. 棣栧厛鎸夌収鍥涜嚦鑼冨洿浠庢暟鎹簱鍒濇绛涢�夋薄鏌撴簮 -// val polygonTmp = pollutedArea.polygon!!.map { -// MapUtil.gcj02ToWgs84(it) -// } + var result = mutableListOf<SceneInfo>() + // 1. 棣栧厛鎸夌収鍥涜嚦鑼冨洿浠庢暟鎹簱鍒濇绛涢�夋薄鏌撴簮锛屾澶勭殑鍖哄煙鍧愭爣宸茶浆鎹负鐏槦鍧愭爣绯� val polygonTmp = pollutedArea.polygon!! val fb = MapUtil.calFourBoundaries(polygonTmp) val sceneList = sceneInfoRep.findByCoordinateRange(fb) // 2. 鍐嶇簿纭垽鏂槸鍚﹀湪鍙嶅悜婧簮鍖哄煙澶氳竟褰㈠唴閮� - val result = mutableListOf<SceneInfo>() sceneList.forEach { val point = it!!.longitude.toDouble() to it.latitude.toDouble() if (MapUtil.isPointInPolygon(point, polygonTmp)) { @@ -60,27 +55,91 @@ } } - findClosestStation(sceneInfoRep, result) + val closePolygonTmp = pollutedArea.closePolygon!! + val closeFb = MapUtil.calFourBoundaries(closePolygonTmp) + val closeSceneList = sceneInfoRep.findByCoordinateRange(closeFb) + // 2. 鍐嶇簿纭垽鏂槸鍚﹀湪鍙嶅悜婧簮鍖哄煙澶氳竟褰㈠唴閮� + closeSceneList.forEach { + val point = it!!.longitude.toDouble() to it.latitude.toDouble() + if (MapUtil.isPointInPolygon(point, closePolygonTmp)) { + result.add(it) + } + } + // 鏍规嵁姹℃煋鍥犲瓙鐨勯噺绾э紝璁$畻涓昏鐨勬薄鏌撳満鏅被鍨嬶紝绛涢�夌粨鏋� + val mainSceneType = calSceneType(pollutedData) + if (mainSceneType != null) { + this.conclusion = mainSceneType.first + result = result.filter { + val r = mainSceneType.second.find { s-> + s.value == it.typeId.toInt() + } + r != null + }.toMutableList() + } -// TODO("鎸夌収鎵�閫夌洃娴嬪洜瀛愮被鍨嬶紝鍖哄垎姹℃煋婧愮被鍨�") + this.sceneList = findClosestStation(sceneInfoRep, result) } /** - * 璁$畻鍙兘鐨勭浉鍏虫薄鏌撳満鏅被鍨� + * 璁$畻鍙兘鐨勭浉鍏虫薄鏌撳満鏅被鍨嬩互鍙婃帹鐞嗙粨璁� */ - private fun calFactorType(factor: FactorFilter.SelectedFactor) { -// when (factor.main) { -// FactorType.PM25 -> {} -// -// } + @Throws(Exception::class) + private fun calSceneType(pollutedData: PollutedData): Pair<String, List<SceneType>>? { + when (pollutedData.selectedFactor?.main) { + // 姘哀鍖栧悎鐗╋紝涓�鑸敱浜庢満鍔ㄨ溅灏炬皵锛屽悓姝ヨ绠桟O + FactorType.NO2 -> { + val coAvg = round(pollutedData.dataList.map { it.co!! }.average()) / 1000 + return "姘哀鍖栧悎鐗╁亸楂橈紝CO鐨勯噺绾т负${coAvg}mg/m鲁锛屼竴鑸敱浜庢満鍔ㄨ溅灏炬皵閫犳垚锛屾薄鏌撴簮浠ユ苯淇�佸姞娌圭珯涓轰富" to + listOf(SceneType.TYPE6, SceneType.TYPE10, SceneType.TYPE17) + } + + FactorType.CO -> return null + + FactorType.H2S -> return null + + FactorType.SO2 -> return null + + FactorType.O3 -> return null + // a) pm2.5銆乸m10鐗瑰埆楂橈紝涓よ�呭湪鍚勬儏鍐典笅鍚屾灞曠ず锛宲m2.5鍗爌m10鐨勬瘮閲嶅彉鍖栵紝姣旈噸瓒婇珮锛岃秺鏈夊彲鑳芥槸椁愰ギ + // b) pm10鐗瑰埆楂樸�乸m2.5杈冮珮锛屽ぇ棰楃矑鎵皹姹℃煋锛屽彧灞曠ずpm10锛宲m2.5鍗爌m10鐨勬瘮閲嶅彉鍖栵紝宸ュ湴涓轰富 + FactorType.PM25, + FactorType.PM10, + -> { + // 璁$畻寮傚父鏁版嵁鐨刾m2.5鍗爌m10姣旈噸鐨勫潎鍊� + val percentageAvg = pollutedData.dataList.map { + it.pm25!! / it.pm10!! + }.average() + return if (percentageAvg > 0.666) { + "PM2.5鍗燩M10鐨勬瘮閲嶄负${round(percentageAvg * 100)}%锛屾瘮閲嶈緝澶э紝姹℃煋婧愪互椁愰ギ涓轰富锛屽伐鍦版涔�" to + listOf(SceneType.TYPE1, SceneType.TYPE2, SceneType.TYPE3, SceneType.TYPE14, SceneType.TYPE5) + } else if (percentageAvg < 0.333) { + "PM2.5鍗燩M10鐨勬瘮閲嶄负${round(percentageAvg * 100)}%锛屾瘮閲嶈緝灏忥紝灞炰簬澶ч绮掓壃灏樻薄鏌擄紝姹℃煋婧愪互宸ュ湴涓轰富" to + listOf(SceneType.TYPE1, SceneType.TYPE2, SceneType.TYPE3, SceneType.TYPE14, SceneType.TYPE5) + } else { + "PM2.5鍗燩M10鐨勬瘮閲嶄负${round(percentageAvg * 100)}%锛屾薄鏌撴簮浠ラ楗�佸伐鍦颁负涓�" to + listOf(SceneType.TYPE1, SceneType.TYPE2, SceneType.TYPE3, SceneType.TYPE14, SceneType.TYPE5) + } + } + // c) VOC杈冮珮锛屽悓姣旇绠梡m2.5鐨勯噺绾э紝鍙兘瀛樺湪鍚屾鍋忛珮锛堟苯淇�佸姞娌圭珯锛�, 鍚屾璁$畻O3鏄惁鏈夐珮鍊� + // d) VOC杈冮珮锛屽浜庡姞娌圭珯锛堣溅杈嗘嫢鍫垫儏鍐碉級锛孋O涓�鑸緝楂�, 鍚屾璁$畻O3鏄惁鏈夐珮鍊� + FactorType.VOC -> { + val pm25Avg = round(pollutedData.dataList.map { it.pm25!! }.average() * 10) / 10 + val coAvg = round(pollutedData.dataList.map { it.co!! }.average()) / 1000 + val o3Avg = round(pollutedData.dataList.map { it.o3!! }.average() * 10) / 10 + return "VOC鍋忛珮锛屽悓鏃禤M2.5閲忕骇涓�${pm25Avg}渭g/m鲁锛孋O閲忕骇涓�${coAvg}mg/m鲁锛孫3閲忕骇涓�${o3Avg}渭g/m鲁锛屾薄鏌撴簮浠ユ苯淇�佸姞娌圭珯涓轰富" to + listOf(SceneType.TYPE6, SceneType.TYPE17, SceneType.TYPE12) + } + + else -> return null + } } /** * 璁$畻鏈�杩戠殑鐩戞祴绔欑偣 */ - private fun findClosestStation(sceneInfoRep: SceneInfoRep, sceneList: List<SceneInfo>) { + private fun findClosestStation(sceneInfoRep: SceneInfoRep, sceneList: List<SceneInfo>): List<SceneInfoVo> { val res1 = sceneInfoRep.findByArea(AreaVo().apply { sceneTypeId = SceneType.TYPE19.value.toString() }) @@ -90,10 +149,10 @@ }) val res = res1.toMutableList().apply { addAll(res2) } - this.sceneList = sceneList.map { + return sceneList.map { var minLen = -1.0 var selectedRes: SceneInfo? = null - res.forEach { r-> + res.forEach { r -> val dis = MapUtil.getDistance( it.longitude.toDouble(), it.latitude.toDouble(), diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSummary.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSummary.kt index 5b3c06a..140c499 100644 --- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSummary.kt +++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSummary.kt @@ -31,11 +31,11 @@ /** * 鍒嗘瀽缁撴灉 */ - inner class AnalysisResult{ + inner class AnalysisResult { // 鎸夌収琚壂鎻忔鏁伴檷搴忔帓鍒楃殑姹℃煋婧愬垪琛� var sortedSceneList: List<Pair<SceneInfo?, Int>>? = null var time: Date? = null - var advice:String?= null + var advice: String? = null var direction: AMapService.AMapDirection? = null } @@ -60,7 +60,7 @@ private var analysisTimer: Timer? = null // 瀹氭椂姹℃煋鍒嗘瀽浠诲姟 - private var lastAnalysisOnTimeTask:TimerTask? = null + private var lastAnalysisOnTimeTask: TimerTask? = null // 瀹氭椂姹℃煋鍒嗘瀽浠诲姟杩愯鐘舵�� private var analysisTaskIsRunning = false @@ -128,8 +128,8 @@ val statistic = AnalysisStatistic() // 鍏辨湁澶氬皯鐩稿叧姹℃煋婧愶紝鍝簺姹℃煋婧愯鎵弿娆℃暟杈冨 val sceneMap = mutableMapOf<String?, Pair<SceneInfo?, Int>>() - clueList.forEach {c-> - c.pollutedSource?.sceneList?.forEach { s-> + clueList.forEach { c -> + c.pollutedSource?.sceneList?.forEach { s -> if (!sceneMap.containsKey(s?.guid)) { sceneMap[s?.guid] = s to 1 } else { @@ -145,11 +145,12 @@ * 绾跨储鍒嗘瀽 */ private fun analysis() { + if (clueList.isEmpty()) return val result = AnalysisResult() // 鍏辨湁澶氬皯鐩稿叧姹℃煋婧愶紝鍝簺姹℃煋婧愯鎵弿娆℃暟杈冨 val sceneMap = mutableMapOf<String?, Pair<SceneInfo?, Int>>() - clueList.forEach {c-> - c.pollutedSource?.sceneList?.forEach { s-> + clueList.forEach { c -> + c.pollutedSource?.sceneList?.forEach { s -> if (!sceneMap.containsKey(s?.guid)) { sceneMap[s?.guid] = s to 1 } else { @@ -157,31 +158,34 @@ } } } - val res = sceneMap.entries.sortedBy { it.value.second } + val res = sceneMap.entries.sortedByDescending { it.value.second } result.sortedSceneList = res.map { it.value } // 褰撳墠鐨勮蛋鑸暟鎹殑瀹氫綅鍜屾薄鏌撴簮璺濈鏄惁鏄�愭笎鎺ヨ繎锛岃嫢璧拌埅杩滅浜嗕富瑕佹薄鏌撴簮锛屾彁绀虹敤鎴疯皟鏁磋蛋鑸矾绾� if (!result.sortedSceneList.isNullOrEmpty()) { val sT = clueList.first().pollutedData?.startTime val closetScene = result.sortedSceneList?.first() - result.advice = "鏍规嵁${sT}璧风殑${clueList.size}鏉℃渶鏂版薄鏌撶嚎绱紝姹℃煋婧怺${closetScene?.first?.name}]琚娆℃函婧愶紝鍏锋湁杈冮珮姹℃煋椋庨櫓锛岀幇鎻愪緵鏂扮殑璧拌埅鎺ㄨ崘璺嚎锛屽彲缁忚繃璇ユ薄鏌撴簮銆�" - + // 璧拌埅璺嚎璋冩暣寤鸿 + result.advice = + "鏍规嵁${sT}璧风殑${clueList.size}鏉℃渶鏂版薄鏌撶嚎绱紝姹℃煋婧愩��${closetScene?.first?.name}銆戣澶氭婧簮锛屽叿鏈夎緝楂樻薄鏌撻闄╋紝鐜版彁渚涙柊鐨勮蛋鑸帹鑽愯矾绾匡紝鍙粡杩囪姹℃煋婧愩��" val lastP = realTimeDataList.last() + // 寤鸿瀵瑰簲鐨勬暟鎹噰鏍锋椂闂� + result.time = lastP.dataTime if (lastP.longitude != null && lastP.latitude != null && lastP.longitude!! > BigDecimal.ZERO && lastP.latitude!! > BigDecimal.ZERO && closetScene?.first?.longitude != null && closetScene.first?.latitude != null && - closetScene.first?.longitude!! > BigDecimal.ZERO && closetScene.first?.latitude!! > BigDecimal.ZERO) { + closetScene.first?.longitude!! > BigDecimal.ZERO && closetScene.first?.latitude!! > BigDecimal.ZERO + ) { val origin = MapUtil.wgs84ToGcj02(lastP.longitude!!.toDouble() to lastP.latitude!!.toDouble()) val destination = closetScene.first!!.longitude.toDouble() to closetScene.first!!.latitude.toDouble() + // 寤鸿鐨勮蛋鑸矾绾� result.direction = AMapService.directionDriving(origin, destination) } } - - result.time = realTimeDataList.last().dataTime // 绾跨储鍒嗘瀽瀹屾垚鍚庯紝绉诲姩鑷冲巻鍙茬嚎绱㈠垪琛� historyClueList.addAll(clueList) clueList.clear() diff --git a/src/test/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSourceTest.kt b/src/test/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSourceTest.kt index f6ceaa0..a31858a 100644 --- a/src/test/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSourceTest.kt +++ b/src/test/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSourceTest.kt @@ -13,21 +13,22 @@ @SpringBootTest class PollutedSourceTest { - @Autowired - lateinit var sceneInfoRep: SceneInfoRep + @Autowired + lateinit var sceneInfoRep: SceneInfoRep - @Test - fun foo1() { - val source = PollutedSource() - val pollutedArea = PollutedArea().apply { - polygon = listOf( - 121.421521 to 31.195457, - 121.421721 to 31.195457, - 121.421521 to 31.195257, - 121.421721 to 31.195257, - ) - } - source.searchScenes(pollutedArea, sceneInfoRep, FactorFilter.SelectedFactor(FactorType.VOC)) + @Test + fun foo1() { + val source = PollutedSource() + val pollutedData = PollutedData() + val pollutedArea = PollutedArea().apply { + polygon = listOf( + 121.421521 to 31.195457, + 121.421721 to 31.195457, + 121.421521 to 31.195257, + 121.421721 to 31.195257, + ) + } + source.searchScenes(pollutedArea, sceneInfoRep, pollutedData) - } + } } \ No newline at end of file -- Gitblit v1.9.3