Riku
2025-06-02 e731486b50c4ea6e2d28f302df449b4bd0b2be57
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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.min
 
/**
 * 污染来源
 * 系统内部的污染场景、电子地图搜索得到的实际路段路口等标志信息
 * @date 2025/5/27
 * @author feiyu02
 */
class PollutedSource {
 
    /**
     * 溯源清单显示与临近监测站点的距离(国控、市控、网格化监测点)
     *
     */
 
    // 溯源企业
    var sceneList:List<SceneInfoVo?>? = null
 
    init {
 
    }
 
    fun searchScenes(pollutedArea: PollutedArea, factor: FactorFilter.SelectedFactor) {
        ContextLoader.getCurrentWebApplicationContext()?.getBean(SceneInfoRep::class.java)?.run {
            searchScenes(pollutedArea, this, factor)
        }
    }
 
    /**
     * 查找系统内部溯源范围内的污染企业
     */
    fun searchScenes(pollutedArea: PollutedArea, sceneInfoRep: SceneInfoRep, factor: FactorFilter.SelectedFactor) {
        // Fixme 2025.5.14: 污染源的坐标是高德地图坐标系(火星坐标系),而走航数据是WGS84坐标系
        // 按照区域检索内部污染源信息
        // 1. 首先按照四至范围从数据库初步筛选污染源,需要先将坐标转换为gcj02(火星坐标系),因为污染源场景信息都为此坐标系
//        val polygonTmp = pollutedArea.polygon!!.map {
//            MapUtil.gcj02ToWgs84(it)
//        }
        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)) {
                result.add(it)
            }
        }
 
        findClosestStation(sceneInfoRep, result)
 
 
//        TODO("按照所选监测因子类型,区分污染源类型")
 
    }
 
    /**
     * 计算可能的相关污染场景类型
     */
    private fun calFactorType(factor: FactorFilter.SelectedFactor) {
//        when (factor.main) {
//            FactorType.PM25 -> {}
//
//        }
    }
 
    /**
     * 计算最近的监测站点
     */
    private fun findClosestStation(sceneInfoRep: SceneInfoRep, sceneList: List<SceneInfo>) {
        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) }
 
        this.sceneList = 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
        }
    }
}