| | |
| | | } |
| | | |
| | | /** |
| | | * å¤ææ°æ®é级å¨å¼å¸¸å¤æçèå´å
|
| | | * å¤ææ°æ®é级æ¯å¦å¨å¼å¸¸å¤æçèå´å
|
| | | * é»è®¤ææé级é½å¨å¼å¸¸å¤æçèå´å
|
| | | */ |
| | | open fun judgeDataScale(p: BaseRealTimeData?, n: BaseRealTimeData): MutableMap<FactorType, Boolean> { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * å¼å¸¸æ°æ®å¤çæ ¸å¿å¤æé»è¾ |
| | | */ |
| | | 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 |
| | | // æé¤æ¤å¼å¸¸ç±»åä¸éç¨ççæµå å |
| | |
| | | it.addHistoryData(data) |
| | | } |
| | | } |
| | | // 4. æ´æ°ææ°æ°æ® |
| | | lastData = data |
| | | |
| | | // 5. ä¿åå¹¶ç§»é¤åå åå¼å¸¸ |
| | | removeSingleFactor(data) |
| | | // 6. æ£æ¥å»¶è¿å¼å¸¸ |
| | | val fittedComb = checkDelayedExceptions(data) |
| | | // 7. åå¹¶å¼å¸¸ç»æ |
| | | mergeExceptionResult(data, fittedComb) |
| | | // 8. è§¦åæ°å¼å¸¸ç»æäºä»¶ |
| | | onNewResult(result) |
| | | // 9. æ¸
é¤å¼å¸¸è®°å½ |
| | | clearExceptions(data) |
| | | } |
| | | |
| | |
| | | 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)) |
| | | } |
| | |
| | | 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)) |
| | | }) |
| | |
| | | .0 to 1.5, |
| | | 0.2 to 0.5, |
| | | DistanceType.TYPE2, |
| | | 1 |
| | | 2 |
| | | ) |
| | | |
| | | // 2 - 4çº§é£ |
| | |
| | | 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( |
| | |
| | | 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( |
| | |
| | | 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 |
| | | ), |
| | | ) |
| | | |
| | |
| | | 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 |
| | | ), |
| | | ) |
| | | |
| | | /****æ°æ®æä¸åè¶å¿æé*****************************************************************************/ |
| | |
| | | // 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 |
| | | ), |
| | | ) |
| | | |
| | |
| | | */ |
| | | 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, |
| | |
| | | pollutedArea = PollutedArea(historyData, exceptionData, config, windLevelCondition) |
| | | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 6. å±ç¤ºæ°æ®ååæ
åµï¼ä¸åéççç |
| | | */ |
| | | |
| | | /** |
| | | * @see [MsgType] |
| | |
| | | var max: Double? = null |
| | | } |
| | | |
| | | /** |
| | | * 9. å
³èå å |
| | | * a) pm2.5ãpm10ç¹å«é«ï¼ä¸¤è
å¨åæ
åµä¸åæ¥å±ç¤ºï¼pm2.5å pm10çæ¯éååï¼æ¯éè¶é«ï¼è¶æå¯è½æ¯é¤é¥® |
| | | * b) pm10ç¹å«é«ãpm2.5è¾é«ï¼å¤§é¢ç²æ¬å°æ±¡æï¼åªå±ç¤ºpm10ï¼pm2.5å pm10çæ¯éååï¼å·¥å°ä¸ºä¸» |
| | | * c) VOCè¾é«ï¼åæ¯è®¡ç®pm2.5çé级ï¼å¯è½åå¨åæ¥åé«ï¼æ±½ä¿®ãå æ²¹ç«ï¼, åæ¥è®¡ç®O3æ¯å¦æé«å¼ |
| | | * d) VOCè¾é«ï¼å¤äºå æ²¹ç«ï¼è½¦è¾æ¥å µæ
åµï¼ï¼COä¸è¬è¾é«, åæ¥è®¡ç®O3æ¯å¦æé«å¼ |
| | | * e) 氮氧ååç©ï¼ä¸è¬ç±äºæºå¨è½¦å°¾æ°ï¼åæ¥è®¡ç®CO |
| | | */ |
| | | |
| | | constructor( |
| | | start: BaseRealTimeData, |
| | | end: BaseRealTimeData?, |
| | |
| | | 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 |
| | |
| | | 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 |
| | |
| | | var times: Int? = null |
| | | |
| | | var historyDataList = mutableListOf<DataVo>() |
| | | // å¼å¸¸çæµæ°æ®ï¼å
å«åæ¤å¼å¸¸ä¸ææåçäºå¼å¸¸çæ°æ®å¼ï¼å¯è½ä¸æ¯æ¶é´è¿ç»çæ°æ®ï¼ |
| | | // å¼å¸¸çæµæ°æ®ï¼å
å«å次å¼å¸¸ä¸ææåçäºå¼å¸¸çæ°æ®å¼ï¼å¯è½ä¸æ¯æ¶é´è¿ç»çæ°æ®ï¼ |
| | | var dataList: MutableList<BaseRealTimeData> = mutableListOf() |
| | | var dataVoList: MutableList<DataVo> = mutableListOf() |
| | | |
| | |
| | | // 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 { |
| | |
| | | } |
| | | } |
| | | |
| | | // 3. åç»ä¸æ£ç´¢è¿è·ç¦»æ±¡æåå½¢åºåå
é¨çæ±¡ææº |
| | | val closePolygonTmp = pollutedArea.closePolygon!! |
| | | val closeFb = MapUtil.calFourBoundaries(closePolygonTmp) |
| | | val closeSceneList = sceneInfoRep.findByCoordinateRange(closeFb) |
| | |
| | | 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() |
| | |
| | | // 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) |
| | |
| | | * @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) |
| | | |
| | |
| | | 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}%" |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | fun getByFactorType(type: FactorType?): Float? { |
| | | return when (type) { |
| | | val res = when (type) { |
| | | FactorType.NO2 -> no2 |
| | | FactorType.CO -> co |
| | | FactorType.H2S -> h2s |
| | |
| | | FactorType.NO -> no |
| | | else -> null |
| | | } |
| | | return if (res != null) round(res * 100) / 100 else null |
| | | } |
| | | |
| | | } |
| | |
| | | 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) |
| | | } |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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 |
| | | |
| | | /** |
| | | * æ°æ®å¹³æ» |
| | | * è§£å³åä¸ªæ°æ®ç¸æ¯ååä¸¤ä¸ªæ°æ®çé级è¿å¤§æè¿å°çé®é¢ |
| | | * @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>() |
| | | |
| | | // æå»ºå ååç§°å°AirDataçæ å° |
| | | 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) |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * ä¸å¤çä½äºæ¤å¼çå¼ |
| | | * ä¸å¤çä½äºæ¤å¼çæ°æ® |
| | | */ |
| | | fun getVMin(type: FactorType): Double = when (type) { |
| | | NO -> 1.0 |
| | |
| | | # 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: |
| | |
| | | |
| | | @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) |
| | |
| | | // "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) |
| | | }) |
| | |
| | | // "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) |
| | | }) |
| | |
| | | @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) |