package com.flightfeather.uav.model
|
|
import com.flightfeather.uav.common.utils.DateUtil
|
import com.flightfeather.uav.common.utils.ExcelUtil
|
import com.flightfeather.uav.socket.eunm.FactorType
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook
|
import java.io.File
|
import java.io.FileOutputStream
|
import java.util.*
|
import kotlin.math.round
|
|
/**
|
* 污染源影响程度权重分析模型
|
* 基类
|
*/
|
abstract class BaseModel<M : BaseMData, S : BaseSOP> {
|
|
data class ResultCell(
|
var total: Double = 0.0,
|
var count: Int = 0,
|
var average: Double = 0.0
|
) {
|
fun average(): Double {
|
average = if (count == 0) .0 else round(total / count * 100) / 100
|
return average
|
}
|
}
|
|
abstract var dataPrep: BaseDataPrep<M, S>
|
|
// 权重因子,在进行计算分析时使用的监测因子
|
abstract var factorTypes: List<FactorType>
|
|
// 权重值,多种权重进行乘积计算
|
abstract var weights: List<BaseWeight<M, S>>
|
|
// 计算结果
|
private val rMap = mutableMapOf<String, MutableMap<String, MutableMap<String, ResultCell>>>()
|
|
// 结果筛选方式
|
abstract var sections: List<BaseSection<M, S>>
|
|
/**
|
* 污染源影响程度计算
|
* @param mDataList 监测数据集合
|
* @param sopList 污染源集合
|
*/
|
fun execute(mDataList: List<M>, sopList: List<S>, hasNext: Boolean = false) {
|
if (!hasNext) rMap.clear()
|
|
//1. 数据预处理
|
val mList = dataPrep.mDataPrep(mDataList)
|
val sList = dataPrep.sopPrep(sopList)
|
|
mList.forEach m@{ m ->
|
if (!mDataCheck(m)) return@m
|
sList.forEach s@{ s ->
|
if (!sopCheck(s)) return@s
|
weightCompute(m, s)
|
}
|
}
|
}
|
|
/**
|
* 单点权重计算
|
* 计算污染源对单次监测数据产生的影响效果
|
* @param mData 监测数据
|
* @param sop 污染源
|
*/
|
private fun weightCompute(mData: M, sop: S) {
|
val effect = BaseEffect(sop.sourceId, sop.sourceName, sop.index)
|
|
// 将原监测数据按照权重计算出结果值
|
factorTypes.forEach { type ->
|
var result = mData.getFactorData(type) ?: return@forEach
|
weights.forEach {
|
result *= it.getWeight(mData, sop)?: return
|
}
|
effect.value.add(Pair(type, result))
|
}
|
|
// 向结果值添加筛选标签
|
sections.forEach { it.filter(mData, sop, effect) }
|
|
// 保存结果
|
formatConversion2(effect)
|
}
|
|
fun outputToExcel(
|
fName: String? = null,
|
_workbook: HSSFWorkbook? = null,
|
_out: FileOutputStream? = null,
|
sheetName: String = "sheet1",
|
done: Boolean = true
|
): Pair<HSSFWorkbook, FileOutputStream>? {
|
// val rMap = formatConversion()
|
|
val workbook = _workbook ?: HSSFWorkbook()
|
val fileName = fName ?: "污染溯源权重模型${DateUtil.instance.dateToString(Date(), "yyyy-MM-ddHHmmss")}.xls"
|
// val filePath = "E:\\work\\export\\$fileName"
|
// val filePath = "E:\\工作\\开发\\走航监测\\算法相关\\自动输出\\$fileName"
|
val filePath = "E:\\工作\\开发\\走航监测\\算法相关\\自动输出\\网格化\\$fileName"
|
val out = _out ?: FileOutputStream(File(filePath))
|
|
// 表头组(多行表头)
|
val heads = mutableListOf<Array<String>>()
|
// 表头行
|
val h1 = mutableListOf<String>()
|
h1.add("编号")
|
h1.add("污染源")
|
// arrayOf("早上", "上午", "中午", "下午", "傍晚", "夜间")
|
|
val contents = mutableListOf<Array<Any>>()
|
var isFirst = true
|
rMap.forEach { (source, tMap) ->
|
// 新建一行
|
val contentList = mutableListOf<Any>()
|
// 添加污染源名称
|
val l = source.split(";")
|
contentList.add(l[1].toIntOrNull() ?: 0)
|
contentList.add(l[0])
|
tMap.forEach { (factorType, lMap) ->
|
sections.forEach {
|
val types = mutableListOf<String>().apply {
|
addAll(it.sectionType)
|
addAll(it.constType)
|
}
|
var max = 0.0
|
var maxP = types[0]
|
types.forEach type@{se ->
|
val lKey = "$se($factorType)"
|
if (lMap.containsKey(lKey)) {
|
val resultCell = lMap[lKey] ?: return@type
|
val size = resultCell.count
|
// 添加该分类作为表头
|
val h = lKey
|
// val h = "$lKey($size)"
|
if (!h1.contains(h)) {
|
h1.add(h)
|
}
|
|
// 将原始的数据换算得出结果,可以是求出均值、总和等等
|
// FIXME: 2021/6/23 此处先默认为求均值
|
val average = resultCell.average()
|
|
if (average > max) {
|
max = average
|
maxP = se
|
}
|
|
// 当前行添加该分类下的结果值
|
contentList.add(average)
|
}
|
}
|
if (isFirst) {
|
h1.add("最高时段")
|
h1.add("最高时段值")
|
}
|
contentList.add(maxP)
|
contentList.add(max)
|
}
|
}
|
isFirst = false
|
contents.add(contentList.toTypedArray())
|
}
|
|
contents.sortByDescending {
|
val i = it[0]
|
if (i is Int) {
|
i
|
} else {
|
0
|
}
|
}
|
|
heads.add(h1.toTypedArray())
|
ExcelUtil.write(heads, contents, workbook, sheetName)
|
return if (!done) {
|
Pair(workbook, out)
|
} else {
|
workbook.write(out)
|
workbook.close()
|
out.flush()
|
out.close()
|
null
|
}
|
}
|
|
fun outputResult(): MutableMap<String, MutableMap<String, MutableMap<String, ResultCell>>> {
|
rMap.forEach { (_, v) ->
|
v.forEach { (_, v2) ->
|
v2.forEach { (_, v3) ->
|
v3.average()
|
}
|
}
|
}
|
|
return rMap
|
}
|
|
private fun formatConversion2(e: BaseEffect) {
|
val rKey = "${e.sourceName};${e.index}"
|
if (!rMap.containsKey(rKey)) {
|
rMap[rKey] = mutableMapOf()
|
}
|
val lMap = rMap[rKey]!!
|
e.value.forEach { v ->
|
if (!lMap.containsKey(v.first.des)) {
|
lMap[v.first.des] = mutableMapOf()
|
}
|
val tMap = lMap[v.first.des]!!
|
e.tag.forEach { t ->
|
val factorName = v.first.des
|
val lKey = t.levelName + "($factorName)"
|
if (!tMap.containsKey(lKey)) {
|
tMap[lKey] = ResultCell()
|
}
|
tMap[lKey]?.run {
|
total += v.second
|
if (factorName != FactorType.H2S.name || v.second > 0) {
|
count++
|
}
|
}
|
}
|
}
|
}
|
|
/**
|
* 监测数据合法性检查
|
*/
|
abstract fun mDataCheck(m: M): Boolean
|
|
/**
|
* 污染源数据合法性检查
|
*/
|
abstract fun sopCheck(s: S): Boolean
|
}
|