From c56e1e74426238939f229f0005828d05089715ff Mon Sep 17 00:00:00 2001 From: feiyu02 <risaku@163.com> Date: 星期四, 03 七月 2025 17:30:58 +0800 Subject: [PATCH] 2025.7.3 1. 新增动态污染溯源新的判定逻辑 --- src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt | 149 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 139 insertions(+), 10 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 de0dc62..1543d33 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,9 +1,15 @@ 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 +import com.flightfeather.uav.lightshare.bean.AreaVo +import com.flightfeather.uav.lightshare.bean.SceneInfoVo +import com.flightfeather.uav.lightshare.eunm.SceneType +import com.flightfeather.uav.socket.eunm.FactorType +import org.springframework.beans.BeanUtils +import org.springframework.web.context.ContextLoader +import kotlin.math.round /** * 姹℃煋鏉ユ簮 @@ -19,22 +25,29 @@ */ // 婧簮浼佷笟 - var sceneList:List<SceneInfo?>? = null + var sceneList: List<SceneInfoVo?>? = null + + // 婧簮鎺ㄧ悊缁撹 + var conclusion: String? = null + + fun searchScenes(pollutedArea: PollutedArea, pollutedData: PollutedData) { + ContextLoader.getCurrentWebApplicationContext()?.getBean(SceneInfoRep::class.java)?.run { + 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. 棣栧厛鎸夌収鍥涜嚦鑼冨洿浠庢暟鎹簱鍒濇绛涢�夋薄鏌撴簮锛岄渶瑕佸厛灏嗗潗鏍囪浆鎹负gcj02锛堢伀鏄熷潗鏍囩郴锛夛紝鍥犱负姹℃煋婧愬満鏅俊鎭兘涓烘鍧愭爣绯� - 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)) { @@ -42,9 +55,125 @@ } } - this.sceneList = 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) + } + } - TODO("鎸夌収鎵�閫夌洃娴嬪洜瀛愮被鍨嬶紝鍖哄垎姹℃煋婧愮被鍨�") + // 鏍规嵁姹℃煋鍥犲瓙鐨勯噺绾э紝璁$畻涓昏鐨勬薄鏌撳満鏅被鍨嬶紝绛涢�夌粨鏋� + 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) + + } + + /** + * 璁$畻鍙兘鐨勭浉鍏虫薄鏌撳満鏅被鍨嬩互鍙婃帹鐞嗙粨璁� + */ + @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) + } + } + // 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>): List<SceneInfoVo> { + val res1 = sceneInfoRep.findByArea(AreaVo().apply { + sceneTypeId = SceneType.TYPE19.value.toString() + }) + + val res2 = sceneInfoRep.findByArea(AreaVo().apply { + sceneTypeId = SceneType.TYPE20.value.toString() + }) + val res = res1.toMutableList().apply { addAll(res2) } + + return sceneList.map { + var minLen = -1.0 + var selectedRes: SceneInfo? = null + res.forEach { r -> + val dis = MapUtil.getDistance( + it.longitude.toDouble(), + it.latitude.toDouble(), + r!!.longitude.toDouble(), + r.latitude.toDouble() + ) + if (minLen < 0 || dis < minLen) { + minLen = dis + selectedRes = r + } + } + val vo = SceneInfoVo() + BeanUtils.copyProperties(it, vo) + vo.closestStation = selectedRes + vo.length = minLen + + return@map vo + } } } \ No newline at end of file -- Gitblit v1.9.3