From b10c22af595bd995e56946bff63b8f2f984b13e8 Mon Sep 17 00:00:00 2001 From: feiyu02 <risaku@163.com> Date: 星期四, 14 八月 2025 17:25:05 +0800 Subject: [PATCH] 2025.8.14 1. 动态溯源模块添加滑动平均异常计算(调试中) --- src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt | 224 +++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 143 insertions(+), 81 deletions(-) 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 1543d33..d25f252 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,5 +1,6 @@ package com.flightfeather.uav.biz.sourcetrace.model +import com.flightfeather.uav.common.utils.DateUtil import com.flightfeather.uav.common.utils.MapUtil import com.flightfeather.uav.domain.entity.SceneInfo import com.flightfeather.uav.domain.repository.SceneInfoRep @@ -25,7 +26,7 @@ */ // 婧簮浼佷笟 - var sceneList: List<SceneInfoVo?>? = null + var sceneList: List<SceneInfoVo>? = null // 婧簮鎺ㄧ悊缁撹 var conclusion: String? = null @@ -44,42 +45,47 @@ // 鎸夌収鍖哄煙妫�绱㈠唴閮ㄦ薄鏌撴簮淇℃伅 var result = mutableListOf<SceneInfo>() // 1. 棣栧厛鎸夌収鍥涜嚦鑼冨洿浠庢暟鎹簱鍒濇绛涢�夋薄鏌撴簮锛屾澶勭殑鍖哄煙鍧愭爣宸茶浆鎹负鐏槦鍧愭爣绯� - val polygonTmp = pollutedArea.polygon!! - val fb = MapUtil.calFourBoundaries(polygonTmp) - val sceneList = sceneInfoRep.findByCoordinateRange(fb) - // 2. 鍐嶇簿纭垽鏂槸鍚﹀湪鍙嶅悜婧簮鍖哄煙澶氳竟褰㈠唴閮� - sceneList.forEach { - val point = it!!.longitude.toDouble() to it.latitude.toDouble() - if (MapUtil.isPointInPolygon(point, polygonTmp)) { - result.add(it) - } - } + val polygonTmp = pollutedArea.polygon + this.sceneList = emptyList() - 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() + if (polygonTmp != null) { + val fb = MapUtil.calFourBoundaries(polygonTmp) + val sceneList = sceneInfoRep.findByCoordinateRange(fb) + // 2. 鍐嶇簿纭垽鏂槸鍚﹀湪鍙嶅悜婧簮鍖哄煙澶氳竟褰㈠唴閮� + sceneList.forEach { + val point = it!!.longitude.toDouble() to it.latitude.toDouble() + if (MapUtil.isPointInPolygon(point, polygonTmp)) { + result.add(it) } - r != null - }.toMutableList() + } + + 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() + } + this.sceneList = findClosestStation(sceneInfoRep, result) } - this.sceneList = findClosestStation(sceneInfoRep, result) - + val txt = summaryTxt(pollutedData, this.sceneList!!) + this.conclusion = txt } /** @@ -87,57 +93,82 @@ */ @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, - -> { - val pm25Avg = round(pollutedData.dataList.map { it.pm25!! }.average() * 10) / 10 - val pm10Avg = round(pollutedData.dataList.map { it.pm10!! }.average() * 10) / 10 - // 璁$畻寮傚父鏁版嵁鐨刾m2.5鍗爌m10姣旈噸鐨勫潎鍊� - val percentageAvg = pollutedData.dataList.map { - it.pm25!! / it.pm10!! - }.average() - val str = - "PM2.5閲忕骇涓�${pm25Avg}渭g/m鲁锛孭M10閲忕骇涓�${pm25Avg}渭g/m鲁锛孭M2.5鍗燩M10鐨勬瘮閲嶄负${round(percentageAvg * 100)}%" - return if (percentageAvg > 0.666) { - "${str}锛屾瘮閲嶈緝澶э紝姹℃煋婧愪互椁愰ギ涓轰富锛屽伐鍦版涔�" to - listOf(SceneType.TYPE1, SceneType.TYPE2, SceneType.TYPE3, SceneType.TYPE14, SceneType.TYPE5) - } else if (percentageAvg < 0.333) { - "${str}锛屾瘮閲嶈緝灏忥紝灞炰簬澶ч绮掓壃灏樻薄鏌擄紝姹℃煋婧愪互宸ュ湴涓轰富" to - listOf(SceneType.TYPE1, SceneType.TYPE2, SceneType.TYPE3, SceneType.TYPE14, SceneType.TYPE5) - } else { - "${str}锛屾薄鏌撴簮浠ラ楗�佸伐鍦颁负涓�" to - listOf(SceneType.TYPE1, SceneType.TYPE2, SceneType.TYPE3, SceneType.TYPE14, SceneType.TYPE5) + var des: String? = null + val sceneTypes = mutableListOf<SceneType>() + pollutedData.statisticMap.entries.forEach { s -> + val res = when (s.key) { + // 姘哀鍖栧悎鐗╋紝涓�鑸敱浜庢満鍔ㄨ溅灏炬皵锛屽悓姝ヨ绠桟O + FactorType.NO2 -> { + val coAvg = round(pollutedData.dataList.map { it.co!! }.average()) / 1000 + "姘哀鍖栧悎鐗╁亸楂橈紝CO鐨勯噺绾т负${coAvg}mg/m鲁锛屼竴鑸敱浜庢満鍔ㄨ溅灏炬皵閫犳垚锛屾薄鏌撴簮浠ユ苯淇�佸姞娌圭珯涓轰富" to + listOf(SceneType.TYPE6, SceneType.TYPE10, SceneType.TYPE17) } - } - // 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 + FactorType.CO -> null + + FactorType.H2S -> null + + FactorType.SO2 -> null + + FactorType.O3 -> null + // a) pm2.5銆乸m10鐗瑰埆楂橈紝涓よ�呭湪鍚勬儏鍐典笅鍚屾灞曠ず锛宲m2.5鍗爌m10鐨勬瘮閲嶅彉鍖栵紝姣旈噸瓒婇珮锛岃秺鏈夊彲鑳芥槸椁愰ギ + // b) pm10鐗瑰埆楂樸�乸m2.5杈冮珮锛屽ぇ棰楃矑鎵皹姹℃煋锛屽彧灞曠ずpm10锛宲m2.5鍗爌m10鐨勬瘮閲嶅彉鍖栵紝宸ュ湴涓轰富 + FactorType.PM25, + FactorType.PM10, + -> { + val pm25Avg = round(pollutedData.dataList.map { it.pm25!! }.average() * 10) / 10 + val pm10Avg = round(pollutedData.dataList.map { it.pm10!! }.average() * 10) / 10 + // 璁$畻寮傚父鏁版嵁鐨刾m2.5鍗爌m10姣旈噸鐨勫潎鍊� + val percentageAvg = pollutedData.dataList.map { + it.pm25!! / it.pm10!! + }.average() + val str = + "PM2.5閲忕骇涓�${pm25Avg}渭g/m鲁锛孭M10閲忕骇涓�${pm10Avg}渭g/m鲁锛孭M2.5鍗燩M10鐨勬瘮閲嶄负${round(percentageAvg * 100)}%" + if (percentageAvg > 0.666) { + "${str}锛屾瘮閲嶈緝澶э紝姹℃煋婧愪互椁愰ギ涓轰富锛屽伐鍦版涔�" to + listOf( + SceneType.TYPE1, + SceneType.TYPE2, + SceneType.TYPE3, + SceneType.TYPE14, + SceneType.TYPE5 + ) + } else if (percentageAvg < 0.333) { + "${str}锛屾瘮閲嶈緝灏忥紝灞炰簬澶ч绮掓壃灏樻薄鏌擄紝姹℃煋婧愪互宸ュ湴涓轰富" to + listOf( + SceneType.TYPE1, + SceneType.TYPE2, + SceneType.TYPE3, + SceneType.TYPE14, + SceneType.TYPE5 + ) + } else { + "${str}锛屾薄鏌撴簮浠ラ楗�佸伐鍦颁负涓�" 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 + "VOC鍋忛珮锛屽悓鏃禤M2.5閲忕骇涓�${pm25Avg}渭g/m鲁锛孋O閲忕骇涓�${coAvg}mg/m鲁锛孫3閲忕骇涓�${o3Avg}渭g/m鲁锛屾薄鏌撴簮浠ユ苯淇�佸姞娌圭珯涓轰富" to + listOf(SceneType.TYPE6, SceneType.TYPE17, SceneType.TYPE12) + } + + else -> null + } + des = res?.first + res?.second?.let { sceneTypes.addAll(it) } } + return (des ?: "") to sceneTypes } /** @@ -176,4 +207,35 @@ return@map vo } } + + private fun summaryTxt(pollutedData: PollutedData, sceneList: List<SceneInfoVo>): String { +// pollutedData.exception +// pollutedData.selectedFactor?.main + val st = DateUtil.instance.getTime(pollutedData.startTime) + val et = DateUtil.instance.getTime(pollutedData.endTime) + var txt = + "鍦�${st}鑷�${et}涔嬮棿锛屽嚭鐜�${pollutedData.exception}" + pollutedData.statisticMap.entries.forEach { s -> + txt += "锛�${s.key.des}鏈�浣庡�间负${s.value.min}渭g/m鲁锛屾渶楂樺�间负${s.value.max}渭g/m鲁锛屽潎鍊间负${s.value.avg}渭g/m鲁" + } + if (sceneList.isEmpty()) { + txt += ("锛屽彲鑳藉瓨鍦ㄩ殣钘忛闄╂簮銆�") + } else { + txt += ("锛屽彂鐜�${sceneList.size}涓闄╂簮锛屽寘鍚�") + + val sizeMap = mutableMapOf<String, Int>() + sceneList.forEach { + if (!sizeMap.containsKey(it.type)) { + sizeMap[it.type] = 0 + } + sizeMap[it.type] = sizeMap[it.type]!! + 1 + } + sizeMap.forEach { (t, u) -> + txt += ("${u}涓�${t}锛�") + } + txt = txt.replaceRange(txt.length - 1, txt.length, "銆�") + } + + return txt + } } \ No newline at end of file -- Gitblit v1.9.3