package com.moral.api.service.impl; import com.fasterxml.jackson.databind.ObjectMapper; import com.moral.api.entity.HistorySecondRadar; import com.moral.api.mapper.HistorySecondRadarMapper; import com.moral.api.pojo.query.radar.RadarListCond; import com.moral.api.pojo.vo.radar.HistorySecondRadarListVo; import com.moral.api.pojo.vo.radar.RadarListVo; import com.moral.api.service.HistorySecondRadarService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; /** *

* 服务实现类 *

* * @author moral * @since 2026-05-14 */ @Service public class HistorySecondRadarServiceImpl extends ServiceImpl implements HistorySecondRadarService { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final double HEIGHT_INTERVAL = 7.5; @Override public RadarListVo radarList(RadarListCond cond) { RadarListVo radarListVo = new RadarListVo(); List time = new ArrayList<>(); List> pm25 = new ArrayList<>(); List> pm10 = new ArrayList<>(); List highList = buildHighList(cond.getHigh2()); List highList1 = buildHighList(cond.getHigh1()); List list = this.baseMapper.listRadar(cond); for (HistorySecondRadarListVo row : list) { time.add(row.getTimeStr()); double[] pm25Values = parseValues(row.getRadarData(), "a34004-Avg"); double[] pm10Values = parseValues(row.getRadarData(), "a34002-Avg"); pm25.add(buildPointList(pm25Values, highList.size(),highList1.size())); pm10.add(buildPointList(pm10Values, highList.size(),highList1.size())); } radarListVo.setPm25(pm25); radarListVo.setTime(time); radarListVo.setPm10(pm10); /* List> pm25 = new ArrayList<>(); List> pm10 = new ArrayList<>(); for(HistorySecondRadarListVo ot : list){ pm10.add(convertSingleRecordToJson(ot.getRadarDataPm10(),cond.getHigh1(),cond.getHigh2())); pm25.add(convertSingleRecordToJson(ot.getRadarDataPm25(),cond.getHigh1(),cond.getHigh2())); time.add(ot.getTimeStr()); } radarListVo.setPm25(pm25); radarListVo.setTime(time); radarListVo.setPm10(pm10);*/ return radarListVo; } private static List buildPointList(double[] values, int pointCount, int minPointCount) { List pointList = new ArrayList(pointCount); int count = Math.min(pointCount, values.length); int minCount = Math.min(minPointCount, values.length); for (int i = minCount; i < count; i++) { pointList.add(new double[]{values[i]}); } return pointList; } private static List buildHighList(int MAX_HEIGHT) { List highList = new ArrayList(); int count = (int) (MAX_HEIGHT / HEIGHT_INTERVAL) + 1; for (int i = 0; i < count; i++) { highList.add(formatHeight(i * HEIGHT_INTERVAL)); } return highList; } private static double[] parseValues(String json, String key) { if (json == null) { return new double[0]; } String keyToken = "\"" + key + "\":"; int keyIndex = json.indexOf(keyToken); if (keyIndex < 0) { return new double[0]; } int bracketStart = json.indexOf('[', keyIndex + keyToken.length()); int bracketEnd = json.indexOf(']', bracketStart + 1); if (bracketStart < 0 || bracketEnd < 0 || bracketEnd - bracketStart <= 1) { return new double[0]; } String body = json.substring(bracketStart + 1, bracketEnd).trim(); if (body.isEmpty()) { return new double[0]; } String[] parts = body.split(","); double[] values = new double[parts.length]; for (int i = 0; i < parts.length; i++) { values[i] = Double.parseDouble(parts[i].trim()); } return values; } private static String formatHeight(double height) { return BigDecimal.valueOf(height).stripTrailingZeros().toPlainString(); } private List convertSingleRecordToJson(String rawData,int high1,int high2){ if (rawData == null || rawData.isEmpty()) { return new ArrayList<>(); } try { // 3. 分割字符串 String[] valuesStr = rawData.split("\\*"); // 4. 预分配列表大小,假设约2000个数据,减少扩容 List seriesData = new ArrayList<>(valuesStr.length); for (int i = 10; i < valuesStr.length; i++) { // 简单的空值检查,避免 NumberFormatException if (valuesStr[i].isEmpty()) continue; double height = (i + 1) * HEIGHT_INTERVAL; if(height> high1 && height < high2){ double pm25Value = Double.parseDouble(valuesStr[i]); pm25Value = new BigDecimal(Double.toString(pm25Value)) .setScale(1, RoundingMode.HALF_UP) .doubleValue(); // 使用 double 数组存储 [浓度, 高度],比对象更节省内存 seriesData.add(new double[]{pm25Value, height}); } } // 5. 序列化为 JSON return seriesData; } catch (Exception e) { // 生产环境中建议记录日志,而不是打印堆栈 System.err.println("处理数据出错: " + e.getMessage()); return new ArrayList<>(); } } }