|
|
|
@ -81,7 +81,7 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
String gridDataSetId = lastGridDataSetMeta.getGridDataSetId();
|
|
|
|
|
int[] pressureLevels = tableConfig.getPressureList();
|
|
|
|
|
Array array = gfsDataFetcher.getProfile(gridDataSetId, targetVariable, iTime, iLat, iLon);
|
|
|
|
|
float[] values = (float[]) array.getStorage();
|
|
|
|
|
float[] values = (float[]) array.copyTo1DJavaArray();
|
|
|
|
|
return new ProfileResponse(pressureLevels, values);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
@ -117,11 +117,11 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
String gridDataSetId = lastGridDataSetMeta.getGridDataSetId();
|
|
|
|
|
GridDataSet gridDataSet = gfsDataFetcher.getSeries(gridDataSetId, variableNames, iTimes, iLev, iLat, iLon);
|
|
|
|
|
|
|
|
|
|
if (level == SURFACE_LEVEL) {
|
|
|
|
|
return buildTimeSeriesDatasetSurface(timeList, gridDataSet);
|
|
|
|
|
} else {
|
|
|
|
|
return buildTimeSeriesDatasetPressure(timeList, gridDataSet);
|
|
|
|
|
}
|
|
|
|
|
final GfsLevelsEnum levelFlag = GfsLevelsEnum.getByCode(level);
|
|
|
|
|
TimeSeriesDataset timeSeriesDataset = buildTimeSeriesDatasetInTargetPoint(timeList, gridDataSet, 0, 0, 0, levelFlag);
|
|
|
|
|
timeSeriesDataset.setLatitude(latitude);
|
|
|
|
|
timeSeriesDataset.setLongitude(longitude);
|
|
|
|
|
return timeSeriesDataset;
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
@ -152,9 +152,9 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
try {
|
|
|
|
|
String gridDataSetId = lastGridDataSetMeta.getGridDataSetId();
|
|
|
|
|
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.setLatitude(latitude);
|
|
|
|
|
nowWeatherStatus.setLongitude(longitude);
|
|
|
|
@ -198,7 +198,7 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
|
|
|
|
|
String gridDataSetId = lastGridDataSetMeta.getGridDataSetId();
|
|
|
|
|
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,
|
|
|
|
|
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) {
|
|
|
|
|
int minLat = Integer.MIN_VALUE;
|
|
|
|
@ -322,55 +373,58 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
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);
|
|
|
|
|
Grid4D grid4D;
|
|
|
|
|
grid4D = gridDataSet.getVariable(GfsVariableHeightEnum.getGfsVariableName(GfsVariableHeightEnum.TEMP));
|
|
|
|
|
if (grid4D != null) {
|
|
|
|
|
timeSeriesDataset.setTemp((float[]) grid4D.toArray().getStorage());
|
|
|
|
|
}
|
|
|
|
|
grid4D = gridDataSet.getVariable(GfsVariableHeightEnum.getGfsVariableName(GfsVariableHeightEnum.WIND_SPEED));
|
|
|
|
|
if (grid4D != null) {
|
|
|
|
|
timeSeriesDataset.setWindSpeed((float[]) grid4D.toArray().getStorage());
|
|
|
|
|
}
|
|
|
|
|
grid4D = gridDataSet.getVariable(GfsVariableHeightEnum.getGfsVariableName(GfsVariableHeightEnum.WIND360));
|
|
|
|
|
if (grid4D != null) {
|
|
|
|
|
timeSeriesDataset.setWind360((float[]) grid4D.toArray().getStorage());
|
|
|
|
|
/**
|
|
|
|
|
* 构建指定位置的预报数据
|
|
|
|
|
* @param timeList-时间列表
|
|
|
|
|
* @param gridDataSet
|
|
|
|
|
* @param iLevInGrid-目标点在返回的网格中的高度索引
|
|
|
|
|
* @param iLatInGrid-目标点在返回的网格中的高度索引
|
|
|
|
|
* @param iLonInGrid-目标点在返回的网格中的高度索引
|
|
|
|
|
* @param levelFlag-高度层次标记,地面或高空
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private TimeSeriesDataset buildTimeSeriesDatasetInTargetPoint(List<String> timeList, GridDataSet gridDataSet, int iLevInGrid, int iLatInGrid, int iLonInGrid, GfsLevelsEnum levelFlag) {
|
|
|
|
|
TimeSeriesDataset result = new TimeSeriesDataset();
|
|
|
|
|
result.setTime(timeList);
|
|
|
|
|
int tsize = timeList.size();
|
|
|
|
|
// 利用反射构建数据集
|
|
|
|
|
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 iLevInGrid-目标点在返回的网格中的高度索引
|
|
|
|
|
* @param iLatInGrid-目标点在返回的网格中的高度索引
|
|
|
|
|
* @param iLonInGrid-目标点在返回的网格中的高度索引
|
|
|
|
|
* @param levelFlag-高度层次标记,地面或高空
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private NowWeatherStatus buildNowWeatherInTargetPoint(GridDataSet gridDataSet, int iLevInGrid, int iLatInGrid, int iLonInGrid, GfsLevelsEnum levelFlag) {
|
|
|
|
|