feiyu02
2025-07-16 8fc27dba6719041402e3e3c099e2f3e01d9d52c7
src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt
@@ -90,57 +90,82 @@
     */
    @Throws(Exception::class)
    private fun calSceneType(pollutedData: PollutedData): Pair<String, List<SceneType>>? {
        when (pollutedData.selectedFactor?.main) {
            // 氮氧化合物,一般由于机动车尾气,同步计算CO
            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、pm10特别高,两者在各情况下同步展示,pm2.5占pm10的比重变化,比重越高,越有可能是餐饮
            // b) pm10特别高、pm2.5较高,大颗粒扬尘污染,只展示pm10,pm2.5占pm10的比重变化,工地为主
            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
                // 计算异常数据的pm2.5占pm10比重的均值
                val percentageAvg = pollutedData.dataList.map {
                    it.pm25!! / it.pm10!!
                }.average()
                val str =
                    "PM2.5量级为${pm25Avg}μg/m³,PM10量级为${pm10Avg}μg/m³,PM2.5占PM10的比重为${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) {
                // 氮氧化合物,一般由于机动车尾气,同步计算CO
                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较高,同比计算pm2.5的量级,可能存在同步偏高(汽修、加油站), 同步计算O3是否有高值
            // d) VOC较高,处于加油站(车辆拥堵情况),CO一般较高, 同步计算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偏高,同时PM2.5量级为${pm25Avg}μg/m³,CO量级为${coAvg}mg/m³,O3量级为${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、pm10特别高,两者在各情况下同步展示,pm2.5占pm10的比重变化,比重越高,越有可能是餐饮
                // b) pm10特别高、pm2.5较高,大颗粒扬尘污染,只展示pm10,pm2.5占pm10的比重变化,工地为主
                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
                    // 计算异常数据的pm2.5占pm10比重的均值
                    val percentageAvg = pollutedData.dataList.map {
                        it.pm25!! / it.pm10!!
                    }.average()
                    val str =
                        "PM2.5量级为${pm25Avg}μg/m³,PM10量级为${pm10Avg}μg/m³,PM2.5占PM10的比重为${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较高,同比计算pm2.5的量级,可能存在同步偏高(汽修、加油站), 同步计算O3是否有高值
                // d) VOC较高,处于加油站(车辆拥堵情况),CO一般较高, 同步计算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偏高,同时PM2.5量级为${pm25Avg}μg/m³,CO量级为${coAvg}mg/m³,O3量级为${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
    }
    /**
@@ -186,10 +211,10 @@
        val st = DateUtil.instance.getTime(pollutedData.startTime)
        val et = DateUtil.instance.getTime(pollutedData.endTime)
        var txt =
            "${pollutedData.selectedFactor?.main?.des}在${st}至${et}之间,出现${pollutedData.exception},最低值为${
                pollutedData
                    .min
            },最高值为${pollutedData.max}"
            "在${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 {