查询航线上的预报数据,并优化了代码逻辑,增加复用性

refactor
shiyi 9 months ago
parent 13805a065d
commit c160cca531

@ -106,7 +106,8 @@ public class UpperWeatherController {
} }
} }
int level = multiPointsRequest.getLevel().intValue(); int level = multiPointsRequest.getLevel().intValue();
// List<TimeSeriesDataset> nowWeatherByMultiPoint = gfsDataService.getNowWeatherByMultiPoint(latitudeList, longitudeList, level); List<TimeSeriesDataset> nowWeatherByMultiPoint = gfsDataService.getForecastSeriesByMultiPoint(latitudeList, longitudeList, level);
return Result.success(); return Result.success(nowWeatherByMultiPoint);
} }
} }

@ -25,6 +25,7 @@ public class TimeSeriesDataset {
float[] cloud; float[] cloud;
float[] precip; float[] precip;
public TimeSeriesDataset() {}
public TimeSeriesDataset(int size) { public TimeSeriesDataset(int size) {
time = new ArrayList<>(size); time = new ArrayList<>(size);
temp = new float[size]; temp = new float[size];

@ -81,7 +81,7 @@ public class GfsDataServiceImpl implements IDataService {
String gridDataSetId = lastGridDataSetMeta.getGridDataSetId(); String gridDataSetId = lastGridDataSetMeta.getGridDataSetId();
int[] pressureLevels = tableConfig.getPressureList(); int[] pressureLevels = tableConfig.getPressureList();
Array array = gfsDataFetcher.getProfile(gridDataSetId, targetVariable, iTime, iLat, iLon); Array array = gfsDataFetcher.getProfile(gridDataSetId, targetVariable, iTime, iLat, iLon);
float[] values = (float[]) array.getStorage(); float[] values = (float[]) array.copyTo1DJavaArray();
return new ProfileResponse(pressureLevels, values); return new ProfileResponse(pressureLevels, values);
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -117,11 +117,11 @@ public class GfsDataServiceImpl implements IDataService {
String gridDataSetId = lastGridDataSetMeta.getGridDataSetId(); String gridDataSetId = lastGridDataSetMeta.getGridDataSetId();
GridDataSet gridDataSet = gfsDataFetcher.getSeries(gridDataSetId, variableNames, iTimes, iLev, iLat, iLon); GridDataSet gridDataSet = gfsDataFetcher.getSeries(gridDataSetId, variableNames, iTimes, iLev, iLat, iLon);
if (level == SURFACE_LEVEL) { final GfsLevelsEnum levelFlag = GfsLevelsEnum.getByCode(level);
return buildTimeSeriesDatasetSurface(timeList, gridDataSet); TimeSeriesDataset timeSeriesDataset = buildTimeSeriesDatasetInTargetPoint(timeList, gridDataSet, 0, 0, 0, levelFlag);
} else { timeSeriesDataset.setLatitude(latitude);
return buildTimeSeriesDatasetPressure(timeList, gridDataSet); timeSeriesDataset.setLongitude(longitude);
} return timeSeriesDataset;
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -152,9 +152,9 @@ public class GfsDataServiceImpl implements IDataService {
try { try {
String gridDataSetId = lastGridDataSetMeta.getGridDataSetId(); String gridDataSetId = lastGridDataSetMeta.getGridDataSetId();
GridDataSet gridDataSet = gfsDataFetcher.getSinglePoint(gridDataSetId, variableNames, iTime, iLev, iLat, iLon); GridDataSet gridDataSet = gfsDataFetcher.getSinglePoint(gridDataSetId, variableNames, iTime, iLev, iLat, iLon);
// 每个变量都是0维数组
final GfsLevelsEnum levelFlag = GfsLevelsEnum.getByCode(level);
final GfsLevelsEnum levelFlag = GfsLevelsEnum.getByCode(level);
// 每个变量都是0维数组
NowWeatherStatus nowWeatherStatus = buildNowWeatherInTargetPoint(gridDataSet, 0, 0, 0, levelFlag); NowWeatherStatus nowWeatherStatus = buildNowWeatherInTargetPoint(gridDataSet, 0, 0, 0, levelFlag);
nowWeatherStatus.setLatitude(latitude); nowWeatherStatus.setLatitude(latitude);
nowWeatherStatus.setLongitude(longitude); nowWeatherStatus.setLongitude(longitude);
@ -198,7 +198,7 @@ public class GfsDataServiceImpl implements IDataService {
String gridDataSetId = lastGridDataSetMeta.getGridDataSetId(); String gridDataSetId = lastGridDataSetMeta.getGridDataSetId();
int[] origin = new int[]{iTime, iLev, 0, 0}; int[] origin = new int[]{iTime, iLev, 0, 0};
int[] shape = new int[]{1, 1, tableConfig.getLatSize(), tableConfig.getLatSize()}; int[] shape = new int[]{1, 1, tableConfig.getLatSize(), tableConfig.getLonSize()};
GridDataSet gridDataSet = gfsDataFetcher.queryByTableStore(gridDataSetId, variableNames, GridDataSet gridDataSet = gfsDataFetcher.queryByTableStore(gridDataSetId, variableNames,
origin, shape); origin, shape);
@ -221,6 +221,57 @@ public class GfsDataServiceImpl implements IDataService {
} }
} }
/**
* 24
* @param latitude
* @param longitude
* @param level
* @return
*/
public List<TimeSeriesDataset> getForecastSeriesByMultiPoint(List<Double> latitude, List<Double> longitude, int level) {
GridDataSetMeta lastGridDataSetMeta = null;
try {
lastGridDataSetMeta = queryMeta.getLastGridDataSetMeta();
} catch (Exception e) {
throw new AppException(ErrorCode.DATA_SET_EMPTY, ": " + e.getMessage());
}
if (latitude.size() != longitude.size()) {
throw new AppException(ErrorCode.INDEX_SIZE_ERROR, ": 经纬度数组大小不一致");
}
int pointSize = latitude.size();
List<String> variableNames = getVariableNamesInDatabase(level);
Map<String, List> params = getFutureTimeIndexList(lastGridDataSetMeta);
List<Integer> iTimeList = params.get("iTimeList");
List<String> timeList = params.get("timeList");
int[] iTimes = iTimeList.stream().mapToInt(Integer::valueOf).toArray();
List<Integer> latIndex = latitude.stream().map(this::getLatitudeIndex).collect(Collectors.toList());
List<Integer> lonIndex = longitude.stream().map(this::getLongitudeIndex).collect(Collectors.toList());
int iLev = getLevelIndex(level);
try {
String gridDataSetId = lastGridDataSetMeta.getGridDataSetId();
int[] origin = new int[]{iTimes[0], iLev, 0, 0};
// TODO 2024/6/12: 全域查询量太大,可以考虑只在航线所在区域查询,提升查询效率
int[] shape = new int[]{iTimes.length, 1, tableConfig.getLatSize(), tableConfig.getLonSize()};
GridDataSet gridDataSet = gfsDataFetcher.queryByTableStore(gridDataSetId, variableNames,
origin, shape);
List<TimeSeriesDataset> timeSeriesDatasetList = new ArrayList<>();
for (int i = 0; i < pointSize; i++) {
// NOTE 2024/6/11: build中传入的索引和数据库的查询索引意义不同
final GfsLevelsEnum levelFlag = GfsLevelsEnum.getByCode(level);
TimeSeriesDataset timeSeriesDataset = buildTimeSeriesDatasetInTargetPoint(timeList, gridDataSet, 0, latIndex.get(i), lonIndex.get(i), levelFlag);
timeSeriesDataset.setLatitude(latitude.get(i));
timeSeriesDataset.setLongitude(longitude.get(i));
timeSeriesDatasetList.add(timeSeriesDataset);
}
return timeSeriesDatasetList;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private int[] getMarginIndexByMultiPoint(List<Double> latitude, List<Double> longitude, List<Double> level) { private int[] getMarginIndexByMultiPoint(List<Double> latitude, List<Double> longitude, List<Double> level) {
int minLat = Integer.MIN_VALUE; int minLat = Integer.MIN_VALUE;
@ -322,55 +373,58 @@ public class GfsDataServiceImpl implements IDataService {
return planeResponse; return planeResponse;
} }
private TimeSeriesDataset buildTimeSeriesDatasetPressure(List<String> timeList, GridDataSet gridDataSet) {
TimeSeriesDataset timeSeriesDataset = new TimeSeriesDataset(timeList.size());
timeSeriesDataset.setTime(timeList);
Grid4D grid4D;
grid4D = gridDataSet.getVariable(GfsVariableIsobaricEnum.getGfsVariableName(GfsVariableIsobaricEnum.TEMP));
if (grid4D != null) {
timeSeriesDataset.setTemp((float[]) grid4D.toArray().getStorage());
}
grid4D = gridDataSet.getVariable(GfsVariableIsobaricEnum.getGfsVariableName(GfsVariableIsobaricEnum.WIND_SPEED));
if (grid4D != null) {
timeSeriesDataset.setWindSpeed((float[]) grid4D.toArray().getStorage());
}
grid4D = gridDataSet.getVariable(GfsVariableIsobaricEnum.getGfsVariableName(GfsVariableIsobaricEnum.WIND360));
if (grid4D != null) {
timeSeriesDataset.setWind360((float[]) grid4D.toArray().getStorage());
}
grid4D = gridDataSet.getVariable(GfsVariableIsobaricEnum.getGfsVariableName(GfsVariableIsobaricEnum.CLOUD));
if (grid4D != null) {
timeSeriesDataset.setCloud((float[]) grid4D.toArray().getStorage());
}
return timeSeriesDataset;
}
private TimeSeriesDataset buildTimeSeriesDatasetSurface(List<String> timeList, GridDataSet gridDataSet) { /**
TimeSeriesDataset timeSeriesDataset = new TimeSeriesDataset(timeList.size()); *
timeSeriesDataset.setTime(timeList); * @param timeList-
Grid4D grid4D; * @param gridDataSet
grid4D = gridDataSet.getVariable(GfsVariableHeightEnum.getGfsVariableName(GfsVariableHeightEnum.TEMP)); * @param iLevInGrid-
if (grid4D != null) { * @param iLatInGrid-
timeSeriesDataset.setTemp((float[]) grid4D.toArray().getStorage()); * @param iLonInGrid-
} * @param levelFlag-
grid4D = gridDataSet.getVariable(GfsVariableHeightEnum.getGfsVariableName(GfsVariableHeightEnum.WIND_SPEED)); * @return
if (grid4D != null) { */
timeSeriesDataset.setWindSpeed((float[]) grid4D.toArray().getStorage()); private TimeSeriesDataset buildTimeSeriesDatasetInTargetPoint(List<String> timeList, GridDataSet gridDataSet, int iLevInGrid, int iLatInGrid, int iLonInGrid, GfsLevelsEnum levelFlag) {
} TimeSeriesDataset result = new TimeSeriesDataset();
grid4D = gridDataSet.getVariable(GfsVariableHeightEnum.getGfsVariableName(GfsVariableHeightEnum.WIND360)); result.setTime(timeList);
if (grid4D != null) { int tsize = timeList.size();
timeSeriesDataset.setWind360((float[]) grid4D.toArray().getStorage()); // 利用反射构建数据集
Class<? extends TimeSeriesDataset> aClass = result.getClass();
for (Map.Entry<String, Grid4D> entry : gridDataSet.getVariables().entrySet()) {
String variableNameInFile = entry.getKey();
String variableNameInApi;
if (GfsLevelsEnum.SURFACE.equals(levelFlag)) {
variableNameInApi = GfsVariableHeightEnum.getVariableNameInApi(variableNameInFile);
} else {
variableNameInApi = GfsVariableIsobaricEnum.getVariableNameInApi(variableNameInFile);
}
if (variableNameInApi == null) {
throw new AppException(ErrorCode.NO_SUCH_VARIABLE);
}
try {
Grid4D grid4D = entry.getValue();
String setMethodName = "set" + variableNameInApi.substring(0, 1).toUpperCase() + variableNameInApi.substring(1);
Method method = aClass.getDeclaredMethod(setMethodName, aClass.getDeclaredField(variableNameInApi).getType());
float[] storage = (float[]) grid4D.toArray().section(new int[]{0, iLevInGrid, iLatInGrid, iLonInGrid}, new int[]{tsize, 1, 1, 1}).copyTo1DJavaArray();
method.invoke(result, storage);
} catch (ReflectiveOperationException e) {
throw new AppException(ErrorCode.NO_SUCH_VARIABLE, e);
} catch (Exception e) {
e.printStackTrace();
throw new AppException(ErrorCode.RESPONSE_DATA_BUILD_ERROR, e);
}
} }
return timeSeriesDataset; return result;
} }
/** /**
* *
* @param gridDataSet * @param gridDataSet
* @param iLevInGrid- * @param iLevInGrid-
* @param iLatInGrid- * @param iLatInGrid-
* @param iLonInGrid- * @param iLonInGrid-
* @param levelFlag-
* @return * @return
*/ */
private NowWeatherStatus buildNowWeatherInTargetPoint(GridDataSet gridDataSet, int iLevInGrid, int iLatInGrid, int iLonInGrid, GfsLevelsEnum levelFlag) { private NowWeatherStatus buildNowWeatherInTargetPoint(GridDataSet gridDataSet, int iLevInGrid, int iLatInGrid, int iLonInGrid, GfsLevelsEnum levelFlag) {

Loading…
Cancel
Save