RasterController.java 18 KB

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