| | |
| | | package com.flightfeather.uav.biz.satellite |
| | | |
| | | import com.flightfeather.uav.common.utils.MapUtil |
| | | import com.flightfeather.uav.domain.entity.BaseRealTimeData |
| | | import com.flightfeather.uav.domain.entity.GridCell |
| | | import com.flightfeather.uav.domain.entity.GridData |
| | | import com.flightfeather.uav.domain.entity.GridDataDetail |
| | | import com.flightfeather.uav.domain.entity.* |
| | | import org.springframework.beans.BeanUtils |
| | | import kotlin.math.PI |
| | | import kotlin.math.sqrt |
| | | |
| | |
| | | /** |
| | | * 根据正方形网格中心点坐标,计算4个顶点坐标 |
| | | * 网格中心点坐标按照从左到右、从上到下的顺序排列 |
| | | * @date 2025.1.8 |
| | | * @param points 网格中心坐标点数组 |
| | | * @return 网格4个顶点经纬度坐标 |
| | | */ |
| | | fun calGridVertex(points: List<Pair<Double, Double>>): List<GridVertex> { |
| | | // 网格少于2个,则无法绘制 |
| | |
| | | /** |
| | | * 拆分网格为细分网格,所有网格应该是相同边长的正方形 |
| | | * 根据相似矩形的原理,可以分别按比例得到每个细分网格的经纬度 |
| | | * @date 2025.1.17 |
| | | * @param gridCellList 原始网格数组 |
| | | * @param scale 拆分的系数,例如 2,表示将原有网格按边长的 1/2 拆分成 2 * 2 的4个网格 |
| | | * @param groupId 细分后的网格所属的网格组id |
| | | * @return |
| | | * @return 细分网格 |
| | | */ |
| | | fun splitGrid(gridCellList: List<GridCell?>, scale: Int, groupId:Int): List<GridCell?> { |
| | | if (scale <= 0) throw IllegalArgumentException("网格拆分的数量不能小于1") |
| | |
| | | |
| | | /** |
| | | * 拆分数据,将原始卫星网格遥测数据映射到对应细分网格上 |
| | | * @param subGridCellList 细分网格, 按照 |
| | | * @date 2025.2.7 |
| | | * @param subGridCellList 细分网格 |
| | | * @param subGridData 细分网格对应的数据索引 |
| | | * @param originGridDataDetailList 细分网格所属网格的原始网格数据 |
| | | * @return 映射后的细分网格遥测数据 |
| | | */ |
| | | fun splitData( |
| | | subGridCellList: List<GridCell?>, subGridData: GridData, originGridDataDetailList: List<GridDataDetail?> |
| | |
| | | } |
| | | |
| | | /** |
| | | * 数据融合 |
| | | * 走航数据和卫星网格融合 |
| | | * 数据融合采用均值方式统计(暂时) |
| | | * @date 2025.2.7 |
| | | * @param realTimeDataList 待融合的走航监测数据 |
| | | * @param gridData 融合后的数据组索引 |
| | | * @param gridCellList 待融合的卫星网格 |
| | | * @return 融合后的网格监测数据 |
| | | */ |
| | | fun dataFusion(realTimeDataList:List<BaseRealTimeData>, gridData: GridData, gridCellList: List<GridCell?>) { |
| | | fun dataFusion( |
| | | realTimeDataList: List<BaseRealTimeData>, |
| | | gridData: GridData?, |
| | | gridCellList: List<GridCell?>, |
| | | ): List<GridDataDetail> { |
| | | // 遍历走航监测数据,计算每个点所在网格 |
| | | val dataMap = mutableMapOf<GridCell, MutableList<BaseRealTimeData>>() |
| | | realTimeDataList.forEach { |
| | | if (it.longitude == null || it.latitude == null) return@forEach |
| | | |
| | | SatelliteGridUtil.searchGirdIn(it.longitude!!.toDouble() to it.latitude!!.toDouble(), gridCellList) |
| | | ?.let { cell -> |
| | | if (!dataMap.containsKey(cell)) { |
| | | dataMap[cell] = mutableListOf() |
| | | } |
| | | dataMap[cell]?.add(it) |
| | | } |
| | | } |
| | | |
| | | // 统计每个网格中的均值 |
| | | // Fixme 2025.2.20 暂时默认以均值方式统计,后续调整为多种方式并支持用户选择 |
| | | val gridDataDetailList = mutableListOf<GridDataDetail>() |
| | | dataMap.forEach { (k, v) -> |
| | | val avgData = v.avg() |
| | | val dataDetail = GridDataDetail() |
| | | BeanUtils.copyProperties(avgData, dataDetail) |
| | | dataDetail.apply { |
| | | dataId = gridData?.id |
| | | groupId = k.groupId |
| | | cellId = k.cellIndex |
| | | // no2 = avgData.no2 |
| | | // co = avgData.co |
| | | // h2s = avgData.h2s |
| | | // so2 = avgData.so2 |
| | | // o3 = avgData.o3 |
| | | // pm25 = avgData.pm25 |
| | | // pm10 = avgData.pm10 |
| | | // temperature = avgData.temperature |
| | | // humidity = avgData.humidity |
| | | // voc = avgData.voc |
| | | // noi = avgData.noi |
| | | // no = avgData.no |
| | | // windSpeed |
| | | // windDirection |
| | | rank |
| | | } |
| | | gridDataDetailList.add(dataDetail) |
| | | } |
| | | |
| | | gridDataDetailList.sortBy { it.pm25 } |
| | | gridDataDetailList.forEachIndexed { index, d -> |
| | | d.rank = index + 1 |
| | | } |
| | | gridDataDetailList.sortBy { it.cellId } |
| | | |
| | | return gridDataDetailList |
| | | } |
| | | |
| | | |
| | | |
| | | } |