package com.fd.controller; import com.fd.constant.Command; import com.fd.constant.MsgCode; import com.fd.constant.TypeCode; import com.fd.dto.ConfigJsonDto; import com.fd.dto.MyQueue; import com.fd.dto.PageDto; import com.fd.entity.FileEntity; import com.fd.entity.OutputFileEntity; import com.fd.server.CmdServer; import com.fd.server.RasterServer; import com.fd.util.FileUtils; import com.fd.util.R; import com.fd.util.RegexUtils; import io.swagger.annotations.ApiOperation; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.PostConstruct; import java.io.File; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; /** * Created by Owen on 2019/11/12 0012 9:40 * * 栅格数据 */ @Log4j2 @RequestMapping("api/raster") @RestController public class RasterController { @Value("${input.file.path.raster}") private String INPUT_FILE_PATH; @Value("${output.file.path.raster}") private String OUTPUT_FILE_PATH; @Autowired private CmdServer cmdServer; @Autowired private RasterServer rasterServer; BlockingQueue sliceQueue = new LinkedBlockingQueue(5); BlockingQueue coordQueue = new LinkedBlockingQueue(5); /** * 初始化队列 * * @return */ @PostConstruct private void init() { // 判断坐标消费队列 new Thread(new JudgeCoordConsumerThread(coordQueue)).start(); // 切片消费队列 new Thread(new SliceConsumerThread(sliceQueue)).start(); } @ApiOperation("上传数据,校验文件名") @GetMapping("check/{fileName}/") private R checkFileName(@PathVariable("fileName") String fileName) { log.info("run checkFileName: {}",fileName); // 文件是否包含中文字符 if (RegexUtils.regexChinese(fileName)) { return new R(51005, MsgCode.E51005); } String s = StringUtils.substringAfterLast(fileName, "."); if (!"tif".equals(s)) { return new R(50008,MsgCode.E50008); } List list = rasterServer.findByFileName(fileName); if (list.size() > 0) { return new R(51006, MsgCode.E51006); } return new R(200, MsgCode.SUCCESS); } @ApiOperation("上传栅格数据,只能上传tif文件") @PostMapping(value = "upload", consumes = { "multipart/form-data" }) private R upload(@RequestParam("file") MultipartFile file, @RequestParam(value = "coord",required = false) String[] coord){ log.info("run upload"); log.info("coord: {}", Arrays.toString(coord)); String strCoord = Arrays.toString(coord); // 文件名全名 String fileName = file.getOriginalFilename(); // 文件是否包含中文字符 if (RegexUtils.regexChinese(fileName)) { return new R(51005, MsgCode.E51005); } String s = StringUtils.substringAfterLast(fileName, "."); if (!"tif".equals(s)) { return new R(50008,MsgCode.E50008); } List list = rasterServer.findByFileName(fileName); if (list.size() > 0) { return new R(51006, MsgCode.E51006); } R r = rasterServer.uploadBigFile(file, strCoord); OutputFileEntity entity = (OutputFileEntity) r.getData(); // 判断坐标 entity = JudgeCoord(entity); return new R(200, entity); } /** * 上传后判断坐标,显示原始坐标 * @return */ private OutputFileEntity JudgeCoord(OutputFileEntity entity){ String cmd = Command.RASTER_JUDGE_COORD; cmd = cmd.replace("@inputFile", entity.getUploadPath()); log.info("cmd: {}", cmd); Integer isJudge = cmdServer.exeCmdRasterJudgeCoord(cmd); if (1000 == isJudge){ log.info("need to transform"); // 严格坐标转换 entity.setCoordType(TypeCode.COORD_XIAN_1980); } else if (0 == isJudge){ log.info("not to transform"); entity.setCoordType(TypeCode.COORD_WGS84); } else { log.info("error exeCmd"); entity.setStatus(7); } entity.setUpdateTime(new Date()); rasterServer.save(entity); return entity; } @ApiOperation("获取栅格数据列表") @PostMapping(value = "list") private R list(@RequestBody PageDto param){ return rasterServer.findByType(TypeCode.FILE_TYPE_RASTER, param); } /** * 删除文件 */ @ApiOperation("删除文件") @GetMapping("delete/{fileId}/") private R deleteFile(@PathVariable("fileId") Long fileId) { log.info("run deleteFile: {}", fileId); return rasterServer.deleteById(fileId); } @ApiOperation("栅格数据判断坐标") @GetMapping("command/judge/coord/{fileId}/") private R cmdJudgeCoord(@PathVariable("fileId") Long fileId) { log.info("run cmdJudgeCoord: {}", fileId); OutputFileEntity entity = rasterServer.findById(fileId); entity.setStatus(9); entity.setUpdateTime(new Date()); entity = rasterServer.save(entity); String cmd = Command.RASTER_JUDGE_COORD; cmd = cmd.replace("@inputFile", entity.getUploadPath()); log.info("cmd: {}", cmd); // 把数据放入队列中 MyQueue data = new MyQueue(); data.setOutputFile(entity); data.setStr(cmd); try { coordQueue.offer(data, 1, TimeUnit.SECONDS); log.info("入队成功"); } catch (Exception e) { log.error("error producer queue raster cmdJudgeCoord: {}", e); e.printStackTrace(); } return new R(200, entity); } /** * 坐标转换消费队列 */ public class JudgeCoordConsumerThread implements Runnable{ private BlockingQueue queue; private boolean isRun = true; public JudgeCoordConsumerThread(BlockingQueue queue){ this.queue = queue; } @Override public void run() { log.warn("run JudgeCoordConsumerThread"); while (true) { OutputFileEntity entity = null; try { MyQueue data = queue.poll(2, TimeUnit.SECONDS); if (data != null) { log.info("消费者,拿到队列中的数据data:" + data.toString()); Integer isJudge = cmdServer.exeCmdRasterJudgeCoord(data.getStr()); entity = data.getOutputFile(); if (1000 == isJudge){ log.info("need to transform"); // 严格坐标转换 entity = cmdTansformGdalwarpStrict(entity); } else if (0 == isJudge){ log.info("not to transform"); // 4:未切片 entity.setStatus(4); // 不需要转,就把上传文件路径复制到严格坐标路径上 entity.setCoordStrictPath(entity.getUploadPath()); entity.setUpdateTime(new Date()); rasterServer.save(entity); } else { log.info("error exeCmd"); entity.setStatus(0); entity.setUpdateTime(new Date()); rasterServer.save(entity); } } } catch (Exception e) { log.error("error consume queue raster JudgeCoordConsumerThread: {}", e); e.printStackTrace(); } } } } @ApiOperation("栅格数据切片命令") @GetMapping("command/osgeo/{fileId}/{layerMin}/{layerMax}/") private R cmdSlice(@PathVariable("fileId") Long fileId, @PathVariable("layerMin") String layerMin, @PathVariable("layerMax") String layerMax) { log.info("run cmdSlice: {}", fileId); if (!RegexUtils.regexInt(layerMin)){ return new R(50010, MsgCode.E50010) ; } if (!RegexUtils.regexInt(layerMax)){ return new R(50010, MsgCode.E50010) ; } OutputFileEntity entity = rasterServer.findById(fileId); String fileName = StringUtils.substringBeforeLast(entity.getFileName(), "."); String outFilePath = OUTPUT_FILE_PATH + "slice" + File.separator + fileName; FileUtils.createDir(outFilePath); String cmd = Command.RASTER_SLICE_OSGEO; cmd = cmd.replace("@inputFile", entity.getCoordStrictPath()); cmd = cmd.replace("@outputFile", outFilePath); cmd = cmd.replace("@layerMin", layerMin); cmd = cmd.replace("@layerMax", layerMax); log.info("cmd: {}", cmd); // 设个默认进度给前端显示 entity.setProgress(1); entity.setStatus(6); entity.setLayerMin(Integer.valueOf(layerMin)); entity.setLayerMax(Integer.valueOf(layerMax)); entity.setUpdateTime(new Date()); entity.setSlicePath(outFilePath); entity = rasterServer.save(entity); // 把数据放入队列中 MyQueue data = new MyQueue(); data.setOutputFile(entity); data.setStr(cmd); try { sliceQueue.offer(data, 1, TimeUnit.SECONDS); log.info("入队成功"); } catch (Exception e) { log.error("error producer queue raster cmdSlice: {}", e); e.printStackTrace(); } return new R(200, entity) ; } /** * 切片消费队列 */ public class SliceConsumerThread implements Runnable{ private BlockingQueue queue; private boolean isRun = true; public SliceConsumerThread(BlockingQueue queue){ this.queue = queue; } @Override public void run() { log.warn("run SliceConsumerThread"); while (isRun) { OutputFileEntity entity = null; try { MyQueue data = queue.poll(2, TimeUnit.SECONDS); if (data != null) { log.info("消费者,拿到队列中的数据data:" + data.toString()); entity = data.getOutputFile(); Integer integer = cmdServer.exeCmdRasterSlice(data.getStr(), entity); if (integer != 0) { log.info("error command exeCmdRasterSlice"); // 如果命令运行失败,状态改为0 entity.setStatus(0); entity.setUpdateTime(new Date()); rasterServer.save(entity); return; } // 切片完成,修改完成状态 entity.setStatus(5); entity.setUpdateTime(new Date()); entity = rasterServer.save(entity); log.info("entity: {}", entity.toString()); } } catch (Exception e) { log.error("error consume queue raster SliceConsumerThread: {}", e); e.printStackTrace(); } } } } @ApiOperation("栅格数据进度查询") @GetMapping("progress/{fileId}/") private R getProgress(@PathVariable("fileId") Long fileId) { // log.info("run getProgress: {}", fileId); OutputFileEntity entity = rasterServer.findById(fileId); return new R(200, entity); } @ApiOperation("移动数据到服务器上") @PostMapping("move/{fileId}/") private R moveFile(@PathVariable("fileId") Long fileId, @RequestBody ConfigJsonDto param) { log.info("run moveFile: {}", fileId); return rasterServer.moveFileToServer(fileId, param); } /** * 严格坐标转换 */ private OutputFileEntity cmdTansformGdalwarpStrict(OutputFileEntity entity){ log.info("run cmdTansformGdalwarpStrict"); String fileName = StringUtils.substringBeforeLast(entity.getFileName(), "."); String outFileStep1 = OUTPUT_FILE_PATH + "transform"; FileUtils.createDir(outFileStep1); outFileStep1 = outFileStep1 + File.separator + entity.getFileName(); // 坐标处理 String coord = entity.getCoord(); String step_1 = Command.RASTER_TRANSFORM_GDALWARP_STRICT_1; String step_2 = Command.RASTER_TRANSFORM_GDALWARP_STRICT_2; step_1 = step_1.replace("@inputFile", entity.getUploadPath()); step_1 = step_1.replace("@outputFile", outFileStep1); String outFileStep2 = OUTPUT_FILE_PATH + "transform_strict"; FileUtils.createDir(outFileStep2); outFileStep2 = outFileStep2 + File.separator + entity.getFileName(); step_2 = step_2.replace("@inputFile", outFileStep1); step_2 = step_2.replace("@outputFile", outFileStep2); log.info("cmd1: {}", step_1); log.info("cmd2: {}", step_2); Integer integer = cmdServer.exeCmd(step_1, step_2); if (integer != 0) { log.info("error command transform"); return null; } entity.setStatus(4); entity.setUpdateTime(new Date()); entity.setCoordGeneralPath(outFileStep1); entity.setCoordStrictPath(outFileStep2); entity = rasterServer.save(entity); return entity; } public static void main(String[] args) { String [] a = {"1.1","1.2","1.3"}; List list = Arrays.asList(a); System.out.println(list.get(1)); } }