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.PageDto; import com.fd.dto.StyleDto; import com.fd.entity.FileEntity; import com.fd.entity.OutputFileEntity; import com.fd.entity.StyleEntity; import com.fd.server.VectorServer; import com.fd.shiro.JWTUtil; import com.fd.thread.AsyncTask; 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.apache.shiro.authz.annotation.RequiresRoles; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; /** * Created by Owen on 2019/11/12 0012 9:40 *

* 矢量数据 */ @Log4j2 @RequestMapping("api/vector") @RestController public class VectorController { @Value("${input.file.path.vector}") private String INPUT_FILE_PATH; @Value("${output.file.path.vector}") private String OUTPUT_FILE_PATH; @Autowired private VectorServer vectorServer; @Autowired private AsyncTask asyncTask; /** * 需要坐标转换 * CGCS_2000 */ private static int COORD_CONVERT_CGCS_2000 = 1000; /** * 需要坐标转换 * _XIAN_1980 */ private static int COORD_CONVERT_XIAN_1980 = 1001; /** * 不需要坐标转换 * WGS84 */ private static int COORD_NOT_WGS84 = 0; private static BlockingQueue vectorCoordQueue = new LinkedBlockingQueue(2); private static BlockingQueue vectorSliceQueue = new LinkedBlockingQueue(2); /** * 保证线程安全的 */ private static AtomicInteger coordCount = new AtomicInteger(); private static AtomicInteger sliceCount = new AtomicInteger(); @ApiOperation("精准查询, fileName:字段名,value:字段值") @GetMapping("wfs/accurate/{fileId}/{fileName}/{value}/") public R wfsAccurate(@PathVariable("fileName") String fileName, @PathVariable("value") String value, @PathVariable("fileId") Long fileId){ return vectorServer.wfsAccurate(fileId, fileName, value); } @ApiOperation("模糊查询, fileName:字段名,value:字段值") @GetMapping("wfs/like/{fileId}/{fileName}/{value}/") public R wfsLike(@PathVariable("fileName") String fileName, @PathVariable("value") String value, @PathVariable("fileId") Long fileId){ return vectorServer.wfsLike(fileId, fileName, value); } // @xMin @yMin @xMax @yMax @ApiOperation("范围查询, xMin,yMin:最小值,xMax,yMax:最大值") @GetMapping("wfs/scope/{fileId}/{xMin}/{yMin}/{xMax}/{yMax}/") public R wfsScope(@PathVariable("fileId") Long fileId, @PathVariable("xMin") String xMin, @PathVariable("yMin") String yMin, @PathVariable("xMax") String xMax, @PathVariable("yMax") String yMax){ return vectorServer.wfsScope(fileId, xMin, yMin, xMax, yMax); } @ApiOperation("上传矢量数据, coord:坐标(可以为空), 坐标格式:0,0,0,0,0,0,0") @PostMapping(value = "uploadMult/{directoryName}", consumes = {"multipart/form-data"}) public R uploadMult(@RequestParam("file") MultipartFile[] file, @PathVariable("directoryName") String directoryName, @RequestParam(value = "coord", required = false) String[] coord, HttpServletRequest req) { log.info("run uploadMult"); log.info("coord: {}", Arrays.toString(coord)); String token = req.getHeader("Authorization"); // 文件是否包含中文字符 if (RegexUtils.regexChinese(directoryName)) { return new R(51005, MsgCode.E51005); } List directory = vectorServer.findByDirectory(directoryName); if (directory.size() > 0) { return new R(51006, MsgCode.E51006); } String strCoord = Arrays.toString(coord); R r = vectorServer.uploadDirectoryFileMul(file, directoryName, strCoord, token); // 判断文件是否有错误 if (r.getStatus() != 200) { return new R(r.getStatus(), r.getMessage()); } OutputFileEntity entity = (OutputFileEntity) r.getData(); // 判断坐标 entity = JudgeCoord(entity, vectorServer); return new R(200, entity); } /** * 上传后判断坐标,显示原始坐标 * * @return */ private OutputFileEntity JudgeCoord(OutputFileEntity entity, VectorServer vectorServer) { // 判断是否需要坐标转换 String cmd = Command.VECTOR_JUDGE_COORD; cmd = cmd.replace("@inputFile", entity.getUploadPath()); log.info("cmd: {}", cmd); Map map = vectorServer.cmdJudgeCoord(cmd); Integer code = (int) map.get("code"); log.info("judgeCoord code: {}", code); // 转换坐标 普通坐标转换 if (code == COORD_CONVERT_CGCS_2000) { // 普通坐标转换 log.info("need to general transform"); entity.setCoordType(TypeCode.COORD_SYSTEM_2000); } else if (code == COORD_CONVERT_XIAN_1980) { // 严格坐标转换 (西安80转wgs84),需要参数 log.info("need to strict transform, code: {}", code); entity.setCoordType(TypeCode.COORD_XIAN_1980); } else if (0 == COORD_NOT_WGS84) { // 不转换坐标 把文件信息移动到CoordStrictPath 这路径下 log.info("not to transform"); entity.setCoordType(TypeCode.COORD_WGS84); } else { log.info("error exeCmd"); entity.setStatus(7); } entity.setUpdateTime(new Date()); vectorServer.save(entity); // 保存经纬度 StyleEntity styleEntity = new StyleEntity(); styleEntity.setOutputFileId(entity.getId()); styleEntity.setCreateTime(new Date()); styleEntity.setUpdateTime(new Date()); styleEntity.setLongitude(map.get("longitude") + ""); styleEntity.setLatitude(map.get("latitude") + ""); vectorServer.saveStyle(styleEntity); return entity; } @ApiOperation("获取矢量数据列表") @PostMapping(value = "list") public R list(@RequestBody PageDto param, HttpServletRequest req) { String token = req.getHeader("Authorization"); Page list = vectorServer.findByList(TypeCode.FILE_TYPE_VECTOR, param, token); return new R(200, list); } /** * 删除文件 */ @ApiOperation("删除文件") @GetMapping("delete/{fileId}/") public R deleteFile(@PathVariable("fileId") Long fileId) { log.info("run deleteFile: {}", fileId); OutputFileEntity entity = vectorServer.findById(fileId); entity.setResStatus(1); vectorServer.save(entity); FileEntity fileEntity = vectorServer.findByInputFileId(entity.getUploadId()); fileEntity.setResStatus(1); fileEntity = vectorServer.saveInputFile(fileEntity); asyncTask.vectorDelete(fileId, vectorServer); log.info("end delete vector id"); return new R(200, MsgCode.SUCCESS); } @ApiOperation("矢量数据判断坐标") @GetMapping("command/judge/coord/{fileId}/") public R cmdJudgeCoord(@PathVariable("fileId") Long fileId) { log.info("run cmdJudgeCoord: {}", fileId); OutputFileEntity entity = vectorServer.findById(fileId); // 判断是否需要坐标转换 String cmd = Command.VECTOR_JUDGE_COORD; cmd = cmd.replace("@inputFile", entity.getUploadPath()); log.info("cmd: {}", cmd); entity.setUpdateTime(new Date()); entity.setStatus(9); entity = vectorServer.save(entity); // 把数据放入队列中 boolean offer = false; try { offer = vectorCoordQueue.offer(coordCount.incrementAndGet(), 1, TimeUnit.SECONDS); log.info("入队成功"); } catch (Exception e) { log.error("error vector producer queue cmdJudgeCoord: {}", e); e.printStackTrace(); } if (offer){ entity.setUpdateTime(new Date()); entity.setStatus(9); entity = vectorServer.save(entity); asyncTask.vectorConvertCoordThread(vectorCoordQueue, vectorServer, OUTPUT_FILE_PATH, entity); return new R(200, entity); } return new R(52000, MsgCode.E52000); } @ApiOperation("矢量数据转geojson") @GetMapping("command/geojson/{fileId}/") public R cmdGeojson(@PathVariable("fileId") Long fileId) { log.info("run cmdGeojson: {}", fileId); OutputFileEntity entity = vectorServer.findById(fileId); String fileName = StringUtils.substringBefore(entity.getFileName(), "."); // 截取目录名称 log.info("json path: {}", OUTPUT_FILE_PATH); String outPath = OUTPUT_FILE_PATH + "geojson" + File.separator + entity.getDirectory(); FileUtils.createDir(outPath); outPath = outPath + File.separator + fileName + ".json"; String cmd = Command.VECTOR_TO_GEOJSON; if (entity.getCoordStrictPath() != null) { cmd = cmd.replace("@inputFile", entity.getCoordStrictPath()); } cmd = cmd.replace("@outputFile", outPath); log.info("cmd: {}", cmd); Integer integer = vectorServer.exeCmd(cmd); if (integer != 0) { return new R(50005, MsgCode.E50005); } entity.setGeojsonPath(outPath); entity.setUpdateTime(new Date()); entity.setStatus(4); entity = vectorServer.save(entity); return new R(200, entity); } @ApiOperation("矢量数据切片") @GetMapping("command/slice/{fileId}/{layerMin}/{layerMax}/") public 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 = vectorServer.findById(fileId); String outPath = OUTPUT_FILE_PATH + "slice" + File.separator + entity.getDirectory(); FileUtils.createDir(outPath); String cmd = Command.VECTOR_SLICE_TIPPECANOE; cmd = cmd.replace("@inputFile", entity.getGeojsonPath()); cmd = cmd.replace("@outputFile", outPath); cmd = cmd.replace("@layerMin", layerMin); cmd = cmd.replace("@layerMax", layerMax); log.info("cmd: {}", cmd); // 把数据放入队列中 boolean offer = false; try { offer = vectorSliceQueue.offer(sliceCount.incrementAndGet(), 1, TimeUnit.SECONDS); log.info("vector slice 入队成功"); } catch (Exception e) { log.error("error producer queue raster cmdSlice: {}", e); e.printStackTrace(); } if (offer) { entity.setSlicePath(outPath); entity.setUpdateTime(new Date()); // 6:切片中 entity.setStatus(6); entity.setLayerMin(Integer.valueOf(layerMin)); entity.setLayerMax(Integer.valueOf(layerMax)); entity = vectorServer.save(entity); asyncTask.vectorSliceThread(vectorSliceQueue, vectorServer, entity, cmd); return new R(200, entity); } return new R(52000, MsgCode.E52000); } @ApiOperation("矢量数据进度查询") @GetMapping("progress/{fileId}/") public R getProgress(@PathVariable("fileId") Long fileId) { OutputFileEntity entity = vectorServer.findById(fileId); return new R(200, entity); } @RequiresRoles("admin") @ApiOperation("移动数据到服务器上") @PostMapping("move/{fileId}/") public R moveFile(@PathVariable("fileId") Long fileId, @RequestBody ConfigJsonDto param) { log.info("run moveFile: {}", fileId); return vectorServer.moveFileToServer(fileId, param); } @ApiOperation("保存样式") @PostMapping("style/save/") public R saveStyle(@RequestBody StyleDto param) { log.info("run saveStyle"); return vectorServer.editStyle(param); } @ApiOperation("获取样式") @GetMapping("style/get/{fileId}/") public R getStyle(@PathVariable("fileId") Long fileId) { log.info("run getStyle: {}", fileId); return vectorServer.getStyle(fileId); } }