diff --git a/weather-service/src/main/java/com/htfp/weather/griddata/common/TableConfig.java b/weather-service/src/main/java/com/htfp/weather/griddata/common/TableConfig.java index 6eea121..be5f7ad 100644 --- a/weather-service/src/main/java/com/htfp/weather/griddata/common/TableConfig.java +++ b/weather-service/src/main/java/com/htfp/weather/griddata/common/TableConfig.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.htfp.weather.download.gfs.GfsDataConfig; import com.htfp.weather.utils.JSONUtils; +import com.htfp.weather.utils.MeteoUtils; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; @@ -18,6 +19,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.NoSuchFileException; +import java.util.Arrays; import java.util.List; @Data @Component @Slf4j @@ -51,6 +53,7 @@ public class TableConfig { public double[] latList; @JsonIgnore public int[] pressureList; + public int[] pressureHeightList; @JsonIgnore public int[] heightList; // @JsonIgnore @@ -136,6 +139,8 @@ public class TableConfig { private void initLevList() { pressureList = dataConfig.getPressureLevels(); + // NOTE 2024/7/4: 气压对应的海拔高度,注意不是离地高度 + pressureHeightList = Arrays.stream(pressureList).map(x-> (int) MeteoUtils.pressure2Elevation(x)).toArray(); heightList = dataConfig.getHeightLevels(); // this.levSize = Math.max(pressureList.length, heightList.length); } diff --git a/weather-service/src/main/java/com/htfp/weather/griddata/operation/GfsDataFetcher.java b/weather-service/src/main/java/com/htfp/weather/griddata/operation/GfsDataFetcher.java index 9c4a5f7..65dc9f9 100644 --- a/weather-service/src/main/java/com/htfp/weather/griddata/operation/GfsDataFetcher.java +++ b/weather-service/src/main/java/com/htfp/weather/griddata/operation/GfsDataFetcher.java @@ -33,7 +33,7 @@ import java.util.stream.Collectors; /** * @Author : shiyi * @Date : 2024/1/22 13:53 - * @Description : 根据维度信息获取数据 + * @Description : 根据维度信息获取数据, 将物理坐标转换为数组索引,与数据库交互 */ @Slf4j @Component @DependsOn({"tableStoreConf", "tableConfig"}) @@ -132,14 +132,15 @@ public class GfsDataFetcher extends BaseTableOperation { } /** - * 获取指定变量在某位置随高度的分布 - * @param variable 变量名 - * @param iLat 纬度索引 - * @param iLon 经度索引 - * @return {@link Array} + * 获取指定变量在某位置随气压的分布 + * @param variableNameList 变量名列表 + * @param targetTime 目标时刻 + * @param latitude 经度 + * @param longitude 纬度 + * @return {@link GridDataSet} * @throws Exception */ - public Array getProfileByVariableAndPressure(String variableName, OffsetDateTime targetTime, double latitude, double longitude) throws Exception { + public GridDataSet getProfileByPressure(List variableNameList, OffsetDateTime targetTime, double latitude, double longitude) throws Exception { lastGridDataSetMeta = getLastGridDataSetMeta(); GridDataFetcher fetcher = tableStoreGrid.getDataFetcher(lastGridDataSetMeta); int iTime = getTargetTimeIndex(targetTime); @@ -148,25 +149,27 @@ public class GfsDataFetcher extends BaseTableOperation { int[] origin = new int[]{iTime, 0, iLat, iLon}; int[] shape = new int[]{1,tableConfig.levSize, 1, 1}; // TODO 2024/6/17: - fetcher.setVariablesToGet(Collections.singletonList(variableName)); + fetcher.setVariablesToGet(variableNameList); fetcher.setOriginShape(origin, shape); - GridDataSet gridDataSet = fetcher.fetch(); - Array array = gridDataSet.getVariable(variableName).toArray(); - return array; + return fetcher.fetch(); } - public GridDataSet getProfileByPressure(List variableNameList, OffsetDateTime targetTime, double latitude, double longitude) throws Exception { + + /**获取变量随近地面高度的分布(目前只针对风速风向)*/ + public GridDataSet getProfileByNearSurfaceHeight(List variableNameList, OffsetDateTime targetTime, double latitude, double longitude) throws Exception { lastGridDataSetMeta = getLastGridDataSetMeta(); GridDataFetcher fetcher = tableStoreGrid.getDataFetcher(lastGridDataSetMeta); int iTime = getTargetTimeIndex(targetTime); int iLat= getLatitudeIndex(latitude); int iLon = getLongitudeIndex(longitude); int[] origin = new int[]{iTime, 0, iLat, iLon}; - int[] shape = new int[]{1,tableConfig.levSize, 1, 1}; + //TODO NOTE 2024/7/4: 目前仅有风速支持近地面多个高度, 且只有10,20,30,40,50,80,100这7个高度,2m高度只针对temp和humidity;nc文件本身高度坐标就有很多种,难以统一到数据库中 + int[] shape = new int[]{1,tableConfig.heightList.length - 1, 1, 1}; // heightList.length - 1 去掉2m高度 // TODO 2024/6/17: fetcher.setVariablesToGet(variableNameList); fetcher.setOriginShape(origin, shape); return fetcher.fetch(); } + /** * 获取指定变量在某经纬高处的预报序列 * @param dataSetId 数据集ID diff --git a/weather-service/src/main/java/com/htfp/weather/utils/MeteoUtils.java b/weather-service/src/main/java/com/htfp/weather/utils/MeteoUtils.java index e360682..606c830 100644 --- a/weather-service/src/main/java/com/htfp/weather/utils/MeteoUtils.java +++ b/weather-service/src/main/java/com/htfp/weather/utils/MeteoUtils.java @@ -78,13 +78,16 @@ public class MeteoUtils { } } - // public static double pressure2Height(double pressure) { - // - // } - // - // public static double height2Pressure(double pressure) { - // - // } + + /** + * 根据标准状况根据气压计算海拔高度(不考虑温度),仅供参考 + * @param currentPressure 当前大气压(hPa) + * @return 高度 + */ + public static double pressure2Elevation(double currentPressure) { + double referencePressure = 101.325; // 参考大气压(单位:kPa) + return 44330 * (1 - Math.pow(currentPressure/10. / referencePressure, 1 / 5.255)); + } /** * @param array 降水率 (kg/m^2/s) * @return mm/h diff --git a/weather-service/src/main/java/com/htfp/weather/web/controller/SurfaceWeatherController.java b/weather-service/src/main/java/com/htfp/weather/web/controller/SurfaceWeatherController.java index 8fcaf76..520bd4b 100644 --- a/weather-service/src/main/java/com/htfp/weather/web/controller/SurfaceWeatherController.java +++ b/weather-service/src/main/java/com/htfp/weather/web/controller/SurfaceWeatherController.java @@ -37,11 +37,14 @@ public class SurfaceWeatherController { double lat = position2D.getLatitude(); double lon = position2D.getLongitude(); log.info("[data-server] 地面实时气象信息查询 start: param={}", position2D); - NowWeatherStatus nowWeatherStatus = surfaceDataService.getNowSurfaceWeatherStatus(lat, lon); - nowWeatherStatus.setLatitude(lat); - nowWeatherStatus.setLongitude(lon); - log.info("[data-server] 地面实时气象信息查询 end"); - return Result.success(nowWeatherStatus); + try { + NowWeatherStatus nowWeatherStatus = surfaceDataService.getNowSurfaceWeatherStatus(lat, lon); + nowWeatherStatus.setLatitude(lat); + nowWeatherStatus.setLongitude(lon); + return Result.success(nowWeatherStatus); + } finally { + log.info("[data-server] 地面实时气象信息查询 end"); + } } @PostMapping("/querySurfaceForecast") @@ -49,11 +52,14 @@ public class SurfaceWeatherController { double lat = position2D.getLatitude(); double lon = position2D.getLongitude(); log.info("[data-server] 地面24小时预报结果查询 start: param={}", position2D); - TimeSeriesDataset forecastSeries = surfaceDataService.getForecastSeries(lat, lon); - forecastSeries.setLatitude(lat); - forecastSeries.setLongitude(lon); - log.info("[data-server] 地面24小时预报结果查询"); - return Result.success(forecastSeries); + try { + TimeSeriesDataset forecastSeries = surfaceDataService.getForecastSeries(lat, lon); + forecastSeries.setLatitude(lat); + forecastSeries.setLongitude(lon); + return Result.success(forecastSeries); + } finally { + log.info("[data-server] 地面24小时预报结果查询"); + } } @PostMapping ("/queryWeatherWarning") @@ -61,10 +67,13 @@ public class SurfaceWeatherController { double lat = position2D.getLatitude(); double lon = position2D.getLongitude(); log.info("[data-server] 地面气象预警信息查询 start: param={}", position2D); - // List warning = surfaceDataService.getSurfaceWarning(lat, lon); - List warning = cmaService.getSurfaceWarning(lat, lon); - log.info("[data-server] 地面气象预警信息查询 end"); - return Result.success(warning); + try { + // List warning = surfaceDataService.getSurfaceWarning(lat, lon); + List warning = cmaService.getSurfaceWarning(lat, lon); + return Result.success(warning); + } finally { + log.info("[data-server] 地面气象预警信息查询 end"); + } } } diff --git a/weather-service/src/main/java/com/htfp/weather/web/controller/UpperWeatherController.java b/weather-service/src/main/java/com/htfp/weather/web/controller/UpperWeatherController.java index beecc36..8123fb7 100644 --- a/weather-service/src/main/java/com/htfp/weather/web/controller/UpperWeatherController.java +++ b/weather-service/src/main/java/com/htfp/weather/web/controller/UpperWeatherController.java @@ -101,10 +101,13 @@ public class UpperWeatherController { String variableName = profileRequest.getVariableName(); double latitude = profileRequest.getLatitude(); double longitude = profileRequest.getLongitude(); - log.info("[data-server] 高度廓线查询 start: param={}", profileRequest); - ProfileResponse profileResponse = gfsDataService.getProfileByVariableAndPressure(variableName, utcDateTime, latitude, longitude); - log.info("[data-server] 高度廓线查询 end"); - return Result.success(profileResponse); + try { + log.info("[data-server] 高度廓线(气压坐标)查询 start: param={}", profileRequest); + ProfileResponse profileResponse = gfsDataService.getProfileByVariableAndPressure(variableName, utcDateTime, latitude, longitude); + return Result.success(profileResponse); + } finally { + log.info("[data-server] 高度廓线(气压坐标)查询 end"); + } } /**查询全部变量随气压的分布*/ @@ -114,12 +117,45 @@ public class UpperWeatherController { OffsetDateTime utcDateTime = DateTimeUtils.getUTCDateTime(time); double latitude = profileRequest.getLatitude(); double longitude = profileRequest.getLongitude(); - log.info("[data-server] 高度廓线查询 start: param={}", profileRequest); - ProfileDataset profile = gfsDataService.getProfileByPressure(utcDateTime, latitude, longitude); - log.info("[data-server] 高度廓线查询 end"); - return Result.success(profile); + try { + log.info("[data-server] 高度廓线(气压坐标)查询 start: param={}", profileRequest); + ProfileDataset profile = gfsDataService.getProfileByPressure(utcDateTime, latitude, longitude); + return Result.success(profile); + } finally { + log.info("[data-server] 高度廓线(气压坐标)查询 end"); + } + } + /**查询全部近地面变量随高度的分布*/ + @RequestMapping("/queryProfileByVariableAndNearSurfaceHeight") + public Result queryProfileByVariableAndNearSurfaceHeight(@Validated @RequestBody ProfileRequest profileRequest) { + OffsetDateTime time = OffsetDateTime.parse(profileRequest.getTime()); + OffsetDateTime utcDateTime = DateTimeUtils.getUTCDateTime(time); + String variableName = profileRequest.getVariableName(); + double latitude = profileRequest.getLatitude(); + double longitude = profileRequest.getLongitude(); + try { + log.info("[data-server] 高度廓线(近地面高度坐标)查询 start: param={}", profileRequest); + ProfileResponse profile = gfsDataService.getProfileByVariableAndNearSurfaceHeight(variableName, utcDateTime, latitude, longitude); + return Result.success(profile); + } finally { + log.info("[data-server] 高度廓线(近地面高度坐标)查询 end"); + } + } + /**查询全部近地面变量随高度的分布*/ + @RequestMapping("/queryProfileByNearSurfaceHeight") + public Result queryProfileByNearSurfaceHeight(@Validated @RequestBody ProfileRequest profileRequest) { + OffsetDateTime time = OffsetDateTime.parse(profileRequest.getTime()); + OffsetDateTime utcDateTime = DateTimeUtils.getUTCDateTime(time); + double latitude = profileRequest.getLatitude(); + double longitude = profileRequest.getLongitude(); + try { + log.info("[data-server] 高度廓线(近地面高度坐标)查询 start: param={}", profileRequest); + ProfileDataset profile = gfsDataService.getProfileByNearSurfaceHeight(utcDateTime, latitude, longitude); + return Result.success(profile); + } finally { + log.info("[data-server] 高度廓线(近地面高度坐标)查询 end"); + } } - @PostMapping("/queryPlaneGrid") public Result queryPlaneGrid(@Validated @RequestBody PlaneRequest planeRequest) { planeRequest.valid(); diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/AddressComponent.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/AddressComponent.java index 386524c..9d6bf58 100644 --- a/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/AddressComponent.java +++ b/weather-service/src/main/java/com/htfp/weather/web/pojo/cma/AddressComponent.java @@ -1,9 +1,10 @@ package com.htfp.weather.web.pojo.cma; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; -@Data +@Data @JsonIgnoreProperties(ignoreUnknown = true) public class AddressComponent { private String address; @@ -29,4 +30,5 @@ public class AddressComponent { private int poiDistance; @JsonProperty("address_distance") private int addressDistance; + private String info; } diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/request/ProfileRequest.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/request/ProfileRequest.java index 59d9ae1..49a61a6 100644 --- a/weather-service/src/main/java/com/htfp/weather/web/pojo/request/ProfileRequest.java +++ b/weather-service/src/main/java/com/htfp/weather/web/pojo/request/ProfileRequest.java @@ -1,7 +1,9 @@ package com.htfp.weather.web.pojo.request; +import com.htfp.weather.download.gfs.GfsVariableIsobaricEnum; import com.htfp.weather.info.Constant; import com.htfp.weather.web.valid.DateTimeStr; +import com.htfp.weather.web.valid.EnumValid; import lombok.Data; import javax.validation.constraints.Max; @@ -18,7 +20,7 @@ public class ProfileRequest { @NotNull(message = "时间不能为空") @DateTimeStr(message = "时间格式错误") String time; - + @EnumValid(enumClass = GfsVariableIsobaricEnum.class, usedField = "getNameInApi", message = "变量不存在") String variableName; @NotNull(message = "纬度 (latitude) 不能为空") diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/MultiPointResponse.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/MultiPointResponse.java deleted file mode 100644 index 8d85b2a..0000000 --- a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/MultiPointResponse.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.htfp.weather.web.pojo.response; - -/** - * @Author : shiyi - * @Date : 2024/6/6 15:24 - * @Description : 航点气象数据响应 - */ -public class MultiPointResponse { -} diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/NowWeatherStatus.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/NowWeatherStatus.java index 19d327a..dca12dd 100644 --- a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/NowWeatherStatus.java +++ b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/NowWeatherStatus.java @@ -1,5 +1,6 @@ package com.htfp.weather.web.pojo.response; +import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data; /** @@ -7,7 +8,7 @@ import lombok.Data; * @Date : 2024/1/24 11:28 * @Description : 当前天气状况 */ -@Data +@Data @JsonInclude(JsonInclude.Include.NON_NULL) public class NowWeatherStatus { String time; // 数据时间,北京时 String weatherText; // 天气状况 diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/ProfileDataset.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/ProfileDataset.java index cb65bcf..fec8755 100644 --- a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/ProfileDataset.java +++ b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/ProfileDataset.java @@ -1,5 +1,7 @@ package com.htfp.weather.web.pojo.response; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data; import java.util.ArrayList; @@ -9,10 +11,10 @@ import java.util.ArrayList; * @Date : 2024/5/8 15:19 * @Description : 高度廓线 */ -@Data +@Data @JsonInclude(JsonInclude.Include.NON_NULL) public class ProfileDataset { int[] pressureLevels; - // int[ pressureHeight; + int[] heightLevel; double latitude; double longitude; float[] temp; diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/ProfileResponse.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/ProfileResponse.java index 230c4be..c889ac2 100644 --- a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/ProfileResponse.java +++ b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/ProfileResponse.java @@ -1,5 +1,6 @@ package com.htfp.weather.web.pojo.response; +import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data; import lombok.Getter; @@ -8,17 +9,11 @@ import lombok.Getter; * @Date : 2024/5/8 15:19 * @Description : 高度廓线 */ -@Data +@Data @JsonInclude(JsonInclude.Include.NON_NULL) public class ProfileResponse { int[] pressureLevels; - // int[ pressureHeight; + int[] heightLevels; double latitude; double longitude; float[] values; - - public ProfileResponse(int[] pressureLevels, float[] values) { - this.pressureLevels = pressureLevels; - // this.pressureHeight = pressureHeight; - this.values = values; - } } diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/SurfaceWeatherWarning.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/SurfaceWeatherWarning.java index 3114fe1..ae11a4c 100644 --- a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/SurfaceWeatherWarning.java +++ b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/SurfaceWeatherWarning.java @@ -1,6 +1,7 @@ package com.htfp.weather.web.pojo.response; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data; /** @@ -8,7 +9,7 @@ import lombok.Data; * @Date : 2024/4/17 15:44 * @Description : 地面天气预警信息 */ -@Data +@Data @JsonInclude(JsonInclude.Include.NON_NULL) public class SurfaceWeatherWarning { String pubTime; String endTime; diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/TimeSeries.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/TimeSeries.java deleted file mode 100644 index 5999325..0000000 --- a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/TimeSeries.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.htfp.weather.web.pojo.response; - -import lombok.Data; - -import java.util.List; - -/** - * @Author : shiyi - * @Date : 2024/1/24 13:38 - * @Description : 时间序列 - */ -@Data -public class TimeSeries { - String name; - List time; - List values; -} diff --git a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/TimeSeriesDataset.java b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/TimeSeriesDataset.java index 7668a0d..47348ca 100644 --- a/weather-service/src/main/java/com/htfp/weather/web/pojo/response/TimeSeriesDataset.java +++ b/weather-service/src/main/java/com/htfp/weather/web/pojo/response/TimeSeriesDataset.java @@ -1,5 +1,6 @@ package com.htfp.weather.web.pojo.response; +import com.fasterxml.jackson.annotation.JsonInclude; import lombok.Data; import java.sql.Time; @@ -11,7 +12,7 @@ import java.util.List; * @Date : 2024/1/24 13:46 * @Description : 将和风的逐小时数据集转换为变量时间序列数据集 */ -@Data +@Data @JsonInclude(JsonInclude.Include.NON_NULL) public class TimeSeriesDataset { List time; Double latitude; diff --git a/weather-service/src/main/java/com/htfp/weather/web/service/GfsDataServiceImpl.java b/weather-service/src/main/java/com/htfp/weather/web/service/GfsDataServiceImpl.java index 73b2dd6..e2d36a8 100644 --- a/weather-service/src/main/java/com/htfp/weather/web/service/GfsDataServiceImpl.java +++ b/weather-service/src/main/java/com/htfp/weather/web/service/GfsDataServiceImpl.java @@ -20,7 +20,7 @@ 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.checkerframework.checker.units.qual.A; import org.springframework.stereotype.Service; import ucar.ma2.Array; import ucar.ma2.Index4D; @@ -125,8 +125,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()); } } @@ -162,8 +164,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()); } } @@ -189,8 +193,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()); } } @@ -223,8 +229,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()); } } @@ -243,22 +251,29 @@ 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()); } } + + /** 获取全部变量随气压变化的廓线 (推荐) */ public ProfileDataset getProfileByPressure(OffsetDateTime targetTime, double latitude, double longitude) { try { - List variableNames = getVariableNamesInDatabase(GfsLevelsEnum.UPPER.getCode()); + GfsLevelsEnum levelFlag = GfsLevelsEnum.UPPER; + List 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; @@ -269,6 +284,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 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()); + } + } /** * 获取指定变量、时间、高度的二维数组数据 @@ -305,8 +362,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()); } } @@ -499,7 +558,12 @@ 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; } diff --git a/weather-service/src/main/java/com/htfp/weather/web/service/surfaceapi/CmaServiceImpl.java b/weather-service/src/main/java/com/htfp/weather/web/service/surfaceapi/CmaServiceImpl.java index 87d09c4..09d3460 100644 --- a/weather-service/src/main/java/com/htfp/weather/web/service/surfaceapi/CmaServiceImpl.java +++ b/weather-service/src/main/java/com/htfp/weather/web/service/surfaceapi/CmaServiceImpl.java @@ -5,6 +5,7 @@ import com.htfp.weather.utils.DateTimeUtils; import com.htfp.weather.utils.JSONUtils; import com.htfp.weather.web.exception.AppException; import com.htfp.weather.web.exception.ErrorCode; +import com.htfp.weather.web.pojo.cma.AddressComponent; import com.htfp.weather.web.pojo.cma.AntiGeoCodeResponse; import com.htfp.weather.web.pojo.cma.CmaWarning; import com.htfp.weather.web.pojo.response.NowWeatherStatus; @@ -78,14 +79,17 @@ public class CmaServiceImpl implements ISurfaceDataService{ params.put("type", "geocode"); params.put("tk", keyOfTianDiTu); AntiGeoCodeResponse antiGeoCodeResponse = sendGet(url, params, AntiGeoCodeResponse.class); - if (!"ok".equals(antiGeoCodeResponse.getMsg())) { + if (antiGeoCodeResponse.getResult() == null){ throw new AppException(ErrorCode.TIANDITU_REQUEST_ERROR, "获取行政区划信息失败:" + antiGeoCodeResponse.getMsg()); } - String countyCode = antiGeoCodeResponse.getResult().getAddressComponent().getCountyCode(); - if (StringUtils.isNotEmpty(countyCode)) { - return countyCode.substring(countyCode.length()-6); + AddressComponent addressComponent = antiGeoCodeResponse.getResult().getAddressComponent(); + String countyCode = addressComponent.getCountyCode(); + if (StringUtils.isEmpty(countyCode)) { + String info; + info = addressComponent.getInfo(); + throw new AppException(ErrorCode.TIANDITU_DATA_PARSE_ERROR, "获取行政区代码失败:" + info); } else { - throw new AppException(ErrorCode.TIANDITU_DATA_PARSE_ERROR, "获取行政区代码失败:" + antiGeoCodeResponse.getMsg()); + return countyCode.substring(countyCode.length()-6); } } /**每半小时定时更新全国的气象预警数据; @@ -101,9 +105,9 @@ public class CmaServiceImpl implements ISurfaceDataService{ * @param countyCode 县级行政区代码*/ public void updateCmaWarning(String countyCode) { String url = "https://data.cma.cn/dataGis/disasterWarning/getWarningDataByCnty"; - // 2小时前,24小时后 - OffsetDateTime startTime = DateTimeUtils.offsetDateTimeToSystemZone(OffsetDateTime.now()).minusHours(2); - OffsetDateTime endTime = startTime.plusHours(24); + // 6小时前,12小时后 + OffsetDateTime startTime = DateTimeUtils.offsetDateTimeToSystemZone(OffsetDateTime.now()).minusHours(6); + OffsetDateTime endTime = startTime.plusHours(12); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd+HH:mm:ss"); HashMap params = new HashMap<>(); params.put("startTime", startTime.format(formatter)); diff --git a/weather-service/src/main/java/com/htfp/weather/web/service/surfaceapi/HeFengServiceImpl.java b/weather-service/src/main/java/com/htfp/weather/web/service/surfaceapi/HeFengServiceImpl.java index 499de5b..710555d 100644 --- a/weather-service/src/main/java/com/htfp/weather/web/service/surfaceapi/HeFengServiceImpl.java +++ b/weather-service/src/main/java/com/htfp/weather/web/service/surfaceapi/HeFengServiceImpl.java @@ -138,7 +138,9 @@ public class HeFengServiceImpl implements ISurfaceDataService { for (int i = 0; i < hourly.size(); i++) { HeFengForecastHour heFengForecastHour = hourly.get(i); processHeFengData(heFengForecastHour); - timeSeriesDataset.getTime().add(heFengForecastHour.getFxTime()); + timeSeriesDataset.getTime().add( + DateTimeUtils.offsetDateTimeToSystemZone(OffsetDateTime.parse(heFengForecastHour.getFxTime())).format(Constant.API_TIME_FORMATTER) + ); timeSeriesDataset.getTemp()[i] = heFengForecastHour.getTemp(); timeSeriesDataset.getWindSpeed()[i] = heFengForecastHour.getWindSpeed(); timeSeriesDataset.getWind360()[i] = heFengForecastHour.getWind360();