|
|
|
@ -4,31 +4,36 @@ import com.aliyun.tablestore.grid.consts.AttributionEnum;
|
|
|
|
|
import com.aliyun.tablestore.grid.model.GridDataSet;
|
|
|
|
|
import com.aliyun.tablestore.grid.model.GridDataSetMeta;
|
|
|
|
|
import com.aliyun.tablestore.grid.model.grid.Grid4D;
|
|
|
|
|
import com.htfp.weather.download.DownLoadFileInfo;
|
|
|
|
|
import com.htfp.weather.download.gfs.GfsDownloader;
|
|
|
|
|
import com.htfp.weather.download.gfs.GfsLevelsEnum;
|
|
|
|
|
import com.htfp.weather.download.gfs.GfsVariableHeightEnum;
|
|
|
|
|
import com.htfp.weather.download.gfs.GfsVariableIsobaricEnum;
|
|
|
|
|
import com.htfp.weather.griddata.common.TableConfig;
|
|
|
|
|
import com.htfp.weather.griddata.operation.GfsDataFetcher;
|
|
|
|
|
import com.htfp.weather.griddata.common.ValueRange;
|
|
|
|
|
import com.htfp.weather.griddata.operation.GfsDataFetcher;
|
|
|
|
|
import com.htfp.weather.griddata.operation.GfsDataImport;
|
|
|
|
|
import com.htfp.weather.info.Constant;
|
|
|
|
|
import com.htfp.weather.download.gfs.GfsLevelsEnum;
|
|
|
|
|
import com.htfp.weather.utils.DateTimeUtils;
|
|
|
|
|
import com.htfp.weather.utils.MeteoUtils;
|
|
|
|
|
import com.htfp.weather.web.exception.AppException;
|
|
|
|
|
import com.htfp.weather.web.exception.ErrorCode;
|
|
|
|
|
import com.htfp.weather.web.pojo.response.*;
|
|
|
|
|
import com.htfp.weather.web.param.response.*;
|
|
|
|
|
import com.htfp.weather.web.service.surfaceapi.ISurfaceDataService;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
|
import ucar.ma2.Array;
|
|
|
|
|
import ucar.ma2.Index4D;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
import javax.annotation.security.DenyAll;
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
import java.time.Duration;
|
|
|
|
|
import java.time.Instant;
|
|
|
|
|
import java.time.OffsetDateTime;
|
|
|
|
|
import java.time.ZoneOffset;
|
|
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @Author : shiyi
|
|
|
|
@ -37,14 +42,86 @@ import java.util.*;
|
|
|
|
|
*/
|
|
|
|
|
@Service("tablestore-gfs")
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
public class GfsDataServiceImpl implements IUpperDataService, ISurfaceDataService {
|
|
|
|
|
@Resource
|
|
|
|
|
GfsDataFetcher gfsDataFetcher;
|
|
|
|
|
@Resource
|
|
|
|
|
TableConfig tableConfig;
|
|
|
|
|
@Resource
|
|
|
|
|
GfsDownloader gfsDownloader;
|
|
|
|
|
@Resource
|
|
|
|
|
GfsDataImport gfsDataImport;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getDataSource() {
|
|
|
|
|
return dataSource;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String dataSource = "GFS";
|
|
|
|
|
// 地面站数据访问接口
|
|
|
|
|
@Override
|
|
|
|
|
public NowWeatherStatus getNowSurfaceWeatherStatus(double lat, double lon) throws Exception {
|
|
|
|
|
return getNowWeather(GfsLevelsEnum.SURFACE.getCode(), lat, lon);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public TimeSeriesDataset getForecastSeries(double lat, double lon) throws Exception {
|
|
|
|
|
return getForecastSeries(GfsLevelsEnum.SURFACE.getCode(), lat, lon);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override @DenyAll
|
|
|
|
|
public List<SurfaceWeatherWarning> getSurfaceWarning(double lat, double lon) throws Exception {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 下载和导入数据
|
|
|
|
|
public DownloadResult downloadNowAllFile() {
|
|
|
|
|
gfsDownloader.iniTimeSetting();
|
|
|
|
|
List<DownLoadFileInfo> downLoadFileInfoList = gfsDownloader.getFilesInfo();
|
|
|
|
|
List<DownLoadFileInfo> finishedList = gfsDownloader.downloadAll(downLoadFileInfoList);
|
|
|
|
|
List<DownLoadFileInfo> successList = finishedList.stream().filter(DownLoadFileInfo::isDownloadSuccess).collect(Collectors.toList());
|
|
|
|
|
List<DownLoadFileInfo> failedList = finishedList.stream().filter(fileInfo -> !fileInfo.isDownloadSuccess()).collect(Collectors.toList());
|
|
|
|
|
DownloadResult downloadResult = new DownloadResult();
|
|
|
|
|
downloadResult.setSuccessList(successList);
|
|
|
|
|
downloadResult.setFailedList(failedList);
|
|
|
|
|
return downloadResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public DownLoadFileInfo downloadSingleFile(OffsetDateTime offsetDateTime) {
|
|
|
|
|
String targetUtcStr = DateTimeUtils.getUTCDateTime(offsetDateTime).format(DateTimeFormatter.ofPattern(Constant.UTC_TIME_STRING));
|
|
|
|
|
try {
|
|
|
|
|
gfsDownloader.iniTimeSetting();
|
|
|
|
|
List<DownLoadFileInfo> downLoadFileInfoList = gfsDownloader.getFilesInfo(); // TODO 2024/6/12: 可以优化,不用生成24小时所有的文件信息
|
|
|
|
|
for (DownLoadFileInfo downLoadFileInfo : downLoadFileInfoList) {
|
|
|
|
|
if (downLoadFileInfo.getForecastUTCTimeStr().equals(targetUtcStr)) {
|
|
|
|
|
DownLoadFileInfo downloadResult = gfsDownloader.download(downLoadFileInfo);
|
|
|
|
|
if (downloadResult.isDownloadSuccess()) {
|
|
|
|
|
return downloadResult;
|
|
|
|
|
} else {
|
|
|
|
|
throw new AppException(ErrorCode.DOWNLOAD_ERROR, downloadResult.getErrorMsg());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
throw new AppException(ErrorCode.QUERY_TIME_ERROR, ": 请选择当前时间之后24小时范围内的时刻");
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new AppException(ErrorCode.DOWNLOAD_START_ERROR, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ImportResult importData(OffsetDateTime time) throws Exception {
|
|
|
|
|
List<GfsDataImport.ImportFileInfo> finishedList = gfsDataImport.importData(time);
|
|
|
|
|
List<GfsDataImport.ImportFileInfo> successList = finishedList.stream().filter(result -> result.isSuccess()).collect(Collectors.toList());
|
|
|
|
|
List<GfsDataImport.ImportFileInfo> failedList = finishedList.stream().filter(result -> !result.isSuccess()).collect(Collectors.toList());
|
|
|
|
|
ImportResult importResult = new ImportResult();
|
|
|
|
|
importResult.setFailedList(failedList);
|
|
|
|
|
importResult.setSuccessList(successList);
|
|
|
|
|
return importResult;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 从tablestore获取数据
|
|
|
|
|
/**
|
|
|
|
|
* 获取当前时刻的天气状况
|
|
|
|
|
*
|
|
|
|
@ -53,6 +130,7 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
* @param level 高度:9999代表地面,其他代表指定气压高度
|
|
|
|
|
* @return @{@link NowWeatherStatus}
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public NowWeatherStatus getNowWeather(int level, double latitude, double longitude) {
|
|
|
|
|
OffsetDateTime nowTime = OffsetDateTime.now();
|
|
|
|
|
ValueRange<OffsetDateTime> timeRange = new ValueRange<>(Collections.singletonList(nowTime));
|
|
|
|
@ -70,8 +148,10 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
nowWeatherStatus.setLatitude(latitude);
|
|
|
|
|
nowWeatherStatus.setLongitude(longitude);
|
|
|
|
|
return nowWeatherStatus;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
} catch (AppException e) {
|
|
|
|
|
throw e;
|
|
|
|
|
}catch (Exception e) {
|
|
|
|
|
throw new AppException(ErrorCode.TABLESTORE_QUERY_ERROR, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -82,6 +162,7 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
* @param level
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public List<NowWeatherStatus> getNowWeatherByMultiPoint(int level, List<Double> latitude, List<Double> longitude) {
|
|
|
|
|
if (latitude.size() != longitude.size()) {
|
|
|
|
|
throw new AppException(ErrorCode.INDEX_SIZE_ERROR, ": 经纬度数组大小不一致");
|
|
|
|
@ -107,8 +188,10 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
nowWeatherStatusList.add(nowWeatherStatus);
|
|
|
|
|
}
|
|
|
|
|
return nowWeatherStatusList;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
} catch (AppException e) {
|
|
|
|
|
throw e;
|
|
|
|
|
}catch (Exception e) {
|
|
|
|
|
throw new AppException(ErrorCode.TABLESTORE_QUERY_ERROR, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -120,6 +203,7 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
* @param level 高度:9999代表地面,其他代表指定气压高度
|
|
|
|
|
* @return @{@link TimeSeriesDataset}
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public TimeSeriesDataset getForecastSeries(int level, double latitude, double longitude) {
|
|
|
|
|
List<String> variableNames = getVariableNamesInDatabase(level);
|
|
|
|
|
OffsetDateTime nowTime = OffsetDateTime.now();
|
|
|
|
@ -134,8 +218,10 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
);
|
|
|
|
|
final GfsLevelsEnum levelFlag = GfsLevelsEnum.getByCode(level);
|
|
|
|
|
return buildTimeSeriesDatasetInTargetPoint(gridDataSet, level, latitude, longitude, levelFlag);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
} catch (AppException e) {
|
|
|
|
|
throw e;
|
|
|
|
|
}catch (Exception e) {
|
|
|
|
|
throw new AppException(ErrorCode.TABLESTORE_QUERY_ERROR, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -146,7 +232,8 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
* @param level
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
public List<TimeSeriesDataset> getForecastSeriesByMultiPoint(List<Double> latitudeList, List<Double> longitudeList, int level) {
|
|
|
|
|
@Override
|
|
|
|
|
public List<TimeSeriesDataset> getForecastSeriesByMultiPoint(int level, List<Double> latitudeList, List<Double> longitudeList) {
|
|
|
|
|
if (latitudeList.size() != longitudeList.size()) {
|
|
|
|
|
throw new AppException(ErrorCode.INDEX_SIZE_ERROR, ": 经纬度数组大小不一致");
|
|
|
|
|
}
|
|
|
|
@ -168,8 +255,10 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
timeSeriesDatasetList.add(timeSeriesDataset);
|
|
|
|
|
}
|
|
|
|
|
return timeSeriesDatasetList;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
} catch (AppException e) {
|
|
|
|
|
throw e;
|
|
|
|
|
}catch (Exception e) {
|
|
|
|
|
throw new AppException(ErrorCode.TABLESTORE_QUERY_ERROR, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -188,22 +277,30 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
throw new AppException(ErrorCode.VALIDATE_ERROR, variableName + "变量在数据库中不存在");
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
int[] pressureLevels = tableConfig.getPressureList();
|
|
|
|
|
Array array = gfsDataFetcher.getProfileByVariableAndPressure(targetVariable, targetTime, latitude, longitude);
|
|
|
|
|
float[] values = (float[]) array.copyTo1DJavaArray();
|
|
|
|
|
ProfileResponse profileResponse = new ProfileResponse(pressureLevels, values);
|
|
|
|
|
GridDataSet gridDataSet = gfsDataFetcher.getProfileByPressure(Collections.singletonList(targetVariable), targetTime, latitude, longitude);
|
|
|
|
|
float[] values = (float[]) gridDataSet.getVariables().get(targetVariable).toArray().copyTo1DJavaArray();
|
|
|
|
|
ProfileResponse profileResponse = new ProfileResponse();
|
|
|
|
|
profileResponse.setPressureLevels(tableConfig.getPressureList());
|
|
|
|
|
profileResponse.setHeightLevels(tableConfig.getPressureHeightList());
|
|
|
|
|
profileResponse.setValues(values);
|
|
|
|
|
profileResponse.setLatitude(latitude);
|
|
|
|
|
profileResponse.setLongitude(longitude);
|
|
|
|
|
return profileResponse;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
} catch (AppException e) {
|
|
|
|
|
throw e;
|
|
|
|
|
}catch (Exception e) {
|
|
|
|
|
throw new AppException(ErrorCode.TABLESTORE_QUERY_ERROR, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 获取全部变量随气压变化的廓线 (推荐) */
|
|
|
|
|
@Override
|
|
|
|
|
public ProfileDataset getProfileByPressure(OffsetDateTime targetTime, double latitude, double longitude) {
|
|
|
|
|
try {
|
|
|
|
|
List<String> variableNames = getVariableNamesInDatabase(GfsLevelsEnum.UPPER.getCode());
|
|
|
|
|
GfsLevelsEnum levelFlag = GfsLevelsEnum.UPPER;
|
|
|
|
|
List<String> variableNames = getVariableNamesInDatabase(levelFlag.getCode());
|
|
|
|
|
GridDataSet gridDataSet = gfsDataFetcher.getProfileByPressure(variableNames, targetTime, latitude, longitude);
|
|
|
|
|
ProfileDataset profile = buildProfileDataset(gridDataSet, GfsLevelsEnum.UPPER);
|
|
|
|
|
ProfileDataset profile = buildProfileDataset(gridDataSet, levelFlag);
|
|
|
|
|
profile.setLatitude(latitude);
|
|
|
|
|
profile.setLongitude(longitude);
|
|
|
|
|
return profile;
|
|
|
|
@ -214,6 +311,48 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 获取指定变量随高度变化的廓线, 目前只支持风速风向*/
|
|
|
|
|
public ProfileResponse getProfileByVariableAndNearSurfaceHeight(String variableName, OffsetDateTime targetTime, double latitude, double longitude) {
|
|
|
|
|
String targetVariable = GfsVariableHeightEnum.getGfsVariableName(variableName);
|
|
|
|
|
if (targetVariable == null) {
|
|
|
|
|
throw new AppException(ErrorCode.VALIDATE_ERROR, variableName + "变量在数据库中不存在");
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
int[] heightLevels = tableConfig.getHeightList();
|
|
|
|
|
GridDataSet gridDataSet = gfsDataFetcher.getProfileByNearSurfaceHeight(Collections.singletonList(targetVariable), targetTime, latitude, longitude);
|
|
|
|
|
float[] values = (float[]) gridDataSet.getVariables().get(targetVariable).toArray().copyTo1DJavaArray();
|
|
|
|
|
ProfileResponse profileResponse = new ProfileResponse();
|
|
|
|
|
profileResponse.setValues(values);
|
|
|
|
|
profileResponse.setHeightLevels(Arrays.copyOfRange(heightLevels, 1, heightLevels.length));
|
|
|
|
|
profileResponse.setLatitude(latitude);
|
|
|
|
|
profileResponse.setLongitude(longitude);
|
|
|
|
|
return profileResponse;
|
|
|
|
|
} catch (AppException e) {
|
|
|
|
|
throw e;
|
|
|
|
|
}catch (Exception e) {
|
|
|
|
|
throw new AppException(ErrorCode.TABLESTORE_QUERY_ERROR, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 获取全部变量随高度变化的廓线, 目前只支持风速风向*/
|
|
|
|
|
public ProfileDataset getProfileByNearSurfaceHeight(OffsetDateTime targetTime, double latitude, double longitude) {
|
|
|
|
|
try {
|
|
|
|
|
GfsLevelsEnum levelFlag = GfsLevelsEnum.SURFACE;
|
|
|
|
|
List<String> variableNames = new ArrayList<>();
|
|
|
|
|
variableNames.add(GfsVariableHeightEnum.getGfsVariableName("windSpeed"));
|
|
|
|
|
variableNames.add(GfsVariableHeightEnum.getGfsVariableName("wind360"));
|
|
|
|
|
GridDataSet gridDataSet = gfsDataFetcher.getProfileByNearSurfaceHeight(variableNames, targetTime, latitude, longitude);
|
|
|
|
|
ProfileDataset profile = buildProfileDataset(gridDataSet, levelFlag);
|
|
|
|
|
profile.setHeightLevel(Arrays.copyOfRange(tableConfig.getHeightList(), 1, tableConfig.getHeightList().length));
|
|
|
|
|
profile.setLatitude(latitude);
|
|
|
|
|
profile.setLongitude(longitude);
|
|
|
|
|
return profile;
|
|
|
|
|
} catch (AppException e) {
|
|
|
|
|
throw e;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new AppException(ErrorCode.TABLESTORE_QUERY_ERROR, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取指定变量、时间、高度的二维数组数据
|
|
|
|
@ -227,6 +366,7 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
* @param maxLon 最大经度
|
|
|
|
|
* @return @{@link PlaneResponse}
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public PlaneResponse getPlane(OffsetDateTime targetTime, String variableName, int level, double minLat, double maxLat, double minLon, double maxLon) {
|
|
|
|
|
String targetVariable;
|
|
|
|
|
if (GfsLevelsEnum.SURFACE.equals(GfsLevelsEnum.getByCode(level))) {
|
|
|
|
@ -250,8 +390,10 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
variableNames, timeRange, levRange, latRange, lonRange
|
|
|
|
|
).getVariable(targetVariable).toArray();
|
|
|
|
|
return buildPlane(array, minLat, maxLat, minLon, maxLon);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
} catch (AppException e) {
|
|
|
|
|
throw e;
|
|
|
|
|
}catch (Exception e) {
|
|
|
|
|
throw new AppException(ErrorCode.TABLESTORE_QUERY_ERROR, e.getMessage());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
@ -325,6 +467,7 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
Method method = aClass.getDeclaredMethod(setMethodName, aClass.getDeclaredField(variableNameInApi).getType());
|
|
|
|
|
// TODO 2024/6/20: 这里的toArray操作在数据量较大的时候会比较吃内存和cpu
|
|
|
|
|
float[] storage = (float[]) grid4D.toArray().section(
|
|
|
|
|
// levIndexGlobal-origin[1] 获取目标点在子区域中的索引
|
|
|
|
|
new int[]{0, levIndexGlobal-origin[1], latIndexGlobal-origin[2], lonIndexGlobal-origin[3]}, new int[]{tSize, 1, 1, 1}
|
|
|
|
|
).copyTo1DJavaArray();
|
|
|
|
|
method.invoke(result, storage);
|
|
|
|
@ -340,6 +483,17 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
List<String> timeList = getResultTimeStringList(gridDataSet, tSize, origin[0]);
|
|
|
|
|
result.setTime(timeList);
|
|
|
|
|
}
|
|
|
|
|
// 计算地面风力等级
|
|
|
|
|
if (levelFlag == GfsLevelsEnum.SURFACE) {
|
|
|
|
|
float[] windSpeed = result.getWindSpeed();
|
|
|
|
|
if (windSpeed != null) {
|
|
|
|
|
int[] windScale = new int[windSpeed.length];
|
|
|
|
|
for (int i = 0; i < windScale.length; i++) {
|
|
|
|
|
windScale[i] = MeteoUtils.mPerSecond2WindScale(windSpeed[i]);
|
|
|
|
|
}
|
|
|
|
|
result.setWindScale(windScale);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
@ -400,6 +554,11 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
throw new AppException(ErrorCode.RESPONSE_DATA_BUILD_ERROR);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (levelFlag == GfsLevelsEnum.SURFACE) {
|
|
|
|
|
if (result.getWindSpeed() != null) {
|
|
|
|
|
result.setWindScale(MeteoUtils.mPerSecond2WindScale(result.getWindSpeed()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -427,12 +586,16 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
throw new AppException(ErrorCode.RESPONSE_DATA_BUILD_ERROR);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
result.setPressureLevels(tableConfig.getPressureList());
|
|
|
|
|
if (levelFlag == GfsLevelsEnum.UPPER) {
|
|
|
|
|
result.setPressureLevels(tableConfig.getPressureList());
|
|
|
|
|
result.setHeightLevel(tableConfig.getPressureHeightList());
|
|
|
|
|
} else {
|
|
|
|
|
result.setHeightLevel(tableConfig.getHeightList());
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@NotNull
|
|
|
|
|
private static String getVariableNameInApi(GfsLevelsEnum levelFlag, Map.Entry<String, Grid4D> variable) {
|
|
|
|
|
private String getVariableNameInApi(GfsLevelsEnum levelFlag, Map.Entry<String, Grid4D> variable) {
|
|
|
|
|
String variableNameInFile = variable.getKey();
|
|
|
|
|
String variableNameInApi;
|
|
|
|
|
if (GfsLevelsEnum.SURFACE.equals(levelFlag)) {
|
|
|
|
@ -446,41 +609,4 @@ public class GfsDataServiceImpl implements IDataService {
|
|
|
|
|
return variableNameInApi;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Map<String, List> getFutureTimeIndexList(GridDataSetMeta lastGridDataSetMeta) {
|
|
|
|
|
long milli = (long) lastGridDataSetMeta.getAttributes().get(AttributionEnum.REFERENCE_TIME.getName());
|
|
|
|
|
OffsetDateTime refTime = OffsetDateTime.ofInstant(Instant.ofEpochMilli(milli), ZoneOffset.ofHours(0));
|
|
|
|
|
OffsetDateTime currentTime = DateTimeUtils.getUTCDateTime(OffsetDateTime.now());
|
|
|
|
|
if (currentTime.isBefore(refTime)) {
|
|
|
|
|
throw new AppException(ErrorCode.QUERY_TIME_ERROR);
|
|
|
|
|
}
|
|
|
|
|
int startHour = getForecastHourFromTargetTime(currentTime, refTime);
|
|
|
|
|
List<String> forecastHours = lastGridDataSetMeta.getForecastHours();
|
|
|
|
|
List<Integer> iTimeList = new ArrayList<>();
|
|
|
|
|
List<String> timeList = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < forecastHours.size(); i++) {
|
|
|
|
|
int hour = Integer.parseInt(forecastHours.get(i));
|
|
|
|
|
if (hour >= startHour) {
|
|
|
|
|
iTimeList.add(i);
|
|
|
|
|
String timeStr = DateTimeUtils.getLocalZoneDateTime(refTime.plusHours(hour))
|
|
|
|
|
.format(Constant.API_TIME_FORMATTER);
|
|
|
|
|
timeList.add(timeStr);
|
|
|
|
|
}
|
|
|
|
|
if (iTimeList.size() >= 24) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (CollectionUtils.isEmpty(iTimeList) || CollectionUtils.isEmpty(timeList)) {
|
|
|
|
|
throw new AppException(ErrorCode.QUERY_TIME_ERROR);
|
|
|
|
|
}
|
|
|
|
|
Map<String, List> map = new HashMap<>(2);
|
|
|
|
|
map.put("iTimeList", iTimeList);
|
|
|
|
|
map.put("timeList", timeList);
|
|
|
|
|
return map;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int getForecastHourFromTargetTime(OffsetDateTime targetTime, OffsetDateTime refTime) {
|
|
|
|
|
return (int) Duration.between(refTime, targetTime).toHours();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|