From 707b00a0ca6604c249a110b376ac1e44e408e624 Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期四, 04 九月 2025 18:24:39 +0800
Subject: [PATCH] 2025.9.4 1. 新增走航任务统计功能(待完成)

---
 src/main/kotlin/com/flightfeather/uav/lightshare/service/DataAnalysisService.kt          |   15 ++
 src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/DataAnalysisServiceImpl.kt |   76 ++++++++++++
 src/main/kotlin/com/flightfeather/uav/lightshare/eunm/PollutionDegree.kt                 |   29 ++++
 src/main/kotlin/com/flightfeather/uav/domain/entity/ExpandFun.kt                         |   20 +++
 src/main/kotlin/com/flightfeather/uav/lightshare/web/DataAnalysisController.kt           |   24 ++++
 src/main/kotlin/com/flightfeather/uav/domain/repository/SceneInfoRep.kt                  |   18 +++
 src/main/kotlin/com/flightfeather/uav/biz/report/MissionGridFusion.kt                    |  113 ++++++++++++++++++
 src/main/kotlin/com/flightfeather/uav/lightshare/eunm/SceneType.kt                       |   44 +++++++
 src/main/kotlin/com/flightfeather/uav/biz/report/MissionSummary.kt                       |    8 
 9 files changed, 338 insertions(+), 9 deletions(-)

diff --git a/src/main/kotlin/com/flightfeather/uav/biz/report/MissionGridFusion.kt b/src/main/kotlin/com/flightfeather/uav/biz/report/MissionGridFusion.kt
new file mode 100644
index 0000000..4bebc3f
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/biz/report/MissionGridFusion.kt
@@ -0,0 +1,113 @@
+package com.flightfeather.uav.biz.report
+
+import com.flightfeather.uav.common.net.AMapService
+import com.flightfeather.uav.common.utils.MapUtil
+import com.flightfeather.uav.domain.entity.GridCell
+import com.flightfeather.uav.domain.entity.SceneInfo
+import com.flightfeather.uav.domain.entity.getByFactorType
+import com.flightfeather.uav.domain.repository.SceneInfoRep
+import com.flightfeather.uav.lightshare.bean.GridDataDetailMixVo
+import com.flightfeather.uav.lightshare.eunm.PollutionDegree
+import com.flightfeather.uav.socket.eunm.FactorType
+
+/**
+ * 璧拌埅缃戞牸鍙犲姞
+ * @date 2025/9/4
+ * @author feiyu02
+ */
+class MissionGridFusion(private val sceneInfoRep: SceneInfoRep) {
+
+    /**
+     * 鎸堿QI绛夌骇鍙犲姞缃戞牸
+     */
+    class GridFusionByAQI {
+        var pollutionDegree: String? = null
+        var gridLen:Int? = null
+        var missionList: MutableList<MissionInventory.MissionDetail> = mutableListOf()
+        var gridFusionList: MutableList<FusionGrid> = mutableListOf()
+        var highRiskGridList: MutableList<HighRiskGridByFactor> = mutableListOf()
+    }
+
+    /**
+     * 鍙犲姞缃戞牸
+     */
+    class FusionGrid(
+        val cell: GridCell,
+        val data: GridDataDetailMixVo,
+    )
+
+    /**
+     * 鐩戞祴鍥犲瓙鐨勯珮椋庨櫓鍙犲姞缃戞牸
+     */
+    class HighRiskGridByFactor{
+        // 鍥犲瓙绫诲瀷
+        var factorType: FactorType? = null
+        // 楂橀闄╃綉鏍间俊鎭�
+        var highRiskGrid: FusionGrid? = null
+        // 鍥犲瓙鍊�
+        var factorValue: Float? = null
+        // 娑夊強鐨勮闀�
+        var town: String? = null
+        // 鍥涜嚦鑼冨洿锛岄『搴忎负鏈�灏忕粡搴︼紝鏈�澶х粡搴�, 鏈�灏忕含搴︼紝鏈�澶х含搴�
+        var bounds: List<Double>? = null
+        // 楂橀闄╁満鏅垪琛�
+        var highRiskScenes:List<SceneInfo?>? = null
+    }
+
+    /**
+     * 鐢熸垚缃戞牸铻嶅悎鏁版嵁锛屾寜AQI绛夌骇鍒嗙粍骞惰绠楀悇鐩戞祴鍥犲瓙鐨勯珮椋庨櫓鍖哄煙
+     *
+     * @param factorTypes 闇�瑕佸垎鏋愮殑鐩戞祴鍥犲瓙绫诲瀷鍒楄〃
+     * @param gridLen 缃戞牸杈归暱(绫�)
+     * @param gridCells 缃戞牸鍗曞厓鍒楄〃锛屽寘鍚綉鏍肩殑鍦扮悊淇℃伅鍜岀储寮�
+     * @param dataList 涓夊厓缁勫垪琛紝姣忎釜鍏冪礌鍖呭惈锛�
+     *                 - 姹℃煋绛夌骇(PollutionDegree)
+     *                 - 璧拌埅浠诲姟璇︽儏鍒楄〃(MissionDetail)
+     *                 - 缃戞牸鏁版嵁璇︽儏鍒楄〃(GridDataDetailMixVo)
+     * @return 鎸堿QI绛夌骇鍒嗙粍鐨勭綉鏍艰瀺鍚堢粨鏋滃垪琛紝姣忎釜鍏冪礌鍖呭惈璇ョ瓑绾т笅鐨勬墍鏈夌綉鏍兼暟鎹拰楂橀闄╁垎鏋�
+     */
+    fun generateGridFusion(
+        factorTypes: List<FactorType>,
+        gridLen: Int,
+        gridCells: List<GridCell>,
+        dataList: List<Triple<PollutionDegree, List<MissionInventory.MissionDetail>, List<GridDataDetailMixVo>>>,
+    ): List<GridFusionByAQI> {
+        return dataList.map {
+            GridFusionByAQI().apply {
+                pollutionDegree = it.first.des
+                this.gridLen = gridLen
+                missionList.addAll(it.second)
+                gridFusionList.addAll(it.third.map { gdm ->
+                    val grid = gridCells.find { it.cellIndex == gdm.cellId }
+                        ?: throw IllegalArgumentException("缃戞牸缁�${gdm.groupId}涓紝鍗曞厓ID: ${gdm.cellId} 涓嶅瓨鍦�")
+                    FusionGrid(grid, gdm)
+                })
+                highRiskGridList.addAll(factorTypes.map { f->
+                    HighRiskGridByFactor().apply {
+                        factorType = f
+                        highRiskGrid = gridFusionList.sortedBy { gf->gf.data.rank }.firstOrNull()
+                        if (highRiskGrid != null) {
+                            factorValue = highRiskGrid!!.data.getByFactorType(f)
+                            if (highRiskGrid!!.cell.longitude != null && highRiskGrid!!.cell.latitude != null) {
+                                Thread.sleep(50)
+                                val address = AMapService.reGeo(MapUtil.wgs84ToGcj02(
+                                    highRiskGrid!!.cell.longitude.toDouble()
+                                            to highRiskGrid!!.cell.latitude.toDouble()
+                                ))
+                                town = address.township + address.street
+                            }
+                            val polygon = listOf(
+                                highRiskGrid!!.cell.point1Lon.toDouble() to highRiskGrid!!.cell.point1Lat.toDouble(),
+                                highRiskGrid!!.cell.point2Lon.toDouble() to highRiskGrid!!.cell.point2Lat.toDouble(),
+                                highRiskGrid!!.cell.point3Lon.toDouble() to highRiskGrid!!.cell.point3Lat.toDouble(),
+                                highRiskGrid!!.cell.point4Lon.toDouble() to highRiskGrid!!.cell.point4Lat.toDouble(),
+                            )
+                            bounds = MapUtil.calFourBoundaries(polygon)
+                            highRiskScenes = sceneInfoRep.findByPolygon(polygon)
+                        }
+                    }
+                })
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/biz/report/MissionSummary.kt b/src/main/kotlin/com/flightfeather/uav/biz/report/MissionSummary.kt
index 3cc0cbb..f82bf96 100644
--- a/src/main/kotlin/com/flightfeather/uav/biz/report/MissionSummary.kt
+++ b/src/main/kotlin/com/flightfeather/uav/biz/report/MissionSummary.kt
@@ -94,7 +94,7 @@
             Triple(degree, count, count.toDouble() / totalCount)
         }
 
-        // 6. 闂鐩稿叧缁熻锛堢ず渚嬶細姝ゅ鍋囪闇�鍏宠仈鍏朵粬琛紝鏆傝繑鍥�0锛屽疄闄呴渶鏍规嵁涓氬姟琛ュ厖锛�
+        // 6. 闂鐩稿叧缁熻
         val clueRes = calClue(clues)
         val probCount = clueRes.first // 闇�鍏宠仈闂琛ㄧ粺璁�
         val highRiskSceneCount = clueRes.second // 闇�鍏宠仈鍦烘櫙琛ㄧ粺璁�
@@ -116,9 +116,9 @@
     }
 
     private fun calClue(clues: List<PollutedClue?>): Triple<Int, Int, List<Triple<String, Int, Double>>> {
-        var probCount = 0 // 闇�鍏宠仈闂琛ㄧ粺璁�
-        var highRiskSceneCount = 0 // 闇�鍏宠仈鍦烘櫙琛ㄧ粺璁�
-        val probByFactorMap = mutableMapOf<FactorType, Int>() // 闇�鍏宠仈鍥犲瓙琛ㄧ粺璁�
+        var probCount = 0
+        var highRiskSceneCount = 0
+        val probByFactorMap = mutableMapOf<FactorType, Int>()
         clues.forEach { c ->
             if (c?.msgType == MsgType.PolClue.value) {
                 c.pollutedSource?.sceneList?.size?.let { s -> highRiskSceneCount += s }
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/ExpandFun.kt b/src/main/kotlin/com/flightfeather/uav/domain/entity/ExpandFun.kt
index e0f3799..0fa5483 100644
--- a/src/main/kotlin/com/flightfeather/uav/domain/entity/ExpandFun.kt
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/ExpandFun.kt
@@ -143,6 +143,26 @@
     }
 }
 
+fun GridDataDetail.getByFactorType(type: FactorType?): Float? {
+    return when (type) {
+        NO2 -> no2
+        CO -> co
+        H2S -> h2s
+        SO2 -> so2
+        O3 -> o3
+        PM25 -> pm25
+        PM10 -> pm10
+        TEMPERATURE -> temperature
+        HUMIDITY -> humidity
+        VOC -> voc
+        NOI -> noi
+        WIND_SPEED -> windSpeed
+        WIND_DIRECTION -> windDirection
+        NO -> no
+        else -> null
+    }
+}
+
 fun List<GridDataDetail>.avg(): GridDataDetail {
     //椋庡悜閲囩敤鍗曚綅鐭㈤噺娉曟眰鍙栧潎鍊�
     var u = .0//涓滆タ鏂逛綅鍒嗛噺鎬诲拰
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/repository/SceneInfoRep.kt b/src/main/kotlin/com/flightfeather/uav/domain/repository/SceneInfoRep.kt
index e0e9729..5ebde44 100644
--- a/src/main/kotlin/com/flightfeather/uav/domain/repository/SceneInfoRep.kt
+++ b/src/main/kotlin/com/flightfeather/uav/domain/repository/SceneInfoRep.kt
@@ -1,5 +1,6 @@
 package com.flightfeather.uav.domain.repository
 
+import com.flightfeather.uav.common.utils.MapUtil
 import com.flightfeather.uav.domain.entity.SceneInfo
 import com.flightfeather.uav.domain.mapper.SceneInfoMapper
 import com.flightfeather.uav.lightshare.bean.AreaVo
@@ -42,6 +43,23 @@
         })
     }
 
+    /**
+     * 鏍规嵁澶氳竟褰㈢瓫閫夊満鏅�
+     * @param polygon 澶氳竟褰㈠潗鏍囧垪琛紝椤哄簭涓洪『鏃堕拡鎴栭�嗘椂閽�(瑕佹眰浣跨敤鐏槦鍧愭爣绯�)
+     * @return 澶氳竟褰㈠唴鐨勫満鏅垪琛�
+     */
+    fun findByPolygon(polygon: List<Pair<Double, Double>>): List<SceneInfo?> {
+        // 璁$畻澶氳竟褰㈠洓鑷宠寖鍥�
+        val bounds = MapUtil.calFourBoundaries(polygon)
+        val sceneList = findByCoordinateRange(bounds)
+        // 绛涢�夋槸鍚﹀湪鍙嶅悜婧簮鍖哄煙澶氳竟褰㈠唴閮�
+        return sceneList.filter { scene ->
+            scene ?: false
+            val point = scene!!.longitude.toDouble() to scene.latitude.toDouble()
+            MapUtil.isPointInPolygon(point, polygon)
+        }
+    }
+
     fun findBySceneTypes(sceneTypes: List<Int>): List<SceneInfo?> {
         if (sceneTypes.isEmpty()){
             return emptyList()
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/PollutionDegree.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/PollutionDegree.kt
new file mode 100644
index 0000000..37a7130
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/PollutionDegree.kt
@@ -0,0 +1,29 @@
+package com.flightfeather.uav.lightshare.eunm
+
+/**
+ * 绌烘皵璐ㄩ噺绛夌骇
+ * @date 2025/9/4
+ * @author feiyu02
+ */
+enum class PollutionDegree(val des: String, val value: Int, val minAqi: Int) {
+    AQI_1("浼�", 1, 0),
+    AQI_2("鑹�", 2, 51),
+    AQI_3("杞诲害姹℃煋", 3, 101),
+    AQI_4("涓害姹℃煋", 4, 151),
+    AQI_5("閲嶅害姹℃煋", 5, 201),
+    AQI_6("涓ラ噸姹℃煋", 6, 301);
+
+    companion object {
+        fun getByValue(value: Int): PollutionDegree {
+            return values().firstOrNull { it.value == value } ?: AQI_1
+        }
+
+        fun getByAqi(aqi: Int): PollutionDegree {
+            return values().reversed().firstOrNull { it.minAqi <= aqi } ?: AQI_1
+        }
+
+        fun getByDes(des: String): PollutionDegree {
+            return values().firstOrNull { it.des == des } ?: AQI_1
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/SceneType.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/SceneType.kt
index 15d6979..dbf1839 100644
--- a/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/SceneType.kt
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/eunm/SceneType.kt
@@ -1,5 +1,7 @@
 package com.flightfeather.uav.lightshare.eunm
 
+import com.flightfeather.uav.socket.eunm.FactorType
+
 /**
  * 鍦烘櫙绫诲瀷
  * @date 2025/6/2
@@ -26,5 +28,45 @@
     TYPE18(18, "鍟嗕笟浣�"),
     TYPE19(19, "鍥芥帶鐐�"),
     TYPE20(20, "甯傛帶鐐�"),
-    TYPE21(21, "灏忓井绔�"),
+    TYPE21(21, "灏忓井绔�");
+
+    companion object {
+        fun getByFactorType(factorType: FactorType): List<SceneType> {
+            return when (factorType) {
+                // 姘哀鍖栧悎鐗╋紝涓�鑸敱浜庢満鍔ㄨ溅灏炬皵锛屽悓姝ヨ绠桟O
+                FactorType.NO,
+                FactorType.NO2 -> {
+                    listOf(TYPE6, TYPE10, TYPE17)
+                }
+
+                FactorType.CO -> listOf(TYPE6, TYPE10, TYPE17)
+
+                FactorType.H2S -> emptyList()
+
+                FactorType.SO2 -> emptyList()
+
+                FactorType.O3 -> emptyList()
+                // a) pm2.5銆乸m10鐗瑰埆楂橈紝涓よ�呭湪鍚勬儏鍐典笅鍚屾灞曠ず锛宲m2.5鍗爌m10鐨勬瘮閲嶅彉鍖栵紝姣旈噸瓒婇珮锛岃秺鏈夊彲鑳芥槸椁愰ギ
+                // b) pm10鐗瑰埆楂樸�乸m2.5杈冮珮锛屽ぇ棰楃矑鎵皹姹℃煋锛屽彧灞曠ずpm10锛宲m2.5鍗爌m10鐨勬瘮閲嶅彉鍖栵紝宸ュ湴涓轰富
+                FactorType.PM25,
+                FactorType.PM10,
+                    -> {
+                    listOf(
+                        TYPE1,
+                        TYPE2,
+                        TYPE3,
+                        TYPE14,
+                        TYPE5
+                    )
+                }
+                // c) VOC杈冮珮锛屽悓姣旇绠梡m2.5鐨勯噺绾э紝鍙兘瀛樺湪鍚屾鍋忛珮锛堟苯淇�佸姞娌圭珯锛�, 鍚屾璁$畻O3鏄惁鏈夐珮鍊�
+                // d) VOC杈冮珮锛屽浜庡姞娌圭珯锛堣溅杈嗘嫢鍫垫儏鍐碉級锛孋O涓�鑸緝楂�, 鍚屾璁$畻O3鏄惁鏈夐珮鍊�
+                FactorType.VOC -> {
+                    listOf(TYPE6, TYPE17, TYPE12)
+                }
+
+                else -> emptyList()
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/DataAnalysisService.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/DataAnalysisService.kt
index bb440bf..5bd59a6 100644
--- a/src/main/kotlin/com/flightfeather/uav/lightshare/service/DataAnalysisService.kt
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/DataAnalysisService.kt
@@ -1,15 +1,20 @@
 package com.flightfeather.uav.lightshare.service
 
 import com.flightfeather.uav.biz.dataanalysis.model.ExceptionResult
+import com.flightfeather.uav.biz.report.MissionGridFusion
 import com.flightfeather.uav.biz.report.MissionInventory
 import com.flightfeather.uav.biz.report.MissionInventory.MissionDetail
 import com.flightfeather.uav.biz.report.MissionRiskArea
 import com.flightfeather.uav.biz.report.MissionSummary
 import com.flightfeather.uav.biz.sourcetrace.model.PollutedClue
 import com.flightfeather.uav.domain.entity.BaseRealTimeData
+import com.flightfeather.uav.domain.entity.GridCell
 import com.flightfeather.uav.domain.entity.Mission
 import com.flightfeather.uav.domain.entity.SceneInfo
 import com.flightfeather.uav.lightshare.bean.AreaVo
+import com.flightfeather.uav.lightshare.bean.GridDataDetailMixVo
+import com.flightfeather.uav.lightshare.eunm.PollutionDegree
+import com.flightfeather.uav.socket.eunm.FactorType
 import java.util.*
 
 /**
@@ -87,4 +92,14 @@
     fun generateClueByRiskArea(startTime: Date, endTime: Date, areaVo: AreaVo): List<MissionRiskArea.ClueByArea>
 
     fun generateClueByRiskArea(keyScenes: List<SceneInfo?>, pollutedClues: List<PollutedClue?>): List<MissionRiskArea.ClueByArea>
+
+    fun generateGridFusion(factorTypes: List<FactorType>, startTime: Date, endTime: Date, areaVo: AreaVo):
+            List<MissionGridFusion.GridFusionByAQI>
+
+    fun generateGridFusion(
+        factorTypes: List<FactorType>,
+        gridLen: Int,
+        gridCells: List<GridCell>,
+        dataList: List<Triple<PollutionDegree, List<MissionInventory.MissionDetail>, List<GridDataDetailMixVo>>>,
+    ): List<MissionGridFusion.GridFusionByAQI>
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/DataAnalysisServiceImpl.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/DataAnalysisServiceImpl.kt
index 9826661..0dcbb4a 100644
--- a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/DataAnalysisServiceImpl.kt
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/DataAnalysisServiceImpl.kt
@@ -3,6 +3,7 @@
 import com.flightfeather.uav.biz.FactorFilter
 import com.flightfeather.uav.biz.dataanalysis.ExceptionAnalysisController
 import com.flightfeather.uav.biz.dataanalysis.model.ExceptionResult
+import com.flightfeather.uav.biz.report.MissionGridFusion
 import com.flightfeather.uav.biz.report.MissionInventory
 import com.flightfeather.uav.biz.report.MissionRiskArea
 import com.flightfeather.uav.biz.report.MissionSummary
@@ -10,14 +11,15 @@
 import com.flightfeather.uav.common.exception.BizException
 import com.flightfeather.uav.common.location.LocationRoadNearby
 import com.flightfeather.uav.common.utils.GsonUtils
-import com.flightfeather.uav.domain.entity.BaseRealTimeData
-import com.flightfeather.uav.domain.entity.Mission
-import com.flightfeather.uav.domain.entity.SceneInfo
+import com.flightfeather.uav.domain.entity.*
 import com.flightfeather.uav.domain.mapper.MissionMapper
 import com.flightfeather.uav.domain.repository.*
 import com.flightfeather.uav.lightshare.bean.AreaVo
+import com.flightfeather.uav.lightshare.bean.GridDataDetailMixVo
+import com.flightfeather.uav.lightshare.eunm.PollutionDegree
 import com.flightfeather.uav.lightshare.eunm.SceneType
 import com.flightfeather.uav.lightshare.service.DataAnalysisService
+import com.flightfeather.uav.lightshare.service.SatelliteDataCalculateService
 import com.flightfeather.uav.socket.eunm.FactorType
 import com.flightfeather.uav.socket.sender.MsgType
 import org.springframework.stereotype.Service
@@ -39,7 +41,9 @@
     private val locationRoadNearby: LocationRoadNearby,
     private val segmentInfoRep: SegmentInfoRep,
     private val sourceTraceRep: SourceTraceRep,
-    private val sceneInfoRep: SceneInfoRep
+    private val sceneInfoRep: SceneInfoRep,
+    private val satelliteGridRep: SatelliteGridRep,
+    private val satelliteDataCalculateService: SatelliteDataCalculateService
 ) : DataAnalysisService {
 
     /**
@@ -204,4 +208,68 @@
     ): List<MissionRiskArea.ClueByArea> {
         return MissionRiskArea().generateClueByRiskArea(keyScenes, pollutedClues)
     }
+
+    override fun generateGridFusion(
+        factorTypes: List<FactorType>,
+        startTime: Date,
+        endTime: Date,
+        areaVo: AreaVo,
+    ): List<MissionGridFusion.GridFusionByAQI> {
+        val gridLen = 100
+        // 鏌ヨ100绫崇綉鏍肩殑鍏蜂綋缃戞牸鏁版嵁
+        val gridGroup = satelliteGridRep.fetchGridGroup(GridGroup().apply {
+            type = "sub"
+            length = gridLen.toDouble()
+            provinceCode = areaVo.provinceCode
+            cityCode = areaVo.cityCode
+            districtCode = areaVo.districtCode
+        }).firstOrNull() ?: throw BizException("鏈煡璇㈠埌100绫崇綉鏍�")
+        val gridCells = satelliteGridRep.fetchGridCell(gridGroup.id).filterNotNull()
+        // 鏌ヨ鑼冨洿鍐呯殑鎵�鏈夎蛋鑸换鍔�
+        val missions = missionRep.findByAreaAndTime(areaVo, startTime, endTime)
+        // 鏍规嵁绌烘皵璐ㄩ噺绛夌骇鍒嗙被
+        val missionGroups = missions.groupBy { PollutionDegree.getByDes(it?.pollutionDegree ?: "") }
+        // 鏌ヨ姣忎釜绛夌骇涓嬬殑璧拌埅浠诲姟瀵瑰簲鐨勭綉鏍兼暟鎹紙濡傛灉娌℃湁鏁版嵁鍒欏墧闄よ浠诲姟锛�
+        val gridDataDetailList = missionGroups.mapNotNull { (degree, missionList) ->
+            // 绛涢�夊嚭鏈夌綉鏍艰瀺鍚堟暟鎹殑璧拌埅浠诲姟(鍚屾椂鑾峰彇瀵瑰簲鐨勮瀺鍚堟暟鎹甶d鍒楄〃)
+            val gridDataIds = mutableListOf<Int>()
+            val validMissions = missionList.filter {mission ->
+                val gridData = satelliteGridRep.fetchGridData(GridData().apply { missionCode = mission?.missionCode }).firstOrNull()
+                val res = gridData != null
+                if (res) gridDataIds.add(gridData?.id ?: 0)
+                res
+            }
+            // 鍚堝苟姣忎釜绛夌骇涓嬬殑缃戞牸鏁版嵁
+            val gridDataDetailMixVos = satelliteDataCalculateService.mixUnderwayGridData(gridGroup.id, gridDataIds)
+            // 缁熻姣忎釜璧拌埅浠诲姟鐨勮蛋鑸鎯呬俊鎭�
+            val missionCluesData = validMissions.filterNotNull().map {
+                Triple(
+                    it,
+                    sourceTraceRep.fetchList(it.deviceCode, it.startTime, it.endTime, MsgType.PolClue) as List<PollutedClue?>,
+                    realTimeDataRep.fetchData(it)
+                )
+            }
+            val keyScenes = sceneInfoRep.findBySceneTypes(
+                listOf(
+                    SceneType.TYPE19.value,
+                    SceneType.TYPE20.value,
+                    SceneType.TYPE21.value
+                )
+            )
+            val missionDetails = generateMissionDetail(keyScenes, missionCluesData)
+
+            return@mapNotNull Triple(degree, missionDetails, gridDataDetailMixVos)
+        }.filter { it.second.isNotEmpty() }
+
+        return generateGridFusion(factorTypes, gridLen, gridCells, gridDataDetailList)
+    }
+
+    override fun generateGridFusion(
+        factorTypes: List<FactorType>,
+        gridLen: Int,
+        gridCells: List<GridCell>,
+        dataList: List<Triple<PollutionDegree, List<MissionInventory.MissionDetail>, List<GridDataDetailMixVo>>>,
+    ): List<MissionGridFusion.GridFusionByAQI> {
+        return MissionGridFusion(sceneInfoRep).generateGridFusion(factorTypes, gridLen, gridCells, dataList)
+    }
 }
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/web/DataAnalysisController.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/web/DataAnalysisController.kt
index ea3ca27..d6057bb 100644
--- a/src/main/kotlin/com/flightfeather/uav/lightshare/web/DataAnalysisController.kt
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/web/DataAnalysisController.kt
@@ -3,6 +3,7 @@
 import com.fasterxml.jackson.annotation.JsonFormat
 import com.flightfeather.uav.lightshare.bean.AreaVo
 import com.flightfeather.uav.lightshare.service.DataAnalysisService
+import com.flightfeather.uav.socket.eunm.FactorType
 import io.swagger.annotations.Api
 import io.swagger.annotations.ApiOperation
 import io.swagger.annotations.ApiParam
@@ -115,4 +116,27 @@
             areaVo
         )
     }
+
+    @ApiOperation(value = "鍙犲姞铻嶅悎鍒嗘瀽")
+    @PostMapping("/report/gridFusion")
+    fun generateGridFusion(
+        @ApiParam("寮�濮嬫椂闂�") @RequestParam
+        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        startTime: LocalDateTime,
+        @ApiParam("缁撴潫鏃堕棿") @RequestParam
+        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+        endTime: LocalDateTime,
+        @ApiParam("闇�瑕佺粺璁$殑鐩戞祴鍥犲瓙", example = "NO2, CO") @RequestParam
+        factorTypes: String,
+        @ApiParam("鍖哄煙") @RequestBody areaVo: AreaVo,
+    ) = resPack {
+        dataAnalysisService.generateGridFusion(
+            factorTypes.split(",").map { FactorType.valueOf(it) },
+            Date.from(startTime.atZone(ZoneId.systemDefault()).toInstant()),
+            Date.from(endTime.atZone(ZoneId.systemDefault()).toInstant()),
+            areaVo
+        )
+    }
 }
\ No newline at end of file

--
Gitblit v1.9.3