VectorController.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  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.PageDto;
  7. import com.fd.dto.StyleDto;
  8. import com.fd.entity.FileEntity;
  9. import com.fd.entity.OutputFileEntity;
  10. import com.fd.entity.StyleEntity;
  11. import com.fd.server.VectorServer;
  12. import com.fd.shiro.JWTUtil;
  13. import com.fd.thread.AsyncTask;
  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.apache.shiro.authz.annotation.RequiresRoles;
  21. import org.springframework.beans.factory.annotation.Autowired;
  22. import org.springframework.beans.factory.annotation.Value;
  23. import org.springframework.data.domain.Page;
  24. import org.springframework.web.bind.annotation.*;
  25. import org.springframework.web.multipart.MultipartFile;
  26. import javax.servlet.http.HttpServletRequest;
  27. import java.io.File;
  28. import java.util.Arrays;
  29. import java.util.Date;
  30. import java.util.List;
  31. import java.util.Map;
  32. import java.util.concurrent.BlockingQueue;
  33. import java.util.concurrent.LinkedBlockingQueue;
  34. import java.util.concurrent.TimeUnit;
  35. import java.util.concurrent.atomic.AtomicInteger;
  36. /**
  37. * Created by Owen on 2019/11/12 0012 9:40
  38. * <p>
  39. * 矢量数据
  40. */
  41. @Log4j2
  42. @RequestMapping("api/vector")
  43. @RestController
  44. public class VectorController {
  45. @Value("${input.file.path.vector}")
  46. private String INPUT_FILE_PATH;
  47. @Value("${output.file.path.vector}")
  48. private String OUTPUT_FILE_PATH;
  49. @Autowired
  50. private VectorServer vectorServer;
  51. @Autowired
  52. private AsyncTask asyncTask;
  53. /**
  54. * 需要坐标转换
  55. * CGCS_2000
  56. */
  57. private static int COORD_CONVERT_CGCS_2000 = 1000;
  58. /**
  59. * 需要坐标转换
  60. * _XIAN_1980
  61. */
  62. private static int COORD_CONVERT_XIAN_1980 = 1001;
  63. /**
  64. * 不需要坐标转换
  65. * WGS84
  66. */
  67. private static int COORD_NOT_WGS84 = 0;
  68. private static BlockingQueue<Integer> vectorCoordQueue = new LinkedBlockingQueue<Integer>(2);
  69. private static BlockingQueue<Integer> vectorSliceQueue = new LinkedBlockingQueue<Integer>(2);
  70. /**
  71. * 保证线程安全的
  72. */
  73. private static AtomicInteger coordCount = new AtomicInteger();
  74. private static AtomicInteger sliceCount = new AtomicInteger();
  75. @ApiOperation("精准查询, fileName:字段名,value:字段值")
  76. @GetMapping("wfs/accurate/{fileId}/{fileName}/{value}/")
  77. public R wfsAccurate(@PathVariable("fileName") String fileName, @PathVariable("value") String value, @PathVariable("fileId") Long fileId){
  78. return vectorServer.wfsAccurate(fileId, fileName, value);
  79. }
  80. @ApiOperation("模糊查询, fileName:字段名,value:字段值")
  81. @GetMapping("wfs/like/{fileId}/{fileName}/{value}/")
  82. public R wfsLike(@PathVariable("fileName") String fileName, @PathVariable("value") String value, @PathVariable("fileId") Long fileId){
  83. return vectorServer.wfsLike(fileId, fileName, value);
  84. }
  85. // @xMin @yMin @xMax @yMax
  86. @ApiOperation("范围查询, xMin,yMin:最小值,xMax,yMax:最大值")
  87. @GetMapping("wfs/scope/{fileId}/{xMin}/{yMin}/{xMax}/{yMax}/")
  88. public R wfsScope(@PathVariable("fileId") Long fileId,
  89. @PathVariable("xMin") String xMin,
  90. @PathVariable("yMin") String yMin,
  91. @PathVariable("xMax") String xMax,
  92. @PathVariable("yMax") String yMax){
  93. return vectorServer.wfsScope(fileId, xMin, yMin, xMax, yMax);
  94. }
  95. @ApiOperation("上传矢量数据, coord:坐标(可以为空), 坐标格式:0,0,0,0,0,0,0")
  96. @PostMapping(value = "uploadMult/{directoryName}", consumes = {"multipart/form-data"})
  97. public R uploadMult(@RequestParam("file") MultipartFile[] file,
  98. @PathVariable("directoryName") String directoryName,
  99. @RequestParam(value = "coord", required = false) String[] coord, HttpServletRequest req) {
  100. log.info("run uploadMult");
  101. log.info("coord: {}", Arrays.toString(coord));
  102. String token = req.getHeader("Authorization");
  103. // 文件是否包含中文字符
  104. if (RegexUtils.regexChinese(directoryName)) {
  105. return new R(51005, MsgCode.E51005);
  106. }
  107. List<FileEntity> directory = vectorServer.findByDirectory(directoryName);
  108. if (directory.size() > 0) {
  109. return new R(51006, MsgCode.E51006);
  110. }
  111. String strCoord = Arrays.toString(coord);
  112. R r = vectorServer.uploadDirectoryFileMul(file, directoryName, strCoord, token);
  113. // 判断文件是否有错误
  114. if (r.getStatus() != 200) {
  115. return new R(r.getStatus(), r.getMessage());
  116. }
  117. OutputFileEntity entity = (OutputFileEntity) r.getData();
  118. // 判断坐标
  119. entity = JudgeCoord(entity, vectorServer);
  120. return new R(200, entity);
  121. }
  122. /**
  123. * 上传后判断坐标,显示原始坐标
  124. *
  125. * @return
  126. */
  127. private OutputFileEntity JudgeCoord(OutputFileEntity entity, VectorServer vectorServer) {
  128. // 判断是否需要坐标转换
  129. String cmd = Command.VECTOR_JUDGE_COORD;
  130. cmd = cmd.replace("@inputFile", entity.getUploadPath());
  131. log.info("cmd: {}", cmd);
  132. Map map = vectorServer.cmdJudgeCoord(cmd);
  133. Integer code = (int) map.get("code");
  134. log.info("judgeCoord code: {}", code);
  135. // 转换坐标 普通坐标转换
  136. if (code == COORD_CONVERT_CGCS_2000) {
  137. // 普通坐标转换
  138. log.info("need to general transform");
  139. entity.setCoordType(TypeCode.COORD_SYSTEM_2000);
  140. } else if (code == COORD_CONVERT_XIAN_1980) {
  141. // 严格坐标转换 (西安80转wgs84),需要参数
  142. log.info("need to strict transform, code: {}", code);
  143. entity.setCoordType(TypeCode.COORD_XIAN_1980);
  144. } else if (0 == COORD_NOT_WGS84) {
  145. // 不转换坐标 把文件信息移动到CoordStrictPath 这路径下
  146. log.info("not to transform");
  147. entity.setCoordType(TypeCode.COORD_WGS84);
  148. } else {
  149. log.info("error exeCmd");
  150. entity.setStatus(7);
  151. }
  152. entity.setUpdateTime(new Date());
  153. vectorServer.save(entity);
  154. // 保存经纬度
  155. StyleEntity styleEntity = new StyleEntity();
  156. styleEntity.setOutputFileId(entity.getId());
  157. styleEntity.setCreateTime(new Date());
  158. styleEntity.setUpdateTime(new Date());
  159. styleEntity.setLongitude(map.get("longitude") + "");
  160. styleEntity.setLatitude(map.get("latitude") + "");
  161. vectorServer.saveStyle(styleEntity);
  162. return entity;
  163. }
  164. @ApiOperation("获取矢量数据列表")
  165. @PostMapping(value = "list")
  166. public R list(@RequestBody PageDto param, HttpServletRequest req) {
  167. String token = req.getHeader("Authorization");
  168. Page<OutputFileEntity> list = vectorServer.findByList(TypeCode.FILE_TYPE_VECTOR, param, token);
  169. return new R(200, list);
  170. }
  171. /**
  172. * 删除文件
  173. */
  174. @ApiOperation("删除文件")
  175. @GetMapping("delete/{fileId}/")
  176. public R deleteFile(@PathVariable("fileId") Long fileId) {
  177. log.info("run deleteFile: {}", fileId);
  178. OutputFileEntity entity = vectorServer.findById(fileId);
  179. entity.setResStatus(1);
  180. vectorServer.save(entity);
  181. FileEntity fileEntity = vectorServer.findByInputFileId(entity.getUploadId());
  182. fileEntity.setResStatus(1);
  183. fileEntity = vectorServer.saveInputFile(fileEntity);
  184. asyncTask.vectorDelete(fileId, vectorServer);
  185. log.info("end delete vector id");
  186. return new R(200, MsgCode.SUCCESS);
  187. }
  188. @ApiOperation("矢量数据判断坐标")
  189. @GetMapping("command/judge/coord/{fileId}/")
  190. public R cmdJudgeCoord(@PathVariable("fileId") Long fileId) {
  191. log.info("run cmdJudgeCoord: {}", fileId);
  192. OutputFileEntity entity = vectorServer.findById(fileId);
  193. // 判断是否需要坐标转换
  194. String cmd = Command.VECTOR_JUDGE_COORD;
  195. cmd = cmd.replace("@inputFile", entity.getUploadPath());
  196. log.info("cmd: {}", cmd);
  197. entity.setUpdateTime(new Date());
  198. entity.setStatus(9);
  199. entity = vectorServer.save(entity);
  200. // 把数据放入队列中
  201. boolean offer = false;
  202. try {
  203. offer = vectorCoordQueue.offer(coordCount.incrementAndGet(), 1, TimeUnit.SECONDS);
  204. log.info("入队成功");
  205. } catch (Exception e) {
  206. log.error("error vector producer queue cmdJudgeCoord: {}", e);
  207. e.printStackTrace();
  208. }
  209. if (offer){
  210. entity.setUpdateTime(new Date());
  211. entity.setStatus(9);
  212. entity = vectorServer.save(entity);
  213. asyncTask.vectorConvertCoordThread(vectorCoordQueue, vectorServer, OUTPUT_FILE_PATH, entity);
  214. return new R(200, entity);
  215. }
  216. return new R(52000, MsgCode.E52000);
  217. }
  218. @ApiOperation("矢量数据转geojson")
  219. @GetMapping("command/geojson/{fileId}/")
  220. public R cmdGeojson(@PathVariable("fileId") Long fileId) {
  221. log.info("run cmdGeojson: {}", fileId);
  222. OutputFileEntity entity = vectorServer.findById(fileId);
  223. String fileName = StringUtils.substringBefore(entity.getFileName(), ".");
  224. // 截取目录名称
  225. log.info("json path: {}", OUTPUT_FILE_PATH);
  226. String outPath = OUTPUT_FILE_PATH + "geojson" + File.separator + entity.getDirectory();
  227. FileUtils.createDir(outPath);
  228. outPath = outPath + File.separator + fileName + ".json";
  229. String cmd = Command.VECTOR_TO_GEOJSON;
  230. if (entity.getCoordStrictPath() != null) {
  231. cmd = cmd.replace("@inputFile", entity.getCoordStrictPath());
  232. }
  233. cmd = cmd.replace("@outputFile", outPath);
  234. log.info("cmd: {}", cmd);
  235. Integer integer = vectorServer.exeCmd(cmd);
  236. if (integer != 0) {
  237. return new R(50005, MsgCode.E50005);
  238. }
  239. entity.setGeojsonPath(outPath);
  240. entity.setUpdateTime(new Date());
  241. entity.setStatus(4);
  242. entity = vectorServer.save(entity);
  243. return new R(200, entity);
  244. }
  245. @ApiOperation("矢量数据切片")
  246. @GetMapping("command/slice/{fileId}/{layerMin}/{layerMax}/")
  247. public R cmdSlice(@PathVariable("fileId") Long fileId, @PathVariable("layerMin") String layerMin, @PathVariable("layerMax") String layerMax) {
  248. log.info("run cmdSlice: {}", fileId);
  249. if (!RegexUtils.regexInt(layerMin)) {
  250. return new R(50010, MsgCode.E50010);
  251. }
  252. if (!RegexUtils.regexInt(layerMax)) {
  253. return new R(50010, MsgCode.E50010);
  254. }
  255. OutputFileEntity entity = vectorServer.findById(fileId);
  256. String outPath = OUTPUT_FILE_PATH + "slice" + File.separator + entity.getDirectory();
  257. FileUtils.createDir(outPath);
  258. String cmd = Command.VECTOR_SLICE_TIPPECANOE;
  259. cmd = cmd.replace("@inputFile", entity.getGeojsonPath());
  260. cmd = cmd.replace("@outputFile", outPath);
  261. cmd = cmd.replace("@layerMin", layerMin);
  262. cmd = cmd.replace("@layerMax", layerMax);
  263. log.info("cmd: {}", cmd);
  264. // 把数据放入队列中
  265. boolean offer = false;
  266. try {
  267. offer = vectorSliceQueue.offer(sliceCount.incrementAndGet(), 1, TimeUnit.SECONDS);
  268. log.info("vector slice 入队成功");
  269. } catch (Exception e) {
  270. log.error("error producer queue raster cmdSlice: {}", e);
  271. e.printStackTrace();
  272. }
  273. if (offer) {
  274. entity.setSlicePath(outPath);
  275. entity.setUpdateTime(new Date());
  276. // 6:切片中
  277. entity.setStatus(6);
  278. entity.setLayerMin(Integer.valueOf(layerMin));
  279. entity.setLayerMax(Integer.valueOf(layerMax));
  280. entity = vectorServer.save(entity);
  281. asyncTask.vectorSliceThread(vectorSliceQueue, vectorServer, entity, cmd);
  282. return new R(200, entity);
  283. }
  284. return new R(52000, MsgCode.E52000);
  285. }
  286. @ApiOperation("矢量数据进度查询")
  287. @GetMapping("progress/{fileId}/")
  288. public R getProgress(@PathVariable("fileId") Long fileId) {
  289. OutputFileEntity entity = vectorServer.findById(fileId);
  290. return new R(200, entity);
  291. }
  292. @RequiresRoles("admin")
  293. @ApiOperation("移动数据到服务器上")
  294. @PostMapping("move/{fileId}/")
  295. public R moveFile(@PathVariable("fileId") Long fileId, @RequestBody ConfigJsonDto param) {
  296. log.info("run moveFile: {}", fileId);
  297. return vectorServer.moveFileToServer(fileId, param);
  298. }
  299. @ApiOperation("保存样式")
  300. @PostMapping("style/save/")
  301. public R saveStyle(@RequestBody StyleDto param) {
  302. log.info("run saveStyle");
  303. return vectorServer.editStyle(param);
  304. }
  305. @ApiOperation("获取样式")
  306. @GetMapping("style/get/{fileId}/")
  307. public R getStyle(@PathVariable("fileId") Long fileId) {
  308. log.info("run getStyle: {}", fileId);
  309. return vectorServer.getStyle(fileId);
  310. }
  311. }