添加地面风力等级

refactor
shiyi 9 months ago
parent 2ec081e80f
commit 4520c5c24d

@ -2,6 +2,7 @@ package com.htfp.weather.utils;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.TimeZone;
/**
* @Author : shiyi
@ -11,6 +12,8 @@ import java.time.format.DateTimeFormatter;
public class DateTimeUtils {
public static final String DEFAULT_PATTERN = "yyyy-MM-dd'T'HH:mm:ssxxx";
public static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern(DEFAULT_PATTERN);
public static final ZoneOffset DEFAULT_ZONE_OFFSET = ZoneOffset.ofHours(TimeZone.getDefault().getRawOffset()/3600000);
public static final ZoneId DEFAULT_ZONE_ID = ZoneId.systemDefault();
/**
* ,
*
@ -132,4 +135,13 @@ public class DateTimeUtils {
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());
return zonedDateTime.format(DEFAULT_FORMATTER);
}
/** 将OffsetDateTime对象转换为指定时区*/
public static OffsetDateTime offsetDateTimeToTargetZone(OffsetDateTime offsetDateTime, int ZoneTo) {
return offsetDateTime.withOffsetSameInstant(ZoneOffset.ofHours(ZoneTo));
}
/** 将OffsetDateTime对象转换为系统时区*/
public static OffsetDateTime offsetDateTimeToSystemZone(OffsetDateTime offsetDateTime) {
return offsetDateTime.withOffsetSameInstant(DEFAULT_ZONE_OFFSET);
}
}

@ -1,9 +0,0 @@
package com.htfp.weather.utils;
/**
* @Author : shiyi
* @Date : 2024/4/25 18:31
* @Description : https://www.jianshu.com/p/3b269082cbbb
*/
public class DownloadUtils {
}

@ -8,7 +8,7 @@ import java.util.Arrays;
/**
* @Author : shiyi
* @Date : 2024/1/24 11:32
* @Description :
* @Description :
*/
public class MeteoUtils {
@ -30,6 +30,54 @@ public class MeteoUtils {
return kph / 3.6;
}
/**
*
* @param kph (km/h)
* @return
*/
public static int kmPerHour2WindScale(double kph) {
return mPerSecond2WindScale(kmPerHour2mPerSecond(kph));
}
/**
*
* @param mps (m/s)
* @return
*/
public static int mPerSecond2WindScale(double mps) {
if (mps < 0) {
throw new IllegalArgumentException("风力等级计算错误风速不能为负值");
}
if (mps <= 0.2) {
return 0;
} else if (mps <= 1.5) {
return 1;
} else if (mps <= 3.3) {
return 2;
} else if (mps <= 5.4) {
return 3;
} else if (mps <= 7.9) {
return 4;
} else if (mps <= 10.7) {
return 5;
} else if (mps <= 13.8) {
return 6;
} else if (mps <= 17.1) {
return 7;
} else if (mps <= 20.7) {
return 8;
} else if (mps <= 24.4) {
return 9;
} else if (mps <= 28.4) {
return 10;
} else if (mps <= 32.6) {
return 11;
} else if (mps <= 36.9){
return 12;
} else {
return 13;
}
}
// public static double pressure2Height(double pressure) {
//
// }
@ -62,7 +110,7 @@ public class MeteoUtils {
//
// @Deprecated
// public static Array calculateWindSpeed(Array u, Array v) {
// // // FIXME 2024/5/13: io耗时太多对于一般大小的矩阵不使
// // note 2024/5/13: io耗时太多对于一般大小的矩阵不实
// uvValid(u, v);
// try (NDManager manager = NDManager.newBaseManager()) {
// int[] shapeArray = u.getShape();

@ -17,7 +17,7 @@ public class NowWeatherStatus {
Float windSpeed; // 风速m/s
Float wind360; // 风向360角度
// String windDir; // 风向, 文字描述,如“西北风”
// String windScale; // 风力等级
Integer windScale; // 风力等级
Float humidity; // 相对湿度 %
// Float pressure; // 大气压强,默认单位:百帕
Float cloud; // 云量

@ -15,11 +15,9 @@ public class ProfileDataset {
// int[ pressureHeight;
double latitude;
double longitude;
float[] temp;
float[] windSpeed;
float[] wind360;
// List<String> windScale;
float[] humidity;
// float[] pressure;
float[] cloud;
@ -33,7 +31,6 @@ public class ProfileDataset {
temp = new float[size];
windSpeed = new float[size];
wind360 = new float[size];
// windScale = new float[size;
humidity = new float[size];
// pressure = new float[size;
cloud = new float[size];

@ -19,7 +19,7 @@ public class TimeSeriesDataset {
float[] temp;
float[] windSpeed;
float[] wind360;
// List<String> windScale;
int[] windScale;
float[] humidity;
// float[] pressure;
float[] cloud;
@ -31,7 +31,7 @@ public class TimeSeriesDataset {
temp = new float[size];
windSpeed = new float[size];
wind360 = new float[size];
// windScale = new float[size;
windScale = new int[size];
humidity = new float[size];
// pressure = new float[size;
cloud = new float[size];

@ -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();
}
}

@ -13,6 +13,7 @@ import com.htfp.weather.web.pojo.response.NowWeatherStatus;
import com.htfp.weather.web.pojo.response.SurfaceWeatherWarning;
import com.htfp.weather.web.pojo.response.TimeSeriesDataset;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.time.OffsetDateTime;
@ -30,11 +31,8 @@ import static com.htfp.weather.utils.HttpClientUtils.sendGet;
*/
@Service("caiyun") @Slf4j
public class CaiYunServiceImpl implements ISurfaceDataService {
private final String key = "Tc9tgOYr5jlPPlEw";
private final HashMap<String, String> variableNameMap =
new HashMap<String, String>() {{
}};
@Value("${caiyun.key}")
private String key;
static final String STATUS_OK = "ok";
public <T extends CaiYunBaseResponse> T caiYunRequest(String url, HashMap<String, String> params, Class<T> responseClass) {
params.put("units", "metric:v2");
@ -126,6 +124,7 @@ public class CaiYunServiceImpl implements ISurfaceDataService {
nowWeatherStatus.setTemp(realtime.getTemperature());
nowWeatherStatus.setWindSpeed((float) MeteoUtils.kmPerHour2mPerSecond(realtime.getWind().getSpeed()));
nowWeatherStatus.setWind360(realtime.getWind().getDirection());
nowWeatherStatus.setWindScale(MeteoUtils.kmPerHour2WindScale(realtime.getWind().getSpeed()));
nowWeatherStatus.setHumidity(realtime.getHumidity());
nowWeatherStatus.setCloud(realtime.getCloudrate());

@ -178,13 +178,13 @@ public class HeFengServiceImpl implements ISurfaceDataService {
private NowWeatherStatus buildNowSurfaceWeatherStatus(HeFengNow now) {
NowWeatherStatus nowWeatherStatus = new NowWeatherStatus();
processHeFengData(now);
nowWeatherStatus.setTime(now.getObsTime());
nowWeatherStatus.setTime(DateTimeUtils.offsetDateTimeToSystemZone(OffsetDateTime.parse(now.getObsTime())).format(Constant.API_TIME_FORMATTER));
nowWeatherStatus.setWeatherText(now.getText());
nowWeatherStatus.setTemp(now.getTemp());
nowWeatherStatus.setWindSpeed(now.getWindSpeed());
nowWeatherStatus.setWind360(now.getWind360());
// nowSurfaceWeatherStatus.setWindDir(now.getWindDir());
// nowSurfaceWeatherStatus.setWindScale(now.getWindScale());
// nowWeatherStatus.setWindDir(now.getWindDir());
nowWeatherStatus.setWindScale(MeteoUtils.mPerSecond2WindScale(now.getWindSpeed()));
nowWeatherStatus.setHumidity(now.getHumidity());
// nowWeatherStatus.setPressure(now.getPressure());
nowWeatherStatus.setCloud(now.getCloud());

Loading…
Cancel
Save