RasterController.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. package com.fd.controller;
  2. import com.fd.constant.Command;
  3. import com.fd.constant.MsgCode;
  4. import com.fd.constant.TypeCode;
  5. import com.fd.dto.ConfigJsonDto;
  6. import com.fd.dto.MyQueue;
  7. import com.fd.dto.PageDto;
  8. import com.fd.entity.FileEntity;
  9. import com.fd.entity.OutputFileEntity;
  10. import com.fd.server.CmdServer;
  11. import com.fd.server.RasterServer;
  12. import com.fd.util.FileUtils;
  13. import com.fd.util.R;
  14. import com.fd.util.RegexUtils;
  15. import io.swagger.annotations.ApiOperation;
  16. import lombok.extern.log4j.Log4j2;
  17. import org.apache.commons.lang3.StringUtils;
  18. import org.springframework.beans.factory.annotation.Autowired;
  19. import org.springframework.beans.factory.annotation.Value;
  20. import org.springframework.web.bind.annotation.*;
  21. import org.springframework.web.multipart.MultipartFile;
  22. import javax.annotation.PostConstruct;
  23. import java.io.File;
  24. import java.util.Arrays;
  25. import java.util.Date;
  26. import java.util.List;
  27. import java.util.concurrent.BlockingQueue;
  28. import java.util.concurrent.LinkedBlockingQueue;
  29. import java.util.concurrent.TimeUnit;
  30. /**
  31. * Created by Owen on 2019/11/12 0012 9:40
  32. *
  33. * 栅格数据
  34. */
  35. @Log4j2
  36. @RequestMapping("api/raster")
  37. @RestController
  38. public class RasterController {
  39. @Value("${input.file.path.raster}")
  40. private String INPUT_FILE_PATH;
  41. @Value("${output.file.path.raster}")
  42. private String OUTPUT_FILE_PATH;
  43. @Autowired
  44. private CmdServer cmdServer;
  45. @Autowired
  46. private RasterServer rasterServer;
  47. BlockingQueue<MyQueue> sliceQueue = new LinkedBlockingQueue<MyQueue>(5);
  48. BlockingQueue<MyQueue> coordQueue = new LinkedBlockingQueue<MyQueue>(5);
  49. /**
  50. * 初始化队列
  51. *
  52. * @return
  53. */
  54. @PostConstruct
  55. private void init() {
  56. // 判断坐标消费队列
  57. new Thread(new JudgeCoordConsumerThread(coordQueue)).start();
  58. // 切片消费队列
  59. new Thread(new SliceConsumerThread(sliceQueue)).start();
  60. }
  61. @ApiOperation("上传数据,校验文件名")
  62. @GetMapping("check/{fileName}/")
  63. private R checkFileName(@PathVariable("fileName") String fileName) {
  64. log.info("run checkFileName: {}",fileName);
  65. // 文件是否包含中文字符
  66. if (RegexUtils.regexChinese(fileName)) {
  67. return new R(51005, MsgCode.E51005);
  68. }
  69. String s = StringUtils.substringAfterLast(fileName, ".");
  70. if (!"tif".equals(s)) {
  71. return new R(50008,MsgCode.E50008);
  72. }
  73. List<FileEntity> list = rasterServer.findByFileName(fileName);
  74. if (list.size() > 0) {
  75. return new R(51006, MsgCode.E51006);
  76. }
  77. return new R(200, MsgCode.SUCCESS);
  78. }
  79. @ApiOperation("上传栅格数据,只能上传tif文件")
  80. @PostMapping(value = "upload", consumes = { "multipart/form-data" })
  81. private R upload(@RequestParam("file") MultipartFile file, @RequestParam(value = "coord",required = false) String[] coord){
  82. log.info("run upload");
  83. log.info("coord: {}", Arrays.toString(coord));
  84. String strCoord = Arrays.toString(coord);
  85. // 文件名全名
  86. String fileName = file.getOriginalFilename();
  87. // 文件是否包含中文字符
  88. if (RegexUtils.regexChinese(fileName)) {
  89. return new R(51005, MsgCode.E51005);
  90. }
  91. String s = StringUtils.substringAfterLast(fileName, ".");
  92. if (!"tif".equals(s)) {
  93. return new R(50008,MsgCode.E50008);
  94. }
  95. List<FileEntity> list = rasterServer.findByFileName(fileName);
  96. if (list.size() > 0) {
  97. return new R(51006, MsgCode.E51006);
  98. }
  99. R r = rasterServer.uploadBigFile(file, strCoord);
  100. OutputFileEntity entity = (OutputFileEntity) r.getData();
  101. // 判断坐标
  102. entity = JudgeCoord(entity);
  103. return new R(200, entity);
  104. }
  105. /**
  106. * 上传后判断坐标,显示原始坐标
  107. * @return
  108. */
  109. private OutputFileEntity JudgeCoord(OutputFileEntity entity){
  110. String cmd = Command.RASTER_JUDGE_COORD;
  111. cmd = cmd.replace("@inputFile", entity.getUploadPath());
  112. log.info("cmd: {}", cmd);
  113. Integer isJudge = cmdServer.exeCmdRasterJudgeCoord(cmd);
  114. if (1000 == isJudge){
  115. log.info("need to transform");
  116. // 严格坐标转换
  117. entity.setCoordType(TypeCode.COORD_XIAN_1980);
  118. } else if (0 == isJudge){
  119. log.info("not to transform");
  120. entity.setCoordType(TypeCode.COORD_WGS84);
  121. } else {
  122. log.info("error exeCmd");
  123. entity.setStatus(7);
  124. }
  125. entity.setUpdateTime(new Date());
  126. rasterServer.save(entity);
  127. return entity;
  128. }
  129. @ApiOperation("获取栅格数据列表")
  130. @PostMapping(value = "list")
  131. private R list(@RequestBody PageDto param){
  132. return rasterServer.findByType(TypeCode.FILE_TYPE_RASTER, param);
  133. }
  134. /**
  135. * 删除文件
  136. */
  137. @ApiOperation("删除文件")
  138. @GetMapping("delete/{fileId}/")
  139. private R deleteFile(@PathVariable("fileId") Long fileId) {
  140. log.info("run deleteFile: {}", fileId);
  141. return rasterServer.deleteById(fileId);
  142. }
  143. @ApiOperation("栅格数据判断坐标")
  144. @GetMapping("command/judge/coord/{fileId}/")
  145. private R cmdJudgeCoord(@PathVariable("fileId") Long fileId) {
  146. log.info("run cmdJudgeCoord: {}", fileId);
  147. OutputFileEntity entity = rasterServer.findById(fileId);
  148. entity.setStatus(9);
  149. entity.setUpdateTime(new Date());
  150. entity = rasterServer.save(entity);
  151. String cmd = Command.RASTER_JUDGE_COORD;
  152. cmd = cmd.replace("@inputFile", entity.getUploadPath());
  153. log.info("cmd: {}", cmd);
  154. // 把数据放入队列中
  155. MyQueue data = new MyQueue();
  156. data.setOutputFile(entity);
  157. data.setStr(cmd);
  158. try {
  159. coordQueue.offer(data, 1, TimeUnit.SECONDS);
  160. log.info("入队成功");
  161. } catch (Exception e) {
  162. log.error("error producer queue raster cmdJudgeCoord: {}", e);
  163. e.printStackTrace();
  164. }
  165. return new R(200, entity);
  166. }
  167. /**
  168. * 坐标转换消费队列
  169. */
  170. public class JudgeCoordConsumerThread implements Runnable{
  171. private BlockingQueue<MyQueue> queue;
  172. private boolean isRun = true;
  173. public JudgeCoordConsumerThread(BlockingQueue<MyQueue> queue){
  174. this.queue = queue;
  175. }
  176. @Override
  177. public void run() {
  178. log.warn("run JudgeCoordConsumerThread");
  179. while (true) {
  180. OutputFileEntity entity = null;
  181. try {
  182. MyQueue data = queue.poll(2, TimeUnit.SECONDS);
  183. if (data != null) {
  184. log.info("消费者,拿到队列中的数据data:" + data.toString());
  185. Integer isJudge = cmdServer.exeCmdRasterJudgeCoord(data.getStr());
  186. entity = data.getOutputFile();
  187. if (1000 == isJudge){
  188. log.info("need to transform");
  189. // 严格坐标转换
  190. entity = cmdTansformGdalwarpStrict(entity);
  191. } else if (0 == isJudge){
  192. log.info("not to transform");
  193. // 4:未切片
  194. entity.setStatus(4);
  195. // 不需要转,就把上传文件路径复制到严格坐标路径上
  196. entity.setCoordStrictPath(entity.getUploadPath());
  197. entity.setUpdateTime(new Date());
  198. rasterServer.save(entity);
  199. } else {
  200. log.info("error exeCmd");
  201. entity.setStatus(0);
  202. entity.setUpdateTime(new Date());
  203. rasterServer.save(entity);
  204. }
  205. }
  206. } catch (Exception e) {
  207. log.error("error consume queue raster JudgeCoordConsumerThread: {}", e);
  208. e.printStackTrace();
  209. }
  210. }
  211. }
  212. }
  213. @ApiOperation("栅格数据切片命令")
  214. @GetMapping("command/osgeo/{fileId}/{layerMin}/{layerMax}/")
  215. private R cmdSlice(@PathVariable("fileId") Long fileId, @PathVariable("layerMin") String layerMin, @PathVariable("layerMax") String layerMax) {
  216. log.info("run cmdSlice: {}", fileId);
  217. if (!RegexUtils.regexInt(layerMin)){
  218. return new R(50010, MsgCode.E50010) ;
  219. }
  220. if (!RegexUtils.regexInt(layerMax)){
  221. return new R(50010, MsgCode.E50010) ;
  222. }
  223. OutputFileEntity entity = rasterServer.findById(fileId);
  224. String fileName = StringUtils.substringBeforeLast(entity.getFileName(), ".");
  225. String outFilePath = OUTPUT_FILE_PATH + "slice" + File.separator + fileName;
  226. FileUtils.createDir(outFilePath);
  227. String cmd = Command.RASTER_SLICE_OSGEO;
  228. cmd = cmd.replace("@inputFile", entity.getCoordStrictPath());
  229. cmd = cmd.replace("@outputFile", outFilePath);
  230. cmd = cmd.replace("@layerMin", layerMin);
  231. cmd = cmd.replace("@layerMax", layerMax);
  232. log.info("cmd: {}", cmd);
  233. // 设个默认进度给前端显示
  234. entity.setProgress(1);
  235. entity.setStatus(6);
  236. entity.setLayerMin(Integer.valueOf(layerMin));
  237. entity.setLayerMax(Integer.valueOf(layerMax));
  238. entity.setUpdateTime(new Date());
  239. entity.setSlicePath(outFilePath);
  240. entity = rasterServer.save(entity);
  241. // 把数据放入队列中
  242. MyQueue data = new MyQueue();
  243. data.setOutputFile(entity);
  244. data.setStr(cmd);
  245. try {
  246. sliceQueue.offer(data, 1, TimeUnit.SECONDS);
  247. log.info("入队成功");
  248. } catch (Exception e) {
  249. log.error("error producer queue raster cmdSlice: {}", e);
  250. e.printStackTrace();
  251. }
  252. return new R(200, entity) ;
  253. }
  254. /**
  255. * 切片消费队列
  256. */
  257. public class SliceConsumerThread implements Runnable{
  258. private BlockingQueue<MyQueue> queue;
  259. private boolean isRun = true;
  260. public SliceConsumerThread(BlockingQueue<MyQueue> queue){
  261. this.queue = queue;
  262. }
  263. @Override
  264. public void run() {
  265. log.warn("run SliceConsumerThread");
  266. while (isRun) {
  267. OutputFileEntity entity = null;
  268. try {
  269. MyQueue data = queue.poll(2, TimeUnit.SECONDS);
  270. if (data != null) {
  271. log.info("消费者,拿到队列中的数据data:" + data.toString());
  272. entity = data.getOutputFile();
  273. Integer integer = cmdServer.exeCmdRasterSlice(data.getStr(), entity);
  274. if (integer != 0) {
  275. log.info("error command exeCmdRasterSlice");
  276. // 如果命令运行失败,状态改为0
  277. entity.setStatus(0);
  278. entity.setUpdateTime(new Date());
  279. rasterServer.save(entity);
  280. return;
  281. }
  282. // 切片完成,修改完成状态
  283. entity.setStatus(5);
  284. entity.setUpdateTime(new Date());
  285. entity = rasterServer.save(entity);
  286. log.info("entity: {}", entity.toString());
  287. }
  288. } catch (Exception e) {
  289. log.error("error consume queue raster SliceConsumerThread: {}", e);
  290. e.printStackTrace();
  291. }
  292. }
  293. }
  294. }
  295. @ApiOperation("栅格数据进度查询")
  296. @GetMapping("progress/{fileId}/")
  297. private R getProgress(@PathVariable("fileId") Long fileId) {
  298. // log.info("run getProgress: {}", fileId);
  299. OutputFileEntity entity = rasterServer.findById(fileId);
  300. return new R(200, entity);
  301. }
  302. @ApiOperation("移动数据到服务器上")
  303. @PostMapping("move/{fileId}/")
  304. private R moveFile(@PathVariable("fileId") Long fileId, @RequestBody ConfigJsonDto param) {
  305. log.info("run moveFile: {}", fileId);
  306. return rasterServer.moveFileToServer(fileId, param);
  307. }
  308. /**
  309. * 严格坐标转换
  310. */
  311. private OutputFileEntity cmdTansformGdalwarpStrict(OutputFileEntity entity){
  312. log.info("run cmdTansformGdalwarpStrict");
  313. String fileName = StringUtils.substringBeforeLast(entity.getFileName(), ".");
  314. String outFileStep1 = OUTPUT_FILE_PATH + "transform";
  315. FileUtils.createDir(outFileStep1);
  316. outFileStep1 = outFileStep1 + File.separator + entity.getFileName();
  317. // 坐标处理
  318. String coord = entity.getCoord();
  319. String step_1 = Command.RASTER_TRANSFORM_GDALWARP_STRICT_1;
  320. String step_2 = Command.RASTER_TRANSFORM_GDALWARP_STRICT_2;
  321. step_1 = step_1.replace("@inputFile", entity.getUploadPath());
  322. step_1 = step_1.replace("@outputFile", outFileStep1);
  323. String outFileStep2 = OUTPUT_FILE_PATH + "transform_strict";
  324. FileUtils.createDir(outFileStep2);
  325. outFileStep2 = outFileStep2 + File.separator + entity.getFileName();
  326. step_2 = step_2.replace("@inputFile", outFileStep1);
  327. step_2 = step_2.replace("@outputFile", outFileStep2);
  328. log.info("cmd1: {}", step_1);
  329. log.info("cmd2: {}", step_2);
  330. Integer integer = cmdServer.exeCmd(step_1, step_2);
  331. if (integer != 0) {
  332. log.info("error command transform");
  333. return null;
  334. }
  335. entity.setStatus(4);
  336. entity.setUpdateTime(new Date());
  337. entity.setCoordGeneralPath(outFileStep1);
  338. entity.setCoordStrictPath(outFileStep2);
  339. entity = rasterServer.save(entity);
  340. return entity;
  341. }
  342. public static void main(String[] args) {
  343. String [] a = {"1.1","1.2","1.3"};
  344. List<String> list = Arrays.asList(a);
  345. System.out.println(list.get(1));
  346. }
  347. }