From e58a05b78d09bcd4c1a12e8610c5adfc316494e8 Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期四, 18 十二月 2025 10:04:42 +0800
Subject: [PATCH] 2025.12.18
---
src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedData.kt | 19 --
src/test/kotlin/com/flightfeather/uav/biz/sourcetrace/SourceTraceControllerTest.kt | 14 +
src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt | 15 -
src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt | 14 +
src/main/resources/application-test.yml | 12
src/test/kotlin/com/flightfeather/uav/lightshare/service/impl/MissionServiceImplTest.kt | 2
src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/config/RTExcWindLevelConfig.kt | 88 +++++++++++
src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedClue.kt | 17 --
src/main/kotlin/com/flightfeather/uav/model/epw/MutationDataPreprocess.kt | 143 ++++++++++++++++++++
src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt | 3
src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/MissionServiceImpl.kt | 2
src/main/kotlin/com/flightfeather/uav/biz/report/MissionGridFusion.kt | 40 +++++
src/main/kotlin/com/flightfeather/uav/socket/eunm/FactorType.kt | 2
src/test/kotlin/com/flightfeather/uav/biz/mission/MissionUtilTest.kt | 9
14 files changed, 311 insertions(+), 69 deletions(-)
diff --git a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt
index 0388a35..3d10232 100644
--- a/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt
+++ b/src/main/kotlin/com/flightfeather/uav/biz/dataanalysis/BaseExceptionContinuous.kt
@@ -75,7 +75,7 @@
}
/**
- * 鍒ゆ柇鏁版嵁閲忕骇鍦ㄥ紓甯稿垽鏂殑鑼冨洿鍐�
+ * 鍒ゆ柇鏁版嵁閲忕骇鏄惁鍦ㄥ紓甯稿垽鏂殑鑼冨洿鍐�
* 榛樿鎵�鏈夐噺绾ч兘鍦ㄥ紓甯稿垽鏂殑鑼冨洿鍐�
*/
open fun judgeDataScale(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> {
@@ -126,9 +126,15 @@
}
}
+ /**
+ * 寮傚父鏁版嵁澶勭悊鏍稿績鍒ゆ柇閫昏緫
+ */
override fun onNextData(data: BaseRealTimeData) {
+ // 1. 鍒ゆ柇鏂版暟鎹殑鏃堕棿杩炵画鎬�
val isContinue = isContinuous(lastData, data)
+ // 2. 璁$畻鍚勪釜鐩戞祴鍥犲瓙鏄惁鍙戠敓寮傚父
val hasException = judge(lastData, data)
+ // 3. 閬嶅巻閰嶇疆涓�変腑鐨勭洃娴嬪洜瀛愶紝鍒ゆ柇鏄惁鍙戠敓寮傚父
config.factorFilter.selectedList.forEach { s ->
val f = s.main
// 鎺掗櫎姝ゅ紓甯哥被鍨嬩笉閫傜敤鐨勭洃娴嬪洜瀛�
@@ -151,12 +157,18 @@
it.addHistoryData(data)
}
}
+ // 4. 鏇存柊鏈�鏂版暟鎹�
lastData = data
+ // 5. 淇濆瓨骞剁Щ闄ゅ崟鍥犲瓙寮傚父
removeSingleFactor(data)
+ // 6. 妫�鏌ュ欢杩熷紓甯�
val fittedComb = checkDelayedExceptions(data)
+ // 7. 鍚堝苟寮傚父缁撴灉
mergeExceptionResult(data, fittedComb)
+ // 8. 瑙﹀彂鏂板紓甯哥粨鏋滀簨浠�
onNewResult(result)
+ // 9. 娓呴櫎寮傚父璁板綍
clearExceptions(data)
}
diff --git a/src/main/kotlin/com/flightfeather/uav/biz/report/MissionGridFusion.kt b/src/main/kotlin/com/flightfeather/uav/biz/report/MissionGridFusion.kt
index 563c22b..4b334b8 100644
--- a/src/main/kotlin/com/flightfeather/uav/biz/report/MissionGridFusion.kt
+++ b/src/main/kotlin/com/flightfeather/uav/biz/report/MissionGridFusion.kt
@@ -149,16 +149,32 @@
town = if (address.address.contains(address.streetNumber)) {
address.address
} else {
- address.address + "锛�" + address.street + address.streetNumber + "锛�"
+// address.address + "锛�" + address.street + address.streetNumber + "锛�"
+ address.address
}
}
- val polygon = listOf(
+ var polygon = listOf(
gf.cell.point1Lon.toDouble() to gf.cell.point1Lat.toDouble(),
gf.cell.point2Lon.toDouble() to gf.cell.point2Lat.toDouble(),
gf.cell.point3Lon.toDouble() to gf.cell.point3Lat.toDouble(),
gf.cell.point4Lon.toDouble() to gf.cell.point4Lat.toDouble(),
)
bounds = MapUtil.calFourBoundaries(polygon)
+ // 灏嗙綉鏍兼悳绱㈣寖鍥存墿澶т竴鍦堢綉鏍�(閽堝鍖楃含涓滅粡鐨勬儏鍐典笅)
+ bounds?.let { bs->
+ val offsetLon = bs[1] - bs[0]
+ val offsetLat = bs[3] - bs[2]
+ polygon = listOf(
+ // 缃戞牸瑗垮寳瑙�
+ bs[0] - offsetLon to bs[3] + offsetLat,
+ // 缃戞牸涓滃寳瑙�
+ bs[1] + offsetLon to bs[3] + offsetLat,
+ // 缃戞牸涓滃崡瑙�
+ bs[1] + offsetLon to bs[2] - offsetLat,
+ // 缃戞牸瑗垮崡瑙�
+ bs[0] - offsetLon to bs[2] - offsetLat,
+ )
+ }
highRiskScenes =
sceneInfoRep.findByPolygon(polygon, listOf(SceneType.TYPE19, SceneType.TYPE20, SceneType.TYPE21))
}
@@ -189,16 +205,32 @@
town = if (address.address.contains(address.streetNumber)) {
address.address
} else {
- address.address + address.street + address.streetNumber
+// address.address + "锛�" + address.street + address.streetNumber + "锛�"
+ address.address
}
}
- val polygon = listOf(
+ var polygon = listOf(
gf.cell.point1Lon.toDouble() to gf.cell.point1Lat.toDouble(),
gf.cell.point2Lon.toDouble() to gf.cell.point2Lat.toDouble(),
gf.cell.point3Lon.toDouble() to gf.cell.point3Lat.toDouble(),
gf.cell.point4Lon.toDouble() to gf.cell.point4Lat.toDouble(),
)
bounds = MapUtil.calFourBoundaries(polygon)
+ // 灏嗙綉鏍兼悳绱㈣寖鍥存墿澶т竴鍦堢綉鏍�(閽堝鍖楃含涓滅粡鐨勬儏鍐典笅)
+ bounds?.let { bs->
+ val offsetLon = bs[1] - bs[0]
+ val offsetLat = bs[3] - bs[2]
+ polygon = listOf(
+ // 缃戞牸瑗垮寳瑙�
+ bs[0] - offsetLon to bs[3] + offsetLat,
+ // 缃戞牸涓滃寳瑙�
+ bs[1] + offsetLon to bs[3] + offsetLat,
+ // 缃戞牸涓滃崡瑙�
+ bs[1] + offsetLon to bs[2] - offsetLat,
+ // 缃戞牸瑗垮崡瑙�
+ bs[0] - offsetLon to bs[2] - offsetLat,
+ )
+ }
highRiskScenes =
sceneInfoRep.findByPolygon(polygon, listOf(SceneType.TYPE19, SceneType.TYPE20, SceneType.TYPE21))
})
diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/config/RTExcWindLevelConfig.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/config/RTExcWindLevelConfig.kt
index 9d69ca6..b51ab61 100644
--- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/config/RTExcWindLevelConfig.kt
+++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/config/RTExcWindLevelConfig.kt
@@ -49,7 +49,7 @@
.0 to 1.5,
0.2 to 0.5,
DistanceType.TYPE2,
- 1
+ 2
)
// 2 - 4绾ч
@@ -95,6 +95,24 @@
DistanceType.TYPE1,
1
),
+ FactorType.NO to WindLevelCondition(
+ .0 to 1.5,
+ 8.0 to Double.MAX_VALUE,
+ DistanceType.TYPE1,
+ 4
+ ),
+ FactorType.NO2 to WindLevelCondition(
+ .0 to 1.5,
+ 4.0 to Double.MAX_VALUE,
+ DistanceType.TYPE1,
+ 4
+ ),
+ FactorType.CO to WindLevelCondition(
+ .0 to 1.5,
+ 10.0 to Double.MAX_VALUE,
+ DistanceType.TYPE1,
+ 5
+ ),
)
// 鍦ㄩ閫熷浜�1.6 - 7.9 m/s 涔嬮棿鏃�
var changeRateUp2 = mutableMapOf(
@@ -119,6 +137,24 @@
DistanceType.TYPE3,
1
),
+ FactorType.NO to WindLevelCondition(
+ 1.6 to 7.9,
+ 8.0 to Double.MAX_VALUE,
+ DistanceType.TYPE3,
+ 4
+ ),
+ FactorType.NO2 to WindLevelCondition(
+ 1.6 to 7.9,
+ 4.0 to Double.MAX_VALUE,
+ DistanceType.TYPE3,
+ 4
+ ),
+ FactorType.CO to WindLevelCondition(
+ 1.6 to 7.9,
+ 10.0 to Double.MAX_VALUE,
+ DistanceType.TYPE3,
+ 5
+ ),
)
// 鍦ㄩ閫熷浜�8.0 - 13.8 m/s 涔嬮棿鏃�
var changeRateUp3 = mutableMapOf(
@@ -142,6 +178,24 @@
6.0 to Double.MAX_VALUE,
DistanceType.TYPE4,
1
+ ),
+ FactorType.NO to WindLevelCondition(
+ 8.0 to 13.8,
+ 8.0 to Double.MAX_VALUE,
+ DistanceType.TYPE4,
+ 4
+ ),
+ FactorType.NO2 to WindLevelCondition(
+ 8.0 to 13.8,
+ 4.0 to Double.MAX_VALUE,
+ DistanceType.TYPE4,
+ 4
+ ),
+ FactorType.CO to WindLevelCondition(
+ 8.0 to 13.8,
+ 10.0 to Double.MAX_VALUE,
+ DistanceType.TYPE4,
+ 5
),
)
@@ -168,6 +222,24 @@
DistanceType.TYPE1,
3
),
+ FactorType.NO to WindLevelCondition(
+ .0 to Double.MAX_VALUE,
+ -Double.MAX_VALUE to -6.0,
+ DistanceType.TYPE1,
+ 4
+ ),
+ FactorType.NO2 to WindLevelCondition(
+ .0 to Double.MAX_VALUE,
+ -Double.MAX_VALUE to -2.0,
+ DistanceType.TYPE1,
+ 4
+ ),
+ FactorType.CO to WindLevelCondition(
+ .0 to Double.MAX_VALUE,
+ -Double.MAX_VALUE to -10.0,
+ DistanceType.TYPE1,
+ 5
+ ),
)
/****鏁版嵁鏈変笂鍗囪秼鍔挎彁閱�*****************************************************************************/
@@ -182,16 +254,22 @@
// PM10鍦ㄤ竴涓洃娴嬪懆鏈燂紙4绉掞級涓婂崌閲忕骇鍦�2 - 4渭g/m鲁涔嬮棿锛岃繛缁彂鐢�3娆�
FactorType.PM10 to WindLevelCondition(
.0 to Double.MAX_VALUE,
- 2.0 to 4.0,
+ 4.0 to 8.0,
DistanceType.TYPE1,
- 2
+ 4
),
// VOC鍦ㄤ竴涓洃娴嬪懆鏈燂紙4绉掞級涓婂崌閲忕骇鍦�3 - 6渭g/m鲁涔嬮棿锛岃繛缁彂鐢�2娆�
FactorType.VOC to WindLevelCondition(
.0 to Double.MAX_VALUE,
- 3.0 to 6.0,
+ 2.0 to 4.0,
DistanceType.TYPE1,
- 2
+ 4
+ ),
+ FactorType.CO to WindLevelCondition(
+ .0 to Double.MAX_VALUE,
+ 5.0 to 10.0,
+ DistanceType.TYPE1,
+ 5
),
)
diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedClue.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedClue.kt
index 6035ec5..306d4a7 100644
--- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedClue.kt
+++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedClue.kt
@@ -20,18 +20,6 @@
*/
class PollutedClue() : BaseExceptionResult() {
-// constructor(
-// tag: ExceptionTag, factor: FactorFilter.SelectedFactor, eType: ExceptionType, config: RTExcWindLevelConfig,
-// windLevelCondition: RTExcWindLevelConfig.WindLevelCondition?,
-// ) : this() {
-// if (tag.exceptionData.isEmpty()) return
-// deviceCode = tag.startData?.deviceCode
-// pollutedData = PollutedData(
-// tag.startData!!, tag.endData, factor, tag.exceptionData, tag.historyData, eType, windLevelCondition
-// )
-// pollutedArea = PollutedArea(tag.historyData, tag.exceptionData, config, windLevelCondition)
-// }
-
constructor(
exceptions: List<Pair<FactorFilter.SelectedFactor, ExceptionTag>>,
eType: ExceptionType,
@@ -97,11 +85,6 @@
pollutedArea = PollutedArea(historyData, exceptionData, config, windLevelCondition)
}
-
-
- /**
- * 6. 灞曠ず鏁版嵁鍙樺寲鎯呭喌锛屼笂鍗囬�熺巼绛夌瓑
- */
/**
* @see [MsgType]
diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedData.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedData.kt
index 5dd3328..577b38b 100644
--- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedData.kt
+++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedData.kt
@@ -34,15 +34,6 @@
var max: Double? = null
}
- /**
- * 9. 鍏宠仈鍥犲瓙
- * a) pm2.5銆乸m10鐗瑰埆楂橈紝涓よ�呭湪鍚勬儏鍐典笅鍚屾灞曠ず锛宲m2.5鍗爌m10鐨勬瘮閲嶅彉鍖栵紝姣旈噸瓒婇珮锛岃秺鏈夊彲鑳芥槸椁愰ギ
- * b) pm10鐗瑰埆楂樸�乸m2.5杈冮珮锛屽ぇ棰楃矑鎵皹姹℃煋锛屽彧灞曠ずpm10锛宲m2.5鍗爌m10鐨勬瘮閲嶅彉鍖栵紝宸ュ湴涓轰富
- * c) VOC杈冮珮锛屽悓姣旇绠梡m2.5鐨勯噺绾э紝鍙兘瀛樺湪鍚屾鍋忛珮锛堟苯淇�佸姞娌圭珯锛�, 鍚屾璁$畻O3鏄惁鏈夐珮鍊�
- * d) VOC杈冮珮锛屽浜庡姞娌圭珯锛堣溅杈嗘嫢鍫垫儏鍐碉級锛孋O涓�鑸緝楂�, 鍚屾璁$畻O3鏄惁鏈夐珮鍊�
- * e) 姘哀鍖栧悎鐗╋紝涓�鑸敱浜庢満鍔ㄨ溅灏炬皵锛屽悓姝ヨ绠桟O
- */
-
constructor(
start: BaseRealTimeData,
end: BaseRealTimeData?,
@@ -59,8 +50,8 @@
endTime = end?.dataTime
// startData = start.getByFactorType(factor.main)
// endData = end?.getByFactorType(factor.main) ?: startData
- startData = start
- endData = end
+// startData = start
+// endData = end
windSpeed = exceptionData.first().windSpeed?.toDouble()
times = windLevelCondition?.countLimit
@@ -100,8 +91,8 @@
var startTime: Date? = null
var endTime: Date? = null
- var startData: BaseRealTimeData? = null
- var endData: BaseRealTimeData? = null
+// var startData: BaseRealTimeData? = null
+// var endData: BaseRealTimeData? = null
// 椋庨��
var windSpeed: Double? = null
@@ -110,7 +101,7 @@
var times: Int? = null
var historyDataList = mutableListOf<DataVo>()
- // 寮傚父鐩戞祴鏁版嵁锛屽寘鍚崟姝ゅ紓甯镐腑鎵�鏈夊彂鐢熶簡寮傚父鐨勬暟鎹�硷紙鍙兘涓嶆槸鏃堕棿杩炵画鐨勬暟鎹級
+ // 寮傚父鐩戞祴鏁版嵁锛屽寘鍚崟娆″紓甯镐腑鎵�鏈夊彂鐢熶簡寮傚父鐨勬暟鎹�硷紙鍙兘涓嶆槸鏃堕棿杩炵画鐨勬暟鎹級
var dataList: MutableList<BaseRealTimeData> = mutableListOf()
var dataVoList: MutableList<DataVo> = mutableListOf()
diff --git a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt
index 706622c..ab85953 100644
--- a/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt
+++ b/src/main/kotlin/com/flightfeather/uav/biz/sourcetrace/model/PollutedSource.kt
@@ -46,12 +46,12 @@
// Fixme 2025.5.14: 姹℃煋婧愮殑鍧愭爣鏄珮寰峰湴鍥惧潗鏍囩郴锛堢伀鏄熷潗鏍囩郴锛夛紝鑰岃蛋鑸暟鎹槸WGS84鍧愭爣绯�
// 鎸夌収鍖哄煙妫�绱㈠唴閮ㄦ薄鏌撴簮淇℃伅
var result = mutableListOf<SceneInfo>()
- // 1. 棣栧厛鎸夌収鍥涜嚦鑼冨洿浠庢暟鎹簱鍒濇绛涢�夋薄鏌撴簮锛屾澶勭殑鍖哄煙鍧愭爣宸茶浆鎹负鐏槦鍧愭爣绯�
val polygonTmp = pollutedArea.polygon
this.sceneList = emptyList()
if (polygonTmp != null) {
val fb = MapUtil.calFourBoundaries(polygonTmp)
+ // 1. 棣栧厛鎸夌収鍥涜嚦鑼冨洿浠庢暟鎹簱鍒濇绛涢�夋薄鏌撴簮锛屾澶勭殑鍖哄煙鍧愭爣宸茶浆鎹负鐏槦鍧愭爣绯�
val sceneList = sceneInfoRep.findByCoordinateRange(fb)
// 2. 鍐嶇簿纭垽鏂槸鍚﹀湪鍙嶅悜婧簮鍖哄煙澶氳竟褰㈠唴閮�
sceneList.forEach {
@@ -61,6 +61,7 @@
}
}
+ // 3. 鍐嶇粺涓�妫�绱㈣繎璺濈姹℃煋鍦嗗舰鍖哄煙鍐呴儴鐨勬薄鏌撴簮
val closePolygonTmp = pollutedArea.closePolygon!!
val closeFb = MapUtil.calFourBoundaries(closePolygonTmp)
val closeSceneList = sceneInfoRep.findByCoordinateRange(closeFb)
@@ -70,13 +71,12 @@
result.add(it)
}
}
- // 鍘婚噸
+ // 4. 鍘婚噸
result = result.distinctBy { it.guid }.toMutableList()
- // 鏍规嵁姹℃煋鍥犲瓙鐨勯噺绾э紝璁$畻涓昏鐨勬薄鏌撳満鏅被鍨嬶紝绛涢�夌粨鏋�
+ // 5. 鏍规嵁姹℃煋鍥犲瓙鐨勯噺绾э紝璁$畻涓昏鐨勬薄鏌撳満鏅被鍨嬶紝绛涢�夌粨鏋�
val mainSceneType = calSceneType(pollutedData)
if (mainSceneType != null) {
-// this.conclusion = mainSceneType.first
result = result.filter {
val r = mainSceneType.second.find { s ->
s.value == it.typeId.toInt()
@@ -107,7 +107,7 @@
// val coAvg = round(pollutedData.dataList.map { it.co!! }.average()) / 1000
val coAvg = round(pollutedData.statisticMap[FactorType.CO]?.avg ?: .0) / 1000
"姘哀鍖栧悎鐗╁亸楂橈紝CO鐨勯噺绾т负${coAvg}mg/m鲁锛屼竴鑸敱浜庢満鍔ㄨ溅灏炬皵閫犳垚锛屾薄鏌撴簮浠ユ苯淇�佸姞娌圭珯涓轰富" to
- listOf(SceneType.TYPE6, SceneType.TYPE10, SceneType.TYPE17)
+ listOf(SceneType.TYPE1, SceneType.TYPE6, SceneType.TYPE10, SceneType.TYPE17)
}
FactorType.CO -> "" to listOf(SceneType.TYPE6, SceneType.TYPE10, SceneType.TYPE17)
@@ -229,9 +229,6 @@
* @return 婧簮鎻忚堪
*/
private fun summaryTxt(pollutedData: PollutedData, sceneList: List<SceneInfoVo>): String {
-// pollutedData.exception
-// pollutedData.selectedFactor?.main
-
val st = DateUtil.instance.getTime(pollutedData.startTime)
val et = DateUtil.instance.getTime(pollutedData.endTime)
@@ -277,7 +274,7 @@
val curValue = pollutedData.dataList.last().getByFactorType(s.key)
if (preValue == null || curValue == null) return@forEach
val r = round((curValue - preValue) / preValue * 100)
- txt += "锛屼粠${preValue}渭g/m鲁蹇�熶笂鍗囪嚦${curValue}渭g/m鲁锛屽彉鍖栫巼涓�${r}%"
+ txt += "锛�${s.key.getTxt()}浠�${preValue}渭g/m鲁蹇�熶笂鍗囪嚦${curValue}渭g/m鲁锛屽彉鍖栫巼涓�${r}%"
}
}
}
diff --git a/src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt b/src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt
index 1066c78..a525f6e 100644
--- a/src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt
+++ b/src/main/kotlin/com/flightfeather/uav/domain/entity/BaseRealTimeData.kt
@@ -122,7 +122,7 @@
}
fun getByFactorType(type: FactorType?): Float? {
- return when (type) {
+ val res = when (type) {
FactorType.NO2 -> no2
FactorType.CO -> co
FactorType.H2S -> h2s
@@ -144,6 +144,7 @@
FactorType.NO -> no
else -> null
}
+ return if (res != null) round(res * 100) / 100 else null
}
}
diff --git a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/MissionServiceImpl.kt b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/MissionServiceImpl.kt
index c8ace2f..54484a9 100644
--- a/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/MissionServiceImpl.kt
+++ b/src/main/kotlin/com/flightfeather/uav/lightshare/service/impl/MissionServiceImpl.kt
@@ -94,7 +94,7 @@
val data = realTimeDataRep.fetchData(mission)
mission.kilometres = MissionUtil.calKilometres(data).toFloat()
// todo: 璁$畻璧拌埅浠诲姟鎵�鍦ㄤ腑蹇冨尯鍩�
- mission.region = MissionUtil.calRegion(data)
+// mission.region = MissionUtil.calRegion(data)
return updateMission(mission)
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/model/epw/MutationDataPreprocess.kt b/src/main/kotlin/com/flightfeather/uav/model/epw/MutationDataPreprocess.kt
new file mode 100644
index 0000000..cb35e11
--- /dev/null
+++ b/src/main/kotlin/com/flightfeather/uav/model/epw/MutationDataPreprocess.kt
@@ -0,0 +1,143 @@
+package com.flightfeather.uav.model.epw
+
+import com.flightfeather.uav.common.utils.DateUtil
+import com.flightfeather.uav.lightshare.bean.DataVo
+import com.flightfeather.uav.socket.bean.AirData
+import com.flightfeather.uav.socket.eunm.FactorType
+
+/**
+ * 绐佸彉鏁版嵁棰勫鐞�
+ * 1. 閽堝鍗曚釜鏁版嵁绐侀珮鎴栫獊浣庯紝鍓嶅悗涓や釜鏁版嵁鐨勯噺绾ф帴杩戠殑鎯呭喌锛岃繘琛屽鐞�
+ * 2. 閽堝鏈夊叧鑱斿叧绯荤殑鐩戞祴鍥犲瓙锛屾暟鎹噺绾у嚭鐜版槑鏄鹃敊璇殑鎯呭喌锛岃繘琛屽鐞�
+ * @date 2025/11/20
+ * @author feiyu02
+ */
+class MutationDataPreprocess {
+
+ // 淇濆瓨鏁版嵁鏈�澶ц褰曟暟
+ private val MAX_COUNT = 15
+
+ private val lastData = mutableListOf<DataVo>()
+
+ // 閲忕骇鍙樺寲闃堝�煎�嶆暟锛堢敤浜庡垽鏂槸鍚︿负绐佸彉锛�
+ private val MUTATION_THRESHOLD = 5.0
+ // 鍓嶅悗鏁版嵁鎺ヨ繎闃堝�煎�嶆暟锛堢敤浜庡垽鏂墠鍚庢暟鎹槸鍚﹂噺绾ф帴杩戯級
+ private val SIMILARITY_THRESHOLD = 1.5
+
+ /**
+ * 鏁版嵁骞虫粦
+ * 瑙e喅鍗曚釜鏁版嵁鐩告瘮鍓嶅悗涓や釜鏁版嵁鐨勯噺绾ц繃澶ф垨杩囧皬鐨勯棶棰�
+ * @param data 鍘熷鏁版嵁
+ * @return 棰勫鐞嗗悗鐨勬暟鎹�
+ */
+ fun preprocess(data: List<DataVo>): List<DataVo> {
+ // 褰撴柊鏁版嵁涓庢棫鏁版嵁閲囨牱鏃堕棿宸秴杩�1鍒嗛挓鏃讹紝璁や负涓ょ粍鏁版嵁宸叉棤鍏宠仈鎬э紝娓呯┖鏃ф暟鎹�
+ if (lastData.isNotEmpty() && data.isNotEmpty()) {
+ val lastTime = DateUtil.instance.StringToDate(lastData.last().time)
+ val thisTime = DateUtil.instance.StringToDate(data.first().time)
+ if ((thisTime?.time?.minus(lastTime?.time ?: 0) ?: 0) >= (60 * 1000)) {
+ lastData.clear()
+ }
+ }
+ lastData.addAll(data)
+ detectAndReplaceMutation(lastData)
+ saveHistory(lastData)
+ return lastData
+ }
+
+ /**
+ * 妫�娴嬪苟鏇挎崲寮傚父绐佸彉鏁版嵁
+ * @param data 鍘熷鏁版嵁鍒楄〃
+ * @return 澶勭悊鍚庣殑鏁版嵁鍒楄〃
+ */
+ fun detectAndReplaceMutation(data: MutableList<DataVo>){
+ if (data.size < 3) return // 鏁版嵁閲忎笉瓒筹紝鏃犳硶杩涜鍓嶅悗瀵规瘮
+
+ // 閬嶅巻鏁版嵁锛屼粠绗簩涓紑濮嬪埌鍊掓暟绗簩涓粨鏉�
+ for (i in 1 until data.size - 1) {
+ val currentData = data[i]
+ val prevData = data[i - 1]
+ val nextData = data[i + 1]
+
+ // 妫�鏌ユ瘡涓洃娴嬪洜瀛�
+ if (currentData.values != null && prevData.values != null && nextData.values != null) {
+ processEachFactor(currentData, prevData, nextData)
+ }
+ }
+
+ }
+
+ /**
+ * 澶勭悊姣忎釜鐩戞祴鍥犲瓙鐨勬暟鎹獊鍙�
+ */
+ private fun processEachFactor(currentData: DataVo, prevData: DataVo, nextData: DataVo) {
+ val currentFactors = mutableMapOf<String, AirData>()
+ val prevFactors = mutableMapOf<String, AirData>()
+ val nextFactors = mutableMapOf<String, AirData>()
+
+ // 鏋勫缓鍥犲瓙鍚嶇О鍒癆irData鐨勬槧灏�
+ currentData.values?.forEach { currentFactors[it.factorName ?: ""] = it }
+ prevData.values?.forEach { prevFactors[it.factorName ?: ""] = it }
+ nextData.values?.forEach { nextFactors[it.factorName ?: ""] = it }
+
+ // 閬嶅巻褰撳墠鏁版嵁涓殑鎵�鏈夊洜瀛�
+ currentFactors.forEach { (factorName, currentFactor) ->
+ val prevFactor = prevFactors[factorName]
+ val nextFactor = nextFactors[factorName]
+
+ // 纭繚涓変釜鏁版嵁鐐归兘鏈夎鍥犲瓙鐨勬暟鎹�
+ if (prevFactor != null && nextFactor != null &&
+ currentFactor.factorData != null && prevFactor.factorData != null && nextFactor.factorData != null) {
+
+ val currentValue = currentFactor.factorData!!
+ val prevValue = prevFactor.factorData!!
+ val nextValue = nextFactor.factorData!!
+
+ // 璺宠繃0鍊兼垨璐熷�硷紝閬垮厤闄ら浂閿欒
+ if (prevValue <= 0 || nextValue <= 0) return@forEach
+
+ // 妫�鏌ユ槸鍚︿负寮傚父绐佸彉鏁版嵁
+ if (isMutationData(currentValue, prevValue, nextValue)) {
+ // 鏇挎崲涓哄墠涓�涓暟鎹殑鍊�
+ currentFactor.factorData = prevValue
+ }
+ }
+ }
+ }
+
+ /**
+ * 鍒ゆ柇褰撳墠鏁版嵁鏄惁涓虹獊鍙樻暟鎹�
+ * 鏉′欢锛�1. 褰撳墠鏁版嵁涓庡墠涓�涓暟鎹殑閲忕骇鍙樺寲瓒呰繃闃堝��
+ * 2. 鍓嶄竴涓暟鎹笌鍚庝竴涓暟鎹殑閲忕骇鎺ヨ繎
+ */
+ private fun isMutationData(currentValue: Double, prevValue: Double, nextValue: Double): Boolean {
+ // 璁$畻鍙樺寲鐜�
+ val currentToPrevRatio = Math.max(currentValue, prevValue) / Math.min(currentValue, prevValue)
+ val prevToNextRatio = Math.max(prevValue, nextValue) / Math.min(prevValue, nextValue)
+
+ // 鍒ゆ柇鏄惁婊¤冻绐佸彉鏉′欢
+ return currentToPrevRatio > MUTATION_THRESHOLD && prevToNextRatio <= SIMILARITY_THRESHOLD
+ }
+
+ fun saveHistory(data: MutableList<DataVo>) {
+// // 灏嗘柊鏁版嵁鐨勮嚦澶氭渶鍚�15涓繚瀛樹笅鏉ワ紙宸茬粡杩囬澶勭悊锛夛紝鐢ㄤ簬涓嬩竴娆$殑鍒ゆ柇
+// val newList = mutableListOf<DataVo>()
+// val s = if ((data.lastIndex - MAX_COUNT + 1) < 0) 0 else data.lastIndex - MAX_COUNT + 1
+// data.subList(s, data.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 (data.size > MAX_COUNT) {
+ data.removeAt(0)
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/flightfeather/uav/socket/eunm/FactorType.kt b/src/main/kotlin/com/flightfeather/uav/socket/eunm/FactorType.kt
index e99a0b7..62af905 100644
--- a/src/main/kotlin/com/flightfeather/uav/socket/eunm/FactorType.kt
+++ b/src/main/kotlin/com/flightfeather/uav/socket/eunm/FactorType.kt
@@ -157,7 +157,7 @@
}
/**
- * 涓嶅鐞嗕綆浜庢鍊肩殑鍊�
+ * 涓嶅鐞嗕綆浜庢鍊肩殑鏁版嵁
*/
fun getVMin(type: FactorType): Double = when (type) {
NO -> 1.0
diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml
index 75ca738..02d8369 100644
--- a/src/main/resources/application-test.yml
+++ b/src/main/resources/application-test.yml
@@ -7,13 +7,13 @@
# password: cn.FLIGHTFEATHER
# 杩滅▼鏈嶅姟鍣�
-# url: jdbc:mysql://47.100.191.150:3306/dronemonitor?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
-# username: remoteU1
-# password: eSoF8DnzfGTlhAjE
-
- url: jdbc:mysql://114.215.109.124:3306/dronemonitor?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
+ url: jdbc:mysql://47.100.191.150:3306/dronemonitor?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
username: remoteU1
- password: feiyu2024
+ password: eSoF8DnzfGTlhAjE
+
+# url: jdbc:mysql://114.215.109.124:3306/dronemonitor?serverTimezone=Asia/Shanghai&prepStmtCacheSize=517&cachePrepStmts=true&autoReconnect=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
+# username: remoteU1
+# password: feiyu2024
springfox:
documentation:
diff --git a/src/test/kotlin/com/flightfeather/uav/biz/mission/MissionUtilTest.kt b/src/test/kotlin/com/flightfeather/uav/biz/mission/MissionUtilTest.kt
index ce27a1a..7550519 100644
--- a/src/test/kotlin/com/flightfeather/uav/biz/mission/MissionUtilTest.kt
+++ b/src/test/kotlin/com/flightfeather/uav/biz/mission/MissionUtilTest.kt
@@ -22,9 +22,12 @@
@Test
fun calKilometres() {
- val m = missionRep.findOne("20250819") ?: return
- val data = realTimeDataRep.fetchData(m)
- MissionUtil.calKilometres(data)
+ val mcodeList = listOf("20250427", "20250526", "20250530")
+ mcodeList.forEach { mcode ->
+ val m = missionRep.findOne(mcode) ?: return@forEach
+ val data = realTimeDataRep.fetchData(m)
+ MissionUtil.calKilometres(data)
+ }
// val d = MapUtil.getDistance(121.425187, 31.225907, 121.425196, 31.225892)
// println(d)
// val d1 = MapUtil.getDistance(121.425196, 31.225892, 121.425187, 31.225907)
diff --git a/src/test/kotlin/com/flightfeather/uav/biz/sourcetrace/SourceTraceControllerTest.kt b/src/test/kotlin/com/flightfeather/uav/biz/sourcetrace/SourceTraceControllerTest.kt
index 05d4e09..651ed15 100644
--- a/src/test/kotlin/com/flightfeather/uav/biz/sourcetrace/SourceTraceControllerTest.kt
+++ b/src/test/kotlin/com/flightfeather/uav/biz/sourcetrace/SourceTraceControllerTest.kt
@@ -45,10 +45,10 @@
// "SH-CN-20240723(02)",
//// "SH-CN-20250723(01)"
// )
-// val startTime = LocalDateTime.of(2024, 12, 31, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant()
- val startTime = LocalDateTime.of(2025, 7, 1, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant()
- val endTime = LocalDateTime.of(2025, 9, 30, 23, 59, 59).atZone(ZoneId.systemDefault()).toInstant()
-// val endTime = LocalDateTime.of(2025, 7, 31, 23, 59, 59).atZone(ZoneId.systemDefault()).toInstant()
+// val startTime = LocalDateTime.of(2025, 7, 1, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant()
+// val endTime = LocalDateTime.of(2025, 9, 30, 23, 59, 59).atZone(ZoneId.systemDefault()).toInstant()
+ val startTime = LocalDateTime.of(2025, 11, 2, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant()
+ val endTime = LocalDateTime.of(2025, 11, 2, 23, 59, 59).atZone(ZoneId.systemDefault()).toInstant()
val missions = missionMapper.selectByExample(Example(Mission::class.java).apply {
createCriteria().andBetween("startTime", startTime, endTime)
})
@@ -116,8 +116,10 @@
// "SH-CN-20240723(02)",
//// "SH-CN-20250723(01)"
// )
- val startTime = LocalDateTime.of(2025, 7, 1, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant()
- val endTime = LocalDateTime.of(2025, 9, 30, 23, 59, 59).atZone(ZoneId.systemDefault()).toInstant()
+// val startTime = LocalDateTime.of(2025, 7, 1, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant()
+// val endTime = LocalDateTime.of(2025, 9, 30, 23, 59, 59).atZone(ZoneId.systemDefault()).toInstant()
+ val startTime = LocalDateTime.of(2025, 11, 2, 0, 0, 0).atZone(ZoneId.systemDefault()).toInstant()
+ val endTime = LocalDateTime.of(2025, 11, 2, 23, 59, 59).atZone(ZoneId.systemDefault()).toInstant()
val missions = missionMapper.selectByExample(Example(Mission::class.java).apply {
createCriteria().andBetween("startTime", startTime, endTime)
})
diff --git a/src/test/kotlin/com/flightfeather/uav/lightshare/service/impl/MissionServiceImplTest.kt b/src/test/kotlin/com/flightfeather/uav/lightshare/service/impl/MissionServiceImplTest.kt
index d66b52b..f5f17d3 100644
--- a/src/test/kotlin/com/flightfeather/uav/lightshare/service/impl/MissionServiceImplTest.kt
+++ b/src/test/kotlin/com/flightfeather/uav/lightshare/service/impl/MissionServiceImplTest.kt
@@ -34,7 +34,7 @@
@Test
fun calMissionInfo() {
missionMapper.selectByExample(Example(Mission::class.java).apply {
- createCriteria().andGreaterThanOrEqualTo("startTime", "2025-07-08 08:30:00")
+ createCriteria().andBetween("startTime", "2025-12-05 00:00:00", "2025-12-31 23:59:59")
}).forEach {mission ->
mission?.let { missionService.calMissionInfo(it.missionCode) }
Thread.sleep(1000)
--
Gitblit v1.9.3