|
|
|
@ -4,27 +4,26 @@ 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.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.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 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 java.lang.reflect.Method;
|
|
|
|
|
import java.time.Duration;
|
|
|
|
|
import java.time.Instant;
|
|
|
|
|
import java.time.OffsetDateTime;
|
|
|
|
|
import java.time.ZoneOffset;
|
|
|
|
@ -325,6 +324,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 +340,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 +411,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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -446,41 +462,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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|