package com.flightfeather.uav.biz.mission
|
|
import com.flightfeather.uav.common.net.AMapService
|
import com.flightfeather.uav.common.utils.MapUtil
|
import com.flightfeather.uav.domain.entity.BaseRealTimeData
|
import com.flightfeather.uav.domain.entity.avg
|
|
/**
|
* 走航任务计算工具
|
* @date 2025/8/21
|
* @author feiyu02
|
*/
|
object MissionUtil {
|
|
/**
|
* 计算里程数
|
*/
|
fun calKilometres(data: List<BaseRealTimeData>): Double {
|
var distance = .0
|
var lastValidPoint: BaseRealTimeData? = null
|
|
for (point in data) {
|
// 跳过无效点
|
if (point.longitude == null || point.latitude == null) continue
|
|
// 如果存在上一个有效点,则计算距离
|
lastValidPoint?.let { prevPoint ->
|
distance += MapUtil.getDistance(
|
prevPoint.longitude!!.toDouble(),
|
prevPoint.latitude!!.toDouble(),
|
point.longitude!!.toDouble(),
|
point.latitude!!.toDouble()
|
)
|
}
|
|
// 更新上一个有效点
|
lastValidPoint = point
|
}
|
return distance
|
}
|
|
/**
|
* 根据轨迹点计算所属区域(乡镇+街道)
|
* @param data 走航轨迹点列表
|
* @return 区域名称(乡镇+街道),若无法计算则返回null
|
*/
|
@Suppress("UNCHECKED_CAST")
|
fun calRegion(data: List<BaseRealTimeData>): String? {
|
// 计算所有轨迹点的平均坐标(中心点)
|
val avgData = data.avg()
|
val pair = avgData.longitude?.toDouble() to avgData.latitude?.toDouble()
|
// 若平均坐标无效则返回null
|
if (pair.first == null || pair.second == null) return null
|
// 将WGS84坐标转换为GCJ02坐标后进行逆地理编码获取地址信息
|
val address = AMapService.reGeo(MapUtil.wgs84ToGcj02(pair as Pair<Double, Double>))
|
// 返回乡镇和街道名称组合
|
return address.township
|
}
|
|
/**
|
* 数据清洗
|
* 1. 修复由于硬件设备卡顿导致的数据采样时间不变问题,采用自动累加数据周期的方式修改采样时间
|
* @param data 原始数据列表
|
* @param period 数据周期,单位:秒
|
* @return 清洗后需要修改的数据列表
|
*/
|
fun dataClean(dataList: List<BaseRealTimeData>, period: Long): List<BaseRealTimeData> {
|
val cleanedData = mutableListOf<BaseRealTimeData>()
|
var errorData: BaseRealTimeData? = null
|
dataList.forEachIndexed { index, data ->
|
if (index == 0) {
|
return@forEachIndexed
|
}
|
val lastOne = dataList[index - 1]
|
if (errorData == null) {
|
if (data.dataTime!!.time == lastOne.dataTime!!.time) {
|
data.dataTime?.time = lastOne.dataTime?.time!!.plus(period * 1000)
|
cleanedData.add(data)
|
errorData = lastOne
|
}
|
} else {
|
if (data.dataTime!!.time == errorData!!.dataTime!!.time) {
|
data.dataTime?.time = lastOne.dataTime?.time!!.plus(period * 1000)
|
cleanedData.add(data)
|
} else {
|
errorData = null
|
}
|
}
|
}
|
return cleanedData
|
}
|
}
|