From 53857f42f777e2b9753b8f00cce1a60ce3dcb8fd Mon Sep 17 00:00:00 2001
From: Riku <risaku@163.com>
Date: 星期三, 15 十月 2025 22:42:29 +0800
Subject: [PATCH] 2025.10.15 修改高德地图地理逆编码结果,让地理位置信息更加详细
---
src/main/kotlin/com/flightfeather/uav/model/epw/EPWDataPrep.kt | 206 +++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 181 insertions(+), 25 deletions(-)
diff --git a/src/main/kotlin/com/flightfeather/uav/model/epw/EPWDataPrep.kt b/src/main/kotlin/com/flightfeather/uav/model/epw/EPWDataPrep.kt
index 3f23d11..45f9b80 100644
--- a/src/main/kotlin/com/flightfeather/uav/model/epw/EPWDataPrep.kt
+++ b/src/main/kotlin/com/flightfeather/uav/model/epw/EPWDataPrep.kt
@@ -1,45 +1,77 @@
package com.flightfeather.uav.model.epw
-import com.flightfeather.uav.lightshare.bean.CompanySOP
+import com.flightfeather.uav.common.utils.DateUtil
import com.flightfeather.uav.lightshare.bean.DataVo
import com.flightfeather.uav.model.BaseDataPrep
+import com.flightfeather.uav.model.BaseSOP
+import com.flightfeather.uav.socket.bean.AirData
+import com.flightfeather.uav.socket.bean.AirDataPackage
import com.flightfeather.uav.socket.eunm.FactorType
+import com.flightfeather.uav.socket.eunm.UWDeviceType
import kotlin.math.max
import kotlin.math.min
+import kotlin.math.round
import kotlin.math.sqrt
-class EPWDataPrep : BaseDataPrep<DataVo, CompanySOP>() {
+/**
+ * 鏁版嵁骞虫粦棰勫鐞�
+ * 瀵逛簬鏈�鏂扮殑涓�缁勬暟鎹紝鏍规嵁鍏朵箣鍓嶈繛缁殑鑻ュ共鏁版嵁锛岃繘琛屾暟鎹钩婊戝鐞�
+ * @Date 2024.5.16
+ */
+class EPWDataPrep(val deviceType: UWDeviceType? = UWDeviceType.GRID) : BaseDataPrep<DataVo, BaseSOP>() {
// 鍚戝墠妫�绱㈢殑鏁版嵁璁板綍鏁�
private val ncal = 15
+
// 鏍囧噯宸�嶆暟鍙傛暟
private val nstd = 3
+
// 鍧囧�煎�嶆暟鍙傛暟
private val xratio = 3
- // 闇�瑕佸鐞嗙殑鍥犲瓙绫诲瀷
- private val calTypes =
-// emptyList<String>()
- WeightType.prep
+
+ // 闇�瑕佸钩婊戝鐞嗙殑鍥犲瓙绫诲瀷
+ private var calTypes = when (deviceType) {
+ UWDeviceType.VEHICLE,
+ UWDeviceType.UAV,
+ UWDeviceType.BOAT,
+ -> WeightType.prepUnderWay
+ UWDeviceType.GRID -> WeightType.prepFixed
+ else -> WeightType.prepFixed
+ }
+
+ // 鍙渶瑕佹鏌ヨ寖鍥村拰鍙樺寲骞呭害鐨勫洜瀛愮被鍨�
+ private var rangeTypes = listOf(
+ FactorType.PM25.des,
+ FactorType.PM10.des,
+ FactorType.VOC.des
+ )
+
+ // 鏃犻渶淇鐨勫洜瀛愮被鍨�
+ private var noCalTypes = listOf(
+ FactorType.TEMPERATURE.des,
+ FactorType.HUMIDITY.des,
+ FactorType.LNG.des,
+ FactorType.LAT.des,
+ FactorType.VELOCITY.des,
+ FactorType.TIME.des,
+ FactorType.WIND_DIRECTION.des,
+ FactorType.HEIGHT.des
+ )
private val lastData = mutableListOf<DataVo>()
override fun mDataPrep(mDataList: List<DataVo>): List<DataVo> {
mDataList.forEach {
- it.values?.forEach v@{a ->
+ it.values?.forEach v@{ a ->
if (!calTypes.contains(a.factorName)) return@v
val range = FactorType.getRange(a.factorName) ?: return@v
// 鍒ゆ柇鏁版嵁鏄惁鍦ㄥ悎鐞嗚寖鍥村唴
- if (a.factorData ?: 0.0 < range.first || a.factorData ?: 0.0 > range.second) {
+ if (a.factorData != null && (a.factorData!! < range.first || a.factorData!! > range.second)) {
a.factorData = null
}
}
}
-
-// val newDataList = mutableListOf<DataVo>()
-// mDataList.forEach {
-// newDataList.add(it.copy())
-// }
var i = ncal
if (lastData.isNotEmpty()) {
@@ -50,12 +82,12 @@
val it = mDataList[i].values?.get(y) ?: continue
if (!calTypes.contains(it.factorName)) continue
- val vMax = FactorType.getVMax(it.factorName) ?: continue
+ val vMax = FactorType.getVMin(it.factorName) ?: continue
it.factorData ?: continue
if (it.factorData!! > vMax) {
val lastDataIndex = i
- val thisIndex = if (i-ncal<0) 0 else i - ncal
+ val thisIndex = if (i - ncal < 0) 0 else i - ncal
val list = mutableListOf<DataVo>()
if (lastDataIndex < lastData.size) {
list.addAll(lastData.subList(lastDataIndex, lastData.lastIndex + 1))
@@ -63,7 +95,7 @@
list.addAll(mDataList.subList(thisIndex, i))
// 鍘婚櫎鏃犳晥鍊肩殑骞冲潎
- val avg = average(list, it.factorName)
+ val avg = average(list, it.factorName) ?: continue
// 鍘婚櫎鏃犳晥鍊肩殑鏍囧噯宸�
val std = standardDeviation(avg.first, list, it.factorName)
// 鍚堢悊鏈�澶у��
@@ -86,15 +118,104 @@
}
lastData.clear()
- mDataList.subList(mDataList.lastIndex - ncal + 1, mDataList.lastIndex + 1).forEach {
+ val s = if ((mDataList.lastIndex - ncal + 1) < 0) 0 else mDataList.lastIndex - ncal + 1
+ mDataList.subList(s, mDataList.lastIndex + 1).forEach {
lastData.add(it.copy())
}
return mDataList
}
- override fun sopPrep(sopList: List<CompanySOP>): List<CompanySOP> {
+ override fun sopPrep(sopList: List<BaseSOP>): List<BaseSOP> {
return sopList
+ }
+
+
+ /**
+ * 瀹炴椂鏁版嵁骞虫粦澶勭悊
+ */
+ fun mDataPrep2(dataPackage: AirDataPackage): List<DataVo> {
+ val vo = dataPackage.toDataVo()
+ return mDataPrep2(listOf(vo))
+ }
+
+ /**
+ * 瀹炴椂鏁版嵁骞虫粦澶勭悊
+ */
+ fun mDataPrep2(mDataList: List<DataVo>): List<DataVo> {
+ var i = ncal
+ if (lastData.isNotEmpty()) {
+ i = 0
+ }
+ while (i < mDataList.size) {
+ for (y in mDataList[i].values?.indices ?: 0..0) {
+ val it = mDataList[i].values?.get(y) ?: continue
+ val vMax = FactorType.getVMin(it.factorName) ?: continue
+ it.factorData ?: continue
+
+ if (it.factorData!! > vMax) {
+ val lastDataIndex = i
+ val thisIndex = if (i - ncal < 0) 0 else i - ncal
+ val list = mutableListOf<DataVo>()
+ if (lastDataIndex < lastData.size) {
+ list.addAll(lastData.subList(lastDataIndex, lastData.lastIndex + 1))
+ }
+ list.addAll(mDataList.subList(thisIndex, i))
+
+ // 鍘婚櫎鏃犳晥鍊肩殑骞冲潎锛屽綋鎵�鏈夋暟鎹兘鏄棤鏁堝�兼椂锛屾殏涓嶅仛澶勭悊
+ average(list, it.factorName)?.let { avg ->
+ // 鍘婚櫎鏃犳晥鍊肩殑鏍囧噯宸�
+ val std = standardDeviation(avg.first, list, it.factorName)
+ // 鍚堢悊鏈�澶у��
+ var maxValue = max(avg.first + std * nstd, avg.first + avg.first * xratio)
+ maxValue = max(maxValue, FactorType.getRange(it.factorName)?.second ?: .0)
+ // 鍚堢悊鏈�灏忓��
+ val minValue = min(avg.first - std * nstd, avg.first / (1 + xratio))
+
+ // 鍒ゆ柇鐩戞祴鍥犲瓙鏄惁闇�瑕佽繘琛屽钩婊戝鐞嗭紝
+ if (calTypes.contains(it.factorName)) {
+ // 鏁版嵁涓嶅浜庡悎鐞嗚寖鍥村苟涓旀湁鏁堜釜鏁拌揪鏍囨椂锛岄噰鐢ㄨ绠楁墍寰楀潎鍊间唬鏇垮師濮嬪��
+ if (avg.second > max(ncal / 5, 2)
+ && (it.factorData!! < minValue || it.factorData!! > maxValue)
+ ) {
+ it.factorData = avg.first
+ }
+ }
+ // 鍒ゆ柇閲忕骇鏄惁鍦ㄥ悎鐞嗚寖鍥村唴浠ュ強鍙樺寲鍊嶇巼鏄惁鍦ㄥ悎鐞嗚寖鍥村唴
+ else if (rangeTypes.contains(it.factorName)) {
+ if (isInRange(it) != true || excessiveChange(it) == true) {
+ // 閲囩敤璁$畻鎵�寰楀潎鍊间唬鏇垮師濮嬪��
+ it.factorData = avg.first
+ }
+ }
+ }
+ }
+ }
+
+ i++
+ }
+
+ // 灏嗘柊鏁版嵁鐨勮嚦澶氭渶鍚�15涓繚瀛樹笅鏉ワ紙宸茬粡杩囬澶勭悊锛夛紝鐢ㄤ簬涓嬩竴娆$殑鍒ゆ柇
+ val newList = mutableListOf<DataVo>()
+ val s = if ((mDataList.lastIndex - ncal + 1) < 0) 0 else mDataList.lastIndex - ncal + 1
+ mDataList.subList(s, mDataList.lastIndex + 1).forEach {
+ newList.add(it.copy())
+ }
+ // 褰撴柊鏁版嵁涓庢棫鏁版嵁閲囨牱鏃堕棿宸秴杩�1鍒嗛挓鏃讹紝璁や负涓ょ粍鏁版嵁宸叉棤鍏宠仈鎬э紝娓呯┖鏃ф暟鎹�
+ if (lastData.isNotEmpty() && newList.isNotEmpty()) {
+ val lastTime = DateUtil.instance.StringToDate(lastData.last().time)
+ val thisTime = DateUtil.instance.StringToDate(newList.first().time)
+ if ((thisTime?.time?.minus(lastTime?.time ?: 0) ?: 0) >= (60 * 1000)) {
+ lastData.clear()
+ }
+ }
+ lastData.addAll(newList)
+ // 纭繚淇濆瓨鐨勬暟鎹渶澶氬彧鏈夋渶鏂扮殑15涓�
+ while (lastData.size > ncal) {
+ lastData.removeAt(0)
+ }
+
+ return mDataList
}
/**
@@ -102,15 +223,17 @@
* @param list 鐩戞祴鏁版嵁
* @return 鍧囧�煎拰鏈夋晥鏁版嵁涓暟
*/
- private fun average(list: List<DataVo>, factorName:String?): Pair<Double, Int> {
+ private fun average(list: List<DataVo>, factorName: String?): Pair<Double, Int>? {
var t = 0.0
var c = 0
list.forEach {
for (i in it.values?.indices ?: 0..0) {
val f = it.values?.get(i)
if (f?.factorName == factorName) {
- if (f?.factorData != null) {
- t += f.factorData!!
+ val range = FactorType.getRange(f?.factorName) ?: continue
+ //鍒ゆ柇鏁版嵁鏄惁鍦ㄥ悎鐞嗚寖鍥村唴
+ if ((f?.factorData ?: 0.0) in range.first..range.second) {
+ t += f?.factorData!!
c++
}
break
@@ -121,10 +244,14 @@
val avg = if (c == 0) {
0.0
} else {
- t / c
+ round(t / c * 1000) / 1000
}
- return Pair(avg, c)
+ return if (c == 0) {
+ null
+ } else {
+ Pair(avg, c)
+ }
}
/**
@@ -137,8 +264,9 @@
for (i in it.values?.indices ?: 0..0) {
val f = it.values?.get(i)
if (f?.factorName == factorName) {
- if (f?.factorData != null) {
- t += (f.factorData!! - avg) * (f.factorData!! - avg)
+ val range = FactorType.getRange(f?.factorName) ?: continue
+ if ((f?.factorData ?: 0.0) in range.first..range.second) {
+ t += (f?.factorData!! - avg) * (f.factorData!! - avg)
c++
}
break
@@ -152,4 +280,32 @@
sqrt(t / (c - 1))
}
}
+
+ /**
+ * 鍒ゆ柇鏁版嵁鏄惁鍦ㄦ甯搁噺绋嬪唴
+ */
+ private fun isInRange(airData: AirData): Boolean? {
+ val range = FactorType.getRange(airData.factorName) ?: return null
+ //鍒ゆ柇鏁版嵁鏄惁鍦ㄥ悎鐞嗚寖鍥村唴
+ return (airData.factorData ?: 0.0) in range.first..range.second
+ }
+
+ /**
+ * 鍒ゆ柇杩炵画鐨勬暟鎹噺绾т笂鍗囧箙搴︽槸鍚﹁繃澶�
+ */
+ private fun excessiveChange(airData: AirData): Boolean? {
+ airData.factorData ?: return null
+ if (lastData.isEmpty()) return false
+ val latestData = lastData.last()
+ // 缁撴灉鍊嶇巼
+ var m = 1.0
+ for (i in latestData.values?.indices ?: 0..0) {
+ val f = latestData.values?.get(i)
+ if (f?.factorName == airData.factorName) {
+ m = airData.factorData!!.div(f?.factorData ?: airData.factorData!!)
+ break
+ }
+ }
+ return m > FactorType.getMultiplier(airData.factorName)
+ }
}
\ No newline at end of file
--
Gitblit v1.9.3