11 changed files with 694 additions and 21 deletions
			
			
		@ -0,0 +1,34 @@ | 
				
			|||||
 | 
					package com.ping.chuan.apiservice.config; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import io.swagger.annotations.Api; | 
				
			||||
 | 
					import org.springframework.context.annotation.Bean; | 
				
			||||
 | 
					import org.springframework.context.annotation.Configuration; | 
				
			||||
 | 
					import springfox.documentation.builders.ApiInfoBuilder; | 
				
			||||
 | 
					import springfox.documentation.builders.PathSelectors; | 
				
			||||
 | 
					import springfox.documentation.builders.RequestHandlerSelectors; | 
				
			||||
 | 
					import springfox.documentation.service.ApiInfo; | 
				
			||||
 | 
					import springfox.documentation.spi.DocumentationType; | 
				
			||||
 | 
					import springfox.documentation.spring.web.plugins.Docket; | 
				
			||||
 | 
					import springfox.documentation.swagger2.annotations.EnableSwagger2; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					@Configuration | 
				
			||||
 | 
					@EnableSwagger2 | 
				
			||||
 | 
					public class SwaggerConfig { | 
				
			||||
 | 
					    @Bean | 
				
			||||
 | 
					    public Docket createRestApi() { | 
				
			||||
 | 
					        return new Docket(DocumentationType.SWAGGER_2) | 
				
			||||
 | 
					                .useDefaultResponseMessages(false) | 
				
			||||
 | 
					                .apiInfo(apiInfo()) | 
				
			||||
 | 
					                .select() | 
				
			||||
 | 
					                .apis(RequestHandlerSelectors.withClassAnnotation(Api.class)) | 
				
			||||
 | 
					                .paths(PathSelectors.any()) | 
				
			||||
 | 
					                .build(); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					    private ApiInfo apiInfo() { | 
				
			||||
 | 
					        return new ApiInfoBuilder() | 
				
			||||
 | 
					                .title("安徽省公共气象服务基础数据平台") | 
				
			||||
 | 
					                .description("测试") | 
				
			||||
 | 
					                .version("5.2.1") | 
				
			||||
 | 
					                .build(); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,192 @@ | 
				
			|||||
 | 
					package com.ping.chuan.apiservice.controller; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import java.math.BigDecimal; | 
				
			||||
 | 
					import java.time.LocalDateTime; | 
				
			||||
 | 
					import java.util.ArrayList; | 
				
			||||
 | 
					import java.util.List; | 
				
			||||
 | 
					import java.util.Map; | 
				
			||||
 | 
					import java.util.Objects; | 
				
			||||
 | 
					import java.util.stream.Collectors; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import io.swagger.annotations.*; | 
				
			||||
 | 
					import org.springframework.web.bind.annotation.PostMapping; | 
				
			||||
 | 
					import org.springframework.web.bind.annotation.RequestMapping; | 
				
			||||
 | 
					import org.springframework.web.bind.annotation.RestController; | 
				
			||||
 | 
					import com.fasterxml.jackson.core.type.TypeReference; | 
				
			||||
 | 
					import com.fasterxml.jackson.databind.ObjectMapper; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.constant.TimeConstant; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.dao.Coordinate; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.dao.MetaInfo; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.service.IDataService; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.template.CacheTemplate; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.util.RequestResult; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * @describe: | 
				
			||||
 | 
					 * @author: xiaowuler | 
				
			||||
 | 
					 * @createTime: 2021-11-12 15:20 | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					@Api(tags = "获取要素模式数据") | 
				
			||||
 | 
					@RestController | 
				
			||||
 | 
					@RequestMapping("baseData") | 
				
			||||
 | 
					public class BaseDataController { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    private final ObjectMapper objectMapper = new ObjectMapper(); | 
				
			||||
 | 
					    private final IDataService dataService; | 
				
			||||
 | 
					    public BaseDataController(IDataService dataService){ | 
				
			||||
 | 
					        this.dataService = dataService; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @ApiOperation(value="用户根据起报时间、要素编码获取SPCC模式要素预报数据", notes="用户根据起报时间、要素编码获取SPCC模式要素预报数据", produces="application/json", httpMethod = "POST") | 
				
			||||
 | 
					    @ApiImplicitParams({ | 
				
			||||
 | 
					            @ApiImplicitParam(name = "elementCode", value = "要素编码", required = true, example = "TMP"), | 
				
			||||
 | 
					            @ApiImplicitParam(name = "initialTime", value = "起报时间", required = true, example = "20211110080000"), | 
				
			||||
 | 
					            @ApiImplicitParam(name = "forecastTime", value = "预报时间", required = true, example = "20211110110000"), | 
				
			||||
 | 
					            @ApiImplicitParam(name = "latLons", value = "经纬度", required = true, example = "[[31.5509, 116.97061], [32.5509, 116.97061], [ 29.8, 118.55], [29.888, 118.77]]") | 
				
			||||
 | 
					    }) | 
				
			||||
 | 
					    @PostMapping("getSPCCFcstByTargetTimeAndLatlons") | 
				
			||||
 | 
					    public RequestResult getSPCCFcstByInitialTimeAndLatlons(String elementCode, String initialTime, String forecastTime, String latLons) throws Exception { | 
				
			||||
 | 
					        String error = verifyParams(elementCode, initialTime, forecastTime, latLons); | 
				
			||||
 | 
					        if (Objects.nonNull(error)){ | 
				
			||||
 | 
					            return RequestResult.fail(error); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        Object initialTimeValue = convertTime(initialTime); | 
				
			||||
 | 
					        if (initialTimeValue instanceof String e){ | 
				
			||||
 | 
					            return RequestResult.fail(e); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        Object forecastTimeValue = convertTime(forecastTime); | 
				
			||||
 | 
					        if (forecastTimeValue instanceof String e){ | 
				
			||||
 | 
					            return RequestResult.fail(e); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        Object latLonValue = convertLatLon(latLons); | 
				
			||||
 | 
					        if (latLonValue instanceof String e){ | 
				
			||||
 | 
					            return RequestResult.fail(e); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        Map.Entry<MetaInfo, Coordinate> entry = CacheTemplate.findOne("SPCC", elementCode, "BEHF", 180, 4320, 1010); | 
				
			||||
 | 
					        if (Objects.isNull(entry)){ | 
				
			||||
 | 
					            return RequestResult.fail("未录入当前要素编码数据"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return RequestResult.success(dataService.findPoints(entry, (LocalDateTime) initialTimeValue, (LocalDateTime) forecastTimeValue, (List<BigDecimal[]>) latLonValue)); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @ApiOperation(value="用户根据起报时间、要素编码获取CLDAS模式要素预报数据", notes="用户根据起报时间、要素编码获取CLDAS模式要素预报数据", produces="application/json", httpMethod = "POST") | 
				
			||||
 | 
					    @ApiImplicitParams({ | 
				
			||||
 | 
					            @ApiImplicitParam(name = "elementCode", value = "要素编码", required = true, example = "RHU"), | 
				
			||||
 | 
					            @ApiImplicitParam(name = "realTime", value = "实况时间", required = true, example = "20211112230000"), | 
				
			||||
 | 
					            @ApiImplicitParam(name = "latLons", value = "经纬度", required = true, example = "[[31.5509, 116.97061], [32.5509, 116.97061], [ 29.8, 118.55], [29.888, 118.77]]") | 
				
			||||
 | 
					    }) | 
				
			||||
 | 
					    @PostMapping("getCLDASRealByTargetTimeAndLatlons") | 
				
			||||
 | 
					    public RequestResult getCLDASRealByInitialTimeAndLatlons(String elementCode, String realTime, String latLons) throws Exception { | 
				
			||||
 | 
					        String error = verifyParams(elementCode, realTime, realTime, latLons); | 
				
			||||
 | 
					        if (Objects.nonNull(error)){ | 
				
			||||
 | 
					            return RequestResult.fail(error); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        Object initialTimeValue = convertTime(realTime); | 
				
			||||
 | 
					        if (initialTimeValue instanceof String e){ | 
				
			||||
 | 
					            return RequestResult.fail(e); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        Object forecastTimeValue = convertTime(realTime); | 
				
			||||
 | 
					        if (forecastTimeValue instanceof String e){ | 
				
			||||
 | 
					            return RequestResult.fail(e); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        Object latLonValue = convertLatLon(latLons); | 
				
			||||
 | 
					        if (latLonValue instanceof String e){ | 
				
			||||
 | 
					            return RequestResult.fail(e); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        Map.Entry<MetaInfo, Coordinate> entry = CacheTemplate.findOne("CLDAS", elementCode, "BABJ", 60, 60, 1010); | 
				
			||||
 | 
					        if (Objects.isNull(entry)){ | 
				
			||||
 | 
					            return RequestResult.fail("未录入当前要素编码数据"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return RequestResult.success(dataService.findPoints(entry, (LocalDateTime) initialTimeValue, (LocalDateTime) forecastTimeValue, (List<BigDecimal[]>) latLonValue)); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @ApiOperation(value="用户根据起报时间、要素编码获取CMPA模式要素预报数据", notes="用户根据起报时间、要素编码获取CMPA模式要素预报数据", produces="application/json", httpMethod = "POST") | 
				
			||||
 | 
					    @ApiImplicitParams({ | 
				
			||||
 | 
					            @ApiImplicitParam(name = "elementCode", value = "要素编码", required = true, example = "PRE"), | 
				
			||||
 | 
					            @ApiImplicitParam(name = "realTime", value = "实况时间", required = true, example = "20211112230000"), | 
				
			||||
 | 
					            @ApiImplicitParam(name = "latLons", value = "经纬度", required = true, example = "[[31.5509, 116.97061], [32.5509, 116.97061], [ 29.8, 118.55], [29.888, 118.77]]") | 
				
			||||
 | 
					    }) | 
				
			||||
 | 
					    @PostMapping("getCMPARealByInitialTimeAndLatlons") | 
				
			||||
 | 
					    public RequestResult getCMPARealByInitialTimeAndLatlons(String elementCode, String realTime, String latLons) throws Exception { | 
				
			||||
 | 
					        String error = verifyParams(elementCode, realTime, realTime, latLons); | 
				
			||||
 | 
					        if (Objects.nonNull(error)){ | 
				
			||||
 | 
					            return RequestResult.fail(error); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        Object initialTimeValue = convertTime(realTime); | 
				
			||||
 | 
					        if (initialTimeValue instanceof String e){ | 
				
			||||
 | 
					            return RequestResult.fail(e); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        Object forecastTimeValue = convertTime(realTime); | 
				
			||||
 | 
					        if (forecastTimeValue instanceof String e){ | 
				
			||||
 | 
					            return RequestResult.fail(e); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        Object latLonValue = convertLatLon(latLons); | 
				
			||||
 | 
					        if (latLonValue instanceof String e){ | 
				
			||||
 | 
					            return RequestResult.fail(e); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        Map.Entry<MetaInfo, Coordinate> entry = CacheTemplate.findOne("CMPA", elementCode, "BABJ", 60, 60, 1010); | 
				
			||||
 | 
					        if (Objects.isNull(entry)){ | 
				
			||||
 | 
					            return RequestResult.fail("未录入当前要素编码数据"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return RequestResult.success(dataService.findPoints(entry, (LocalDateTime) initialTimeValue, (LocalDateTime) forecastTimeValue, (List<BigDecimal[]>) latLonValue)); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    private String verifyParams(String elementCode, String initialTime, String forecastTime, String latLons){ | 
				
			||||
 | 
					        List<String> errors = new ArrayList<>(4); | 
				
			||||
 | 
					        if (Objects.isNull(elementCode)){ | 
				
			||||
 | 
					            errors.add("要素编码不能为空"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (Objects.isNull(initialTime)){ | 
				
			||||
 | 
					            errors.add("起报时间不能为空"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (Objects.isNull(forecastTime)){ | 
				
			||||
 | 
					            errors.add("预报时间不能为空"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (Objects.isNull(latLons)){ | 
				
			||||
 | 
					            errors.add("经纬度不能为空"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (errors.isEmpty()){ | 
				
			||||
 | 
					            return null; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return errors.stream().collect(Collectors.joining(", ")); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    private Object convertTime(String timeStr){ | 
				
			||||
 | 
					        try{ | 
				
			||||
 | 
					            return LocalDateTime.parse(timeStr, TimeConstant.YYYYMMDDHHMMSS); | 
				
			||||
 | 
					        }catch (Exception e){ | 
				
			||||
 | 
					            return  "时间格式是yyyyMMddHHmmss"; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    private Object convertLatLon(String latLons){ | 
				
			||||
 | 
					        try { | 
				
			||||
 | 
					            List<BigDecimal[]> newLocations = new ArrayList<>(); | 
				
			||||
 | 
					            List<BigDecimal[]> locations = objectMapper.readValue(latLons, new TypeReference<List<BigDecimal[]>>() {}); | 
				
			||||
 | 
					            for (BigDecimal[] loc : locations) { | 
				
			||||
 | 
					                if (loc.length != 2) { | 
				
			||||
 | 
					                    return "latlons 格式不正确,格式应为'[[lat,lon],...,[lat,lon]]'"; | 
				
			||||
 | 
					                } | 
				
			||||
 | 
					                newLocations.add(new BigDecimal[]{loc[0], loc[1]}); | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					            return newLocations; | 
				
			||||
 | 
					        } catch (Exception e) { | 
				
			||||
 | 
					            return "latlons 格式不正确,格式应为'[[lat,lon],...,[lat,lon]]'"; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,147 @@ | 
				
			|||||
 | 
					package com.ping.chuan.apiservice.controller; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.dao.Coordinate; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.dao.MetaInfo; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.service.IDataService; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.template.CacheTemplate; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.util.RequestResult; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.util.TimeUtil; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import io.swagger.annotations.Api; | 
				
			||||
 | 
					import io.swagger.annotations.ApiImplicitParam; | 
				
			||||
 | 
					import io.swagger.annotations.ApiImplicitParams; | 
				
			||||
 | 
					import io.swagger.annotations.ApiOperation; | 
				
			||||
 | 
					import org.springframework.web.bind.annotation.RequestMapping; | 
				
			||||
 | 
					import org.springframework.web.bind.annotation.RestController; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import java.time.LocalDateTime; | 
				
			||||
 | 
					import java.time.ZoneId; | 
				
			||||
 | 
					import java.util.*; | 
				
			||||
 | 
					import java.util.stream.Collectors; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * @author zhangjian | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					@Api(tags = "获取要素元信息") | 
				
			||||
 | 
					@RestController | 
				
			||||
 | 
					@RequestMapping("baseInfo") | 
				
			||||
 | 
					public class BaseInfoController { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    private final IDataService dataService; | 
				
			||||
 | 
					    public BaseInfoController(IDataService dataService){ | 
				
			||||
 | 
					        this.dataService = dataService; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @ApiOperation(value="用户根据模式编码获取要素编码", notes="用户根据模式编码获取要素编码", produces="application/json", httpMethod = "POST") | 
				
			||||
 | 
					    @ApiImplicitParam(name="modeCode", value="modeCode", required=true, example = "SPCC", paramType="query") | 
				
			||||
 | 
					    @RequestMapping("getElementCodes") | 
				
			||||
 | 
					    public RequestResult getElementCodes(String modeCode){ | 
				
			||||
 | 
					        if(Objects.isNull(modeCode)){ | 
				
			||||
 | 
					            return RequestResult.fail("modeCode不能为空"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        String targetModeCode = modeCode.toUpperCase(Locale.ROOT); | 
				
			||||
 | 
					        List<String> result = CacheTemplate.metaInfos.keySet().stream() | 
				
			||||
 | 
					                .filter(m -> m.getModeCode().equals(targetModeCode)) | 
				
			||||
 | 
					                .map(m -> m.getElementCode()) | 
				
			||||
 | 
					                .distinct() | 
				
			||||
 | 
					                .collect(Collectors.toList()); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (result.isEmpty()){ | 
				
			||||
 | 
					            return RequestResult.fail("当前模式未录入相关要素信息"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return RequestResult.success(result); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @ApiOperation(value="用户获取所有模式编码", notes="用户获取所有模式编码", produces="application/json", httpMethod = "POST") | 
				
			||||
 | 
					    @RequestMapping("getAllModeCode") | 
				
			||||
 | 
					    public RequestResult getAllModeCode(){ | 
				
			||||
 | 
					        List<String> result = CacheTemplate.metaInfos.keySet().stream() | 
				
			||||
 | 
					                .map(m -> m.getModeCode()) | 
				
			||||
 | 
					                .distinct() | 
				
			||||
 | 
					                .collect(Collectors.toList()); | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (result.isEmpty()){ | 
				
			||||
 | 
					            return RequestResult.fail("当前无相关模式信息"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return RequestResult.success(result); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @ApiOperation(value="用户根据模式编码和要素编码获取起报时间", notes="用户根据模式编码和要素编码获取起报时间", produces="application/json", httpMethod = "POST") | 
				
			||||
 | 
					    @ApiImplicitParams({ | 
				
			||||
 | 
					            @ApiImplicitParam(name="modeCode", value="模式编码", example = "SPCC", required=true, paramType="query"), | 
				
			||||
 | 
					            @ApiImplicitParam(name="elementCode", value="要素编码", example = "TMP", required=true, paramType="query") | 
				
			||||
 | 
					    }) | 
				
			||||
 | 
					    @RequestMapping("getInitialTimeByModeCodeAndElementCode") | 
				
			||||
 | 
					    public RequestResult getInitialTimeByModeCodeAndElementCode(String modeCode, String elementCode) throws Exception { | 
				
			||||
 | 
					        if(Objects.isNull(modeCode)){ | 
				
			||||
 | 
					            return RequestResult.fail("modeCode不能为空"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        if(Objects.isNull(elementCode)){ | 
				
			||||
 | 
					            return RequestResult.fail("elementCode不能为空"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        int timeInterval = 60; | 
				
			||||
 | 
					        int timeLength = 60; | 
				
			||||
 | 
					        String memberCode = "BABJ"; | 
				
			||||
 | 
					        modeCode = modeCode.toUpperCase(Locale.ROOT); | 
				
			||||
 | 
					        elementCode = elementCode.toUpperCase(Locale.ROOT); | 
				
			||||
 | 
					        if ("SPCC".equals(modeCode)){ | 
				
			||||
 | 
					            timeInterval = 180; | 
				
			||||
 | 
					            timeLength = 4320; | 
				
			||||
 | 
					            memberCode = "BEHF"; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        Map.Entry<MetaInfo, Coordinate> entry = CacheTemplate.findOne(modeCode, elementCode, memberCode, timeInterval, timeLength, 1010); | 
				
			||||
 | 
					        if (Objects.isNull(entry)){ | 
				
			||||
 | 
					            return RequestResult.fail("当前无相关模式信息"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return RequestResult.success(dataService.findInitialTime(entry)); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @ApiOperation(value="用户根据模式编码、要素编码、起报时间获取预报时间", notes="用户根据模式编码、要素编码、起报时间获取预报时间", produces="application/json", httpMethod = "POST") | 
				
			||||
 | 
					    @ApiImplicitParams({ | 
				
			||||
 | 
					            @ApiImplicitParam(name="modeCode", value="模式编码", example = "SPCC", required=true, paramType="query"), | 
				
			||||
 | 
					            @ApiImplicitParam(name="elementCode", value="要素编码", example = "TMP", required=true, paramType="query"), | 
				
			||||
 | 
					            @ApiImplicitParam(name="initialTime", value="起报时间", example = "20211112080000", required=true, paramType="query") | 
				
			||||
 | 
					    }) | 
				
			||||
 | 
					    @RequestMapping("getForecastTimeByModeCodeAndElementCode") | 
				
			||||
 | 
					    public RequestResult getForecastTimeByModeCodeAndElementCode(String modeCode, String elementCode, String initialTime) throws Exception { | 
				
			||||
 | 
					        if(Objects.isNull(modeCode)){ | 
				
			||||
 | 
					            return RequestResult.fail("modeCode不能为空"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        if(Objects.isNull(elementCode)){ | 
				
			||||
 | 
					            return RequestResult.fail("elementCode不能为空"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (Objects.isNull(initialTime)){ | 
				
			||||
 | 
					            return RequestResult.fail("initialTime不能为空"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        int timeInterval = 60; | 
				
			||||
 | 
					        int timeLength = 60; | 
				
			||||
 | 
					        String memberCode = "BABJ"; | 
				
			||||
 | 
					        modeCode = modeCode.toUpperCase(Locale.ROOT); | 
				
			||||
 | 
					        elementCode = elementCode.toUpperCase(Locale.ROOT); | 
				
			||||
 | 
					        if ("SPCC".equals(modeCode)){ | 
				
			||||
 | 
					            timeInterval = 180; | 
				
			||||
 | 
					            timeLength = 4320; | 
				
			||||
 | 
					            memberCode = "BEHF"; | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        Map.Entry<MetaInfo, Coordinate> entry = CacheTemplate.findOne(modeCode, elementCode, memberCode, timeInterval, timeLength, 1010); | 
				
			||||
 | 
					        if (Objects.isNull(entry)){ | 
				
			||||
 | 
					            return RequestResult.fail("当前无相关模式信息"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        Object initialTimeValue = TimeUtil.convertTime(initialTime); | 
				
			||||
 | 
					        if (initialTimeValue instanceof String e){ | 
				
			||||
 | 
					            return RequestResult.fail(e); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return RequestResult.success(dataService.findForecastTime(entry, Date.from(((LocalDateTime) initialTimeValue).atZone(ZoneId.systemDefault()).toInstant()))); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,19 @@ | 
				
			|||||
 | 
					package com.ping.chuan.apiservice.handler; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import lombok.extern.slf4j.Slf4j; | 
				
			||||
 | 
					import org.springframework.web.bind.annotation.ControllerAdvice; | 
				
			||||
 | 
					import org.springframework.web.bind.annotation.ExceptionHandler; | 
				
			||||
 | 
					import org.springframework.web.bind.annotation.ResponseBody; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import com.ping.chuan.apiservice.util.RequestResult; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					@ControllerAdvice | 
				
			||||
 | 
					@Slf4j | 
				
			||||
 | 
					public class GlobalDefaultExceptionHandler { | 
				
			||||
 | 
					    @ExceptionHandler(Exception.class) | 
				
			||||
 | 
					    @ResponseBody | 
				
			||||
 | 
					    public RequestResult defaultExceptionHandler(Exception e) { | 
				
			||||
 | 
					        log.error("An error has occurred", e); | 
				
			||||
 | 
					        return RequestResult.fail(e.getMessage()); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,43 @@ | 
				
			|||||
 | 
					package com.ping.chuan.apiservice.model.domain; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import java.math.BigDecimal; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import lombok.Data; | 
				
			||||
 | 
					import com.fasterxml.jackson.annotation.JsonProperty; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * @describe: | 
				
			||||
 | 
					 * @author: xiaowuler | 
				
			||||
 | 
					 * @createTime: 2021-11-12 16:16 | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					@Data | 
				
			||||
 | 
					public class CoordinateInfo { | 
				
			||||
 | 
					    private BigDecimal originalLon; | 
				
			||||
 | 
					    private BigDecimal originalLat; | 
				
			||||
 | 
					    private BigDecimal gridLon; | 
				
			||||
 | 
					    private BigDecimal gridLat; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) | 
				
			||||
 | 
					    private int lonIndex; | 
				
			||||
 | 
					    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) | 
				
			||||
 | 
					    private int latIndex; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) | 
				
			||||
 | 
					    private int sliceLon; | 
				
			||||
 | 
					    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) | 
				
			||||
 | 
					    private int sliceLat; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) | 
				
			||||
 | 
					    private int sliceLonIndex; | 
				
			||||
 | 
					    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) | 
				
			||||
 | 
					    private int sliceLatIndex; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    private int targetLatIndex; | 
				
			||||
 | 
					    private int targetLonIndex; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) | 
				
			||||
 | 
					    private String column; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) | 
				
			||||
 | 
					    private boolean isHandler = true; | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,19 @@ | 
				
			|||||
 | 
					package com.ping.chuan.apiservice.model.vo; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import java.math.BigDecimal; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import lombok.Data; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * @describe: 点数据返回实体类 | 
				
			||||
 | 
					 * @author: xiaowuler | 
				
			||||
 | 
					 * @createTime: 2021-11-13 11:03 | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					@Data | 
				
			||||
 | 
					public class PointValue { | 
				
			||||
 | 
					    private BigDecimal originalLon; | 
				
			||||
 | 
					    private BigDecimal originalLat; | 
				
			||||
 | 
					    private BigDecimal gridLon; | 
				
			||||
 | 
					    private BigDecimal gridLat; | 
				
			||||
 | 
					    private BigDecimal value; | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,25 @@ | 
				
			|||||
 | 
					package com.ping.chuan.apiservice.model.vo; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import java.time.LocalDateTime; | 
				
			||||
 | 
					import java.util.List; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import lombok.Data; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import com.fasterxml.jackson.annotation.JsonFormat; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.dao.MetaInfo; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * @describe: 点数据 传输类 | 
				
			||||
 | 
					 * @author: xiaowuler | 
				
			||||
 | 
					 * @createTime: 2021-11-13 11:10 | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					@Data | 
				
			||||
 | 
					public class PointValueVo { | 
				
			||||
 | 
					    private MetaInfo metaInfo; | 
				
			||||
 | 
					    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyyMMddHHmmss") | 
				
			||||
 | 
					    private LocalDateTime initialTime; | 
				
			||||
 | 
					    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyyMMddHHmmss") | 
				
			||||
 | 
					    private LocalDateTime targetTime; | 
				
			||||
 | 
					    private List<PointValue> pointValues; | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,117 @@ | 
				
			|||||
 | 
					package com.ping.chuan.apiservice.service.impl; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import java.math.BigDecimal; | 
				
			||||
 | 
					import java.text.SimpleDateFormat; | 
				
			||||
 | 
					import java.time.LocalDateTime; | 
				
			||||
 | 
					import java.util.*; | 
				
			||||
 | 
					import java.util.stream.Collectors; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import org.springframework.stereotype.Service; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import com.ping.chuan.apiservice.dao.IDataRepository; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.dao.ISchemaRepository; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.constant.TimeConstant; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.dao.Coordinate; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.dao.DealInfo; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.dao.MetaInfo; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.domain.CoordinateInfo; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.vo.PointValue; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.model.vo.PointValueVo; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.service.IDataService; | 
				
			||||
 | 
					import com.ping.chuan.apiservice.util.CalcUtil; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					/** | 
				
			||||
 | 
					 * @describe: 数据服务 | 
				
			||||
 | 
					 * @author: xiaowuler | 
				
			||||
 | 
					 * @createTime: 2021-11-12 15:58 | 
				
			||||
 | 
					 */ | 
				
			||||
 | 
					@Service | 
				
			||||
 | 
					public class DataService implements IDataService { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    private final ISchemaRepository schemaRepository; | 
				
			||||
 | 
					    private final IDataRepository dataRepository; | 
				
			||||
 | 
					    public DataService(ISchemaRepository schemaRepository, IDataRepository dataRepository){ | 
				
			||||
 | 
					        this.schemaRepository = schemaRepository; | 
				
			||||
 | 
					        this.dataRepository = dataRepository; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @Override | 
				
			||||
 | 
					    public void readRoutineElement(Map.Entry<DealInfo, Map.Entry<MetaInfo, Coordinate>> entry, boolean isTmp) { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @Override | 
				
			||||
 | 
					    public void readWindElement(Map.Entry<DealInfo, Map.Entry<MetaInfo, Coordinate>> entry) { | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @Override | 
				
			||||
 | 
					    public PointValueVo findPoints(Map.Entry<MetaInfo, Coordinate> entry, LocalDateTime initialTime, LocalDateTime forecastTime, List<BigDecimal[]> latLons) throws Exception { | 
				
			||||
 | 
					        String keyspace = toKeyspace(initialTime); | 
				
			||||
 | 
					        String tableName = entry.getKey().toTableName(); | 
				
			||||
 | 
					        boolean isExist = schemaRepository.exist(keyspace, tableName); | 
				
			||||
 | 
					        if (!isExist){ | 
				
			||||
 | 
					            throw new Exception("当前数据未建立库,请调整时间查询。"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        List<CoordinateInfo> coordinateInfos = new ArrayList<>(latLons.size()); | 
				
			||||
 | 
					        for(BigDecimal[] latLon : latLons){ | 
				
			||||
 | 
					            coordinateInfos.add(CalcUtil.calcLocation(entry.getValue(), entry.getKey(), latLon)); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        List<PointValue> pointValues = dataRepository.findPoint(keyspace, tableName, initialTime, forecastTime, coordinateInfos); | 
				
			||||
 | 
					        return toPointValueVo(initialTime, forecastTime, entry.getKey(), pointValues); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @Override | 
				
			||||
 | 
					    public List<String> findInitialTime(Map.Entry<MetaInfo, Coordinate> entry) throws Exception { | 
				
			||||
 | 
					        LocalDateTime now = LocalDateTime.now(); | 
				
			||||
 | 
					        List<String> times = new ArrayList<>(); | 
				
			||||
 | 
					        SimpleDateFormat sdf = new SimpleDateFormat(TimeConstant.YYYYMMDDHHMMSS_STR); | 
				
			||||
 | 
					        for(int index = 0; index < 3; index++){ | 
				
			||||
 | 
					            LocalDateTime time = now.minusMonths(index); | 
				
			||||
 | 
					            String keyspace = "data_%s".formatted(time.format(TimeConstant.YYYYMM)); | 
				
			||||
 | 
					            String tableName =  entry.getKey().toTableName(); | 
				
			||||
 | 
					            if (!schemaRepository.exist(keyspace, tableName)){ | 
				
			||||
 | 
					                break; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					            List<Date> sourceTimes = dataRepository.findInitialTime(keyspace, tableName); | 
				
			||||
 | 
					            times.addAll(sourceTimes.stream().map(t -> sdf.format(t)).collect(Collectors.toList())); | 
				
			||||
 | 
					            if (times.size() >= 10){ | 
				
			||||
 | 
					                break; | 
				
			||||
 | 
					            } | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        if (times.isEmpty()){ | 
				
			||||
 | 
					            throw new Exception("未查到相关信息,请调整参数查询"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					        return times.stream().limit(10).sorted().collect(Collectors.toList()); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    @Override | 
				
			||||
 | 
					    public List<String> findForecastTime(Map.Entry<MetaInfo, Coordinate> entry, Date initialTime) throws Exception { | 
				
			||||
 | 
					        SimpleDateFormat sdf = new SimpleDateFormat(TimeConstant.YYYYMM_STR); | 
				
			||||
 | 
					        String keyspace = "data_%s".formatted(sdf.format(initialTime)); | 
				
			||||
 | 
					        String tableName =  entry.getKey().toTableName(); | 
				
			||||
 | 
					        if (!schemaRepository.exist(keyspace, tableName)){ | 
				
			||||
 | 
					            throw new Exception("当前查询数据未入库,请调整参数查询"); | 
				
			||||
 | 
					        } | 
				
			||||
 | 
					        List<Date> time = dataRepository.findForecastTime(keyspace, tableName, initialTime); | 
				
			||||
 | 
					        SimpleDateFormat convertSdf = new SimpleDateFormat(TimeConstant.YYYYMMDDHHMMSS_STR); | 
				
			||||
 | 
					        return time.stream().map(t -> convertSdf.format(t)).sorted().collect(Collectors.toList()); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    private PointValueVo toPointValueVo(LocalDateTime initialTime, LocalDateTime forecastTime, MetaInfo metaInfo, List<PointValue> pointValues){ | 
				
			||||
 | 
					        PointValueVo pointValueVo = new PointValueVo(); | 
				
			||||
 | 
					        pointValueVo.setPointValues(pointValues); | 
				
			||||
 | 
					        pointValueVo.setMetaInfo(metaInfo); | 
				
			||||
 | 
					        pointValueVo.setInitialTime(initialTime); | 
				
			||||
 | 
					        pointValueVo.setTargetTime(forecastTime); | 
				
			||||
 | 
					        return pointValueVo; | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    private String toKeyspace(LocalDateTime initialTime){ | 
				
			||||
 | 
					        return "data_%s".formatted(initialTime.format(TimeConstant.YYYYMM)); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
@ -0,0 +1,38 @@ | 
				
			|||||
 | 
					package com.ping.chuan.apiservice.util; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					import lombok.Data; | 
				
			||||
 | 
					import lombok.NoArgsConstructor; | 
				
			||||
 | 
					import lombok.AllArgsConstructor; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					@Data | 
				
			||||
 | 
					@NoArgsConstructor | 
				
			||||
 | 
					@AllArgsConstructor | 
				
			||||
 | 
					public class RequestResult<T> { | 
				
			||||
 | 
					    private int error; | 
				
			||||
 | 
					    private String message; | 
				
			||||
 | 
					    private T data; | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    public static RequestResult success() { | 
				
			||||
 | 
					        return new RequestResult(0, null, null); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    public static RequestResult success(Object data) { | 
				
			||||
 | 
					        return new RequestResult(0, null, data); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    public static RequestResult success(String message, Object data){ | 
				
			||||
 | 
					        return new RequestResult(0, message, data); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    public static RequestResult fail() { | 
				
			||||
 | 
					        return new RequestResult(1, null, null); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    public static RequestResult fail(int code, String message) { | 
				
			||||
 | 
					        return new RequestResult(code, message, null); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					
 | 
				
			||||
 | 
					    public static RequestResult fail(String message) { | 
				
			||||
 | 
					        return new RequestResult(1, message, null); | 
				
			||||
 | 
					    } | 
				
			||||
 | 
					} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue