feiyu02
2024-01-09 c1becf4cbd2e99601ce011c14b8742427249cfb4
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package cn.flightfeather.supervision.business.autooutput.dataanalysis
 
import cn.flightfeather.supervision.business.autooutput.AopOutput
import cn.flightfeather.supervision.business.autooutput.datasource.AopDataSource
import cn.flightfeather.supervision.business.autooutput.datasource.AopDbMapper
import cn.flightfeather.supervision.business.autooutput.datasource.AopSceneTypeCheck
import cn.flightfeather.supervision.domain.ds3.entity.JSDustData
import cn.flightfeather.supervision.domain.ds3.entity.JSDustSiteMap
import cn.flightfeather.supervision.domain.ds3.enum.JSSceneType
import cn.flightfeather.supervision.domain.ds3.mapper.JSDustDataMapper
import cn.flightfeather.supervision.domain.ds3.mapper.JSDustSiteMapMapper
import tk.mybatis.mapper.entity.Example
import java.time.Duration
import java.time.LocalDateTime
import java.time.ZoneId
import kotlin.math.round
 
/**
 * 金山扬尘监测数据统计
 */
abstract class JSDustDataAnalysis(
    aopDbMapper: AopDbMapper,
    aopSceneTypeCheck: AopSceneTypeCheck,
    aopOutput: AopOutput,
    private val jsDustDataMapper: JSDustDataMapper,
    private val jsDustSiteMapMapper: JSDustSiteMapMapper,
) : AopDataAnalysis<JSDustData>(aopDbMapper, aopSceneTypeCheck, aopOutput){
 
    abstract var sceneType: JSSceneType
 
    override fun districtAvg(source: AopDataSource?): Double? {
        var total = .0
        var count = 0
 
        var page = 0
        val perPage = 20000
        var hasNextPage = false
        do {
            val res = jsDustDataMapper
                .getDataBySceneType(source?.config?.startTime, source?.config?.endTime, sceneType.value,
                    page * perPage, perPage)
            res.forEach {
                it?.dustValue?.let { v ->
                    total += v
                    count++
                }
            }
            page++
            hasNextPage = res.isNotEmpty()
            println("均值计算:当前页码 $page")
        } while (hasNextPage)
 
        return if (count == 0) {
            .0
        } else {
            round((total / count) * 1000) / 1000
        }
    }
 
    override fun fetchDataResources(evaluationScene: AopDataSource.EvaluationScene): List<List<JSDustData?>> {
        val dustSiteMaps = jsDustSiteMapMapper.selectByExample(Example(JSDustSiteMap::class.java).apply {
            createCriteria().andEqualTo("svUserId", evaluationScene.userInfo.value?.guid)
                .andIsNotNull("jsDeviceCode")
        })
        if (dustSiteMaps.isEmpty()) return emptyList()
 
        val mnCodeList =  dustSiteMaps.map { it?.jsDeviceCode }
        val map = mutableMapOf<String?, MutableList<JSDustData?>>()
        jsDustDataMapper.selectByExample(Example(JSDustData::class.java).apply {
            createCriteria().andBetween("lst", evaluationScene.config?.startTime, evaluationScene.config?.endTime)
                .andIn("mnCode", mnCodeList)
        }).forEach {
            if (!map.containsKey(it?.mnCode)) {
                map[it?.mnCode] = mutableListOf()
            }
            map[it?.mnCode]?.add(it)
        }
        val res = mutableListOf<List<JSDustData?>>()
        map.forEach { (_, u) ->
            res.add(u)
        }
        return res
    }
 
    override fun exceedTimes(data: JSDustData, t: TempResult) {
        data.dustValue?.let {
            if (it >= 1) {
                t.count++
            }
        }
    }
 
    override fun avg(data: JSDustData, t: TempResult) {
        data.dustValue?.let {
            t.total += it
            t.count++
        }
    }
 
    override fun max(data: JSDustData, t: TempResult) {
        data.dustValue?.let {
            if (it > t.total) {
                t.total = it
            }
        }
    }
 
    override fun min(data: JSDustData, t: TempResult) {
        data.dustValue?.let {
            if (t.count == 0 || it < t.total) {
                t.total = it
            }
            // 通过t.count 来判定是否是初始化状态
            if (t.count == 0) t.count = 1
        }
    }
 
    override fun overAvgRate(avg: Double, dAvg: Double?): Double? {
        return if (dAvg != null) {
            round(((avg - dAvg) / dAvg) * 1000) / 1000
        } else {
            null
        }
    }
 
    override fun effectiveRate(
        dataList: List<List<JSDustData?>>,
        evaluationScene: AopDataSource.EvaluationScene,
    ): Double {
        if (dataList.isEmpty()) return .0
 
        val st = LocalDateTime.ofInstant(evaluationScene.config?.startTime?.toInstant(), ZoneId.systemDefault())
        val et = LocalDateTime.ofInstant(evaluationScene.config?.endTime?.toInstant(), ZoneId.systemDefault())
        val days = Duration.between(st, et).toDays() + 1
 
        return if (days == 0L) {
            .0
        } else {
            round((count(dataList) / (dataList.size * days * 24 * 4).toDouble()) * 1000) / 1000
        }
    }
}