Преглед изворни кода

修改了矢量数据以zip上传
添加了严格坐标转换

wuweihao пре 5 година
родитељ
комит
1c2ccc9594

+ 1 - 0
pom.xml

@@ -70,6 +70,7 @@
             <artifactId>commons-lang3</artifactId>
             <version>${lang3.version}</version>
         </dependency>
+
     </dependencies>
 
     <build>

+ 20 - 1
src/main/java/com/fd/constant/Command.java

@@ -20,7 +20,26 @@ public class Command {
      * 输出文件:/root/gis/cesium/input/transform/@fileName/@fileName.shp
      * 坐标参数:EPSG:4326
      */
-    public static String VECTOR_TRANSFORM_OGR2OGR  = "docker run --rm -v /root/gis/cesium/input:/root/gis/cesium/input osgeo/gdal  ogr2ogr -t_srs EPSG:4326  /root/gis/cesium/input/transform/@directory/@fileName.shp  /root/gis/cesium/input/@directory/@fileName.shp";
+    public static String VECTOR_TRANSFORM_GENERAL  = "docker run --rm -v /root/gis/cesium/input:/root/gis/cesium/input osgeo/gdal  ogr2ogr -t_srs EPSG:4326  @outputFile  @inputFile";
+
+
+    /**
+     * 矢量数据 严格坐标转换
+     * 有坐标参数,执行严格坐标转换(CGCS2000转wgs80)
+     * 坐标: @coord
+     * 输入文件:
+     * 输出文件:
+     */
+    public static String VECTOR_TRANSFORM_STRICT_WGS80  = "docker run --rm -v /root/gis/cesium/input:/root/gis/cesium/input osgeo/gdal ogr2ogr -overwrite  -s_srs \"+proj=longlat +ellps=GRS80 +no_defs +towgs84=@coord\" -t_srs EPSG:4326 @outputFile @inputFile";
+
+    /**
+     * 矢量数据 严格坐标转换
+     * 有坐标参数,执行严格坐标转换(西安80转wgs84)
+     * 坐标: @coord
+     * 输入文件:
+     * 输出文件:
+     */
+    public static String VECTOR_TRANSFORM_STRICT_WGS84  = "docker run --rm -v /root/gis/cesium/input:/root/gis/cesium/input osgeo/gdal ogr2ogr -overwrite  -s_srs \"+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=38500000 +y_0=0 +ellps=IAU76 +units=m +no_defs +towgs84=@coord\" -t_srs EPSG:4326 @outputFile @inputFile";
 
     /**
      * 矢量数据切片 step1

+ 158 - 29
src/main/java/com/fd/controller/VectorController.java

@@ -7,6 +7,7 @@ import com.fd.dto.PageDto;
 import com.fd.entity.FileEntity;
 import com.fd.server.CmdServer;
 import com.fd.server.FileServer;
+import com.fd.server.VectorServer;
 import com.fd.util.FileUtils;
 import com.fd.util.R;
 import io.swagger.annotations.ApiOperation;
@@ -40,17 +41,95 @@ public class VectorController {
     private FileServer fileServer;
 
     @Autowired
+    private VectorServer vectorServer;
+
+    @Autowired
     private CmdServer cmdServer;
 
 
 
-    @ApiOperation("上传矢量数据")
-    @PostMapping(value = "upload/{directoryName}/", consumes = { "multipart/form-data" })
-    private R upload(@RequestParam("file") MultipartFile file, @PathVariable("directoryName") String directoryName){
+//    @ApiOperation("上传矢量数据,coord:坐标, directoryName:目录名称")
+//    @PostMapping(value = "upload/{directoryName}/", consumes = { "multipart/form-data" })
+//    private R upload(@RequestParam("file") MultipartFile file, @PathVariable("directoryName") String directoryName,
+//                     @RequestParam(value = "coord",required = false) String coord){
+//        log.info("run upload");
+//        return fileServer.uploadFile(file, directoryName, TypeCode.FILE_TYPE_VECTOR);
+//    }
+
+    @ApiOperation("上传矢量数据,只能上传zip文件,里面的文件名必须跟压缩包一致, coord:坐标(可以为空), 坐标格式:0,0,0,0,0,0,0")
+    @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");
-        return fileServer.uploadFile(file, directoryName, TypeCode.FILE_TYPE_VECTOR);
+
+        // 文件名全名
+        String fileName = file.getOriginalFilename();
+        String s = StringUtils.substringAfterLast(fileName, ".");
+
+        if (!"zip".equals(s)) {
+            return new R(50007,MsgCode.E50007);
+        }
+
+        return vectorServer.uploadFile(file, coord);
     }
 
+
+    @ApiOperation("解压zip文件")
+    @GetMapping("unzip/{fileId}/")
+    private R fileUnzip(@PathVariable("fileId") Long fileId) {
+        log.info("run fileUnzip: {}", fileId);
+        FileEntity entity = fileServer.findById(fileId);
+
+        boolean unzip = FileUtils.unzip(entity.getFileUrl(), INPUT_FILE_PATH);
+
+        if (!unzip) {
+            return new R(50006, MsgCode.E50006);
+        }
+
+        String fileName = StringUtils.substringBefore(entity.getFileName(), ".");
+
+        FileEntity fileEntity = new FileEntity();
+
+        // 添加文件夹到数据库
+        fileEntity.setFileName(fileName);
+        fileEntity.setFileUrl(INPUT_FILE_PATH + fileName);
+        fileEntity.setCreateTime(new Date());
+        fileEntity.setUpdateTime(new Date());
+        fileEntity.setType(TypeCode.FILE_TYPE_VECTOR);
+        fileEntity.setCoord(entity.getCoord());
+        fileEntity = fileServer.save(fileEntity);
+
+        // xxx.shp到数据库
+//        String sName = StringUtils.substringAfter(fileName, "_");
+//        sName = sName + ".shp";
+        fileEntity = new FileEntity();
+//        fileEntity.setFileName(sName);
+//        fileEntity.setFileUrl(INPUT_FILE_PATH + fileName + File.separator + sName);
+
+        fileEntity.setFileName(fileName + ".shp");
+        fileEntity.setFileUrl(INPUT_FILE_PATH + fileName + File.separator + fileName + ".shp");
+
+        fileEntity.setCreateTime(new Date());
+        fileEntity.setUpdateTime(new Date());
+        fileEntity.setType(TypeCode.FILE_TYPE_VECTOR);
+        fileEntity.setCoord(entity.getCoord());
+        fileEntity = fileServer.save(fileEntity);
+
+        return new R(200, fileEntity);
+    }
+
+
+//    @ApiOperation("test")
+//    @PostMapping(value = "test/{directoryName}/", consumes = { "multipart/form-data" })
+//    private R test(@RequestParam("file") MultipartFile file, @PathVariable("directoryName") String directoryName, @RequestParam(value = "str",required = false) String str){
+//        log.info("run upload");
+//        log.info("directoryName: {}", directoryName);
+//        log.info("str: {}", str);
+//        return new R(200, "123");
+//    }
+
+
+
     @ApiOperation("获取矢量数据列表")
     @PostMapping(value = "list")
     private R list(@RequestBody PageDto param){
@@ -70,6 +149,9 @@ public class VectorController {
     }
 
 
+
+
+
 //    @ApiOperation("矢量数据判断坐标")
 //    @GetMapping("command/judge/coord/{fileId}/")
 //    private R cmdJudgeCoord(@PathVariable("fileId") Long fileId) {
@@ -98,6 +180,8 @@ public class VectorController {
     private R cmdJudgeCoord(@PathVariable("fileId") Long fileId) {
         log.info("run cmdJudgeCoord: {}", fileId);
         FileEntity entity = fileServer.findById(fileId);
+        String coord = entity.getCoord();
+        log.info("coord: {}", coord);
 
         // 判断是否需要坐标转换
         String cmd = Command.VECTOR_JUDGE_COORD;
@@ -109,33 +193,22 @@ public class VectorController {
         FileEntity fileEntity = null;
         // 转换坐标 普通坐标转换
         if (isJudge == 1000){
-            log.info("need to transform");
-
-            String fileName = StringUtils.substringBefore(entity.getFileName(), ".");
-            // 截取目录名称
-            String fileUrl = entity.getFileUrl();
-            String directoryName = StringUtils.substring(fileUrl, fileUrl.indexOf("input/") + 6, fileUrl.lastIndexOf("/"));
-            cmd = Command.VECTOR_TRANSFORM_OGR2OGR;
-            cmd = cmd.replace("@fileName", fileName);
-            cmd = cmd.replace("@directory", directoryName);
-            log.info("cmd: {}", cmd);
-
-            // 创建个目录,用来存转换后的文件,目录以文件名命名
-            String directoryPath = INPUT_FILE_PATH + "transform" + File.separator + directoryName;
-            FileUtils.createDir(directoryPath);
-
-            Integer integer = cmdServer.exeCmdInt(cmd);
-            if (integer != 0) {
-                return new R(50005, MsgCode.E50005);
+            // 普通坐标转换
+            log.info("need to general transform");
+            if (coord == null) {
+                // 没有坐标参数,执行普通坐标转换(ogrinfo)
+                fileEntity = generalCoordTransform(entity, Command.VECTOR_TRANSFORM_GENERAL);
+
+            } else {
+                // 有坐标参数,执行严格坐标转换(CGCS2000转wgs80)
+                fileEntity = strictCoordTransform(entity, Command.VECTOR_TRANSFORM_STRICT_WGS80);
             }
 
-            fileEntity = new FileEntity();
-            fileEntity.setFileName(entity.getFileName());
-            fileEntity.setFileUrl(directoryPath + File.separator + entity.getFileName());
-            fileEntity.setCreateTime(new Date());
-            fileEntity.setUpdateTime(new Date());
-            fileEntity.setType(TypeCode.FILE_TYPE_VECTOR);
-            fileEntity = fileServer.save(fileEntity);
+        } else if (isJudge == 1001 && coord != null) {
+            // 严格坐标转换 (西安80转wgs84),需要参数
+            log.info("need to strict transform");
+            fileEntity = strictCoordTransform(entity, Command.VECTOR_TRANSFORM_STRICT_WGS84);
+
         } else if (0 == isJudge){ // 不转换坐标
             log.info("not to transform");
             fileEntity = entity;
@@ -213,4 +286,60 @@ public class VectorController {
 
         return new R(200, fileEntity);
     }
+
+
+    // 普通坐标转换
+    private FileEntity generalCoordTransform(FileEntity entity, String cmd){
+
+        String directory = createDirectory(entity);
+        directory = directory + File.separator + entity.getFileName();
+
+        cmd = cmd.replace("@inputFile", entity.getFileUrl());
+        cmd = cmd.replace("@outputFile", directory);
+        log.info("cmd: {}", cmd);
+        return  runCmd(cmd, entity, directory);
+    }
+
+
+
+    // 严格坐标转换
+    private FileEntity strictCoordTransform(FileEntity entity, String cmd){
+
+        String directory = createDirectory(entity);
+        directory = directory + File.separator + entity.getFileName();
+
+        cmd = cmd.replace("@coord", entity.getCoord());
+        cmd = cmd.replace("@inputFile", entity.getFileUrl());
+        cmd = cmd.replace("@outputFile", directory);
+        log.info("cmd: {}", cmd);
+
+        return  runCmd(cmd, entity, directory);
+    }
+
+    // 创建目录
+    private String createDirectory(FileEntity entity){
+        String fileName = StringUtils.substringBeforeLast(entity.getFileName(), ".");
+        String directory = INPUT_FILE_PATH + "transform" + File.separator + fileName;
+        FileUtils.createDir(directory);
+        return directory;
+    }
+
+    // 执行命令,创建对象
+    private FileEntity runCmd(String cmd, FileEntity entity, String filePath){
+        Integer integer = cmdServer.exeCmdInt(cmd);
+        if (integer != 0) {
+            return null;
+        }
+
+        FileEntity fileEntity = new FileEntity();
+        fileEntity.setFileName(entity.getFileName());
+        fileEntity.setFileUrl(filePath);
+        fileEntity.setCreateTime(new Date());
+        fileEntity.setUpdateTime(new Date());
+        fileEntity.setType(TypeCode.FILE_TYPE_VECTOR);
+        fileEntity = fileServer.save(fileEntity);
+        return fileEntity;
+
+    }
+
 }

+ 3 - 0
src/main/java/com/fd/entity/FileEntity.java

@@ -40,4 +40,7 @@ public class FileEntity extends BaseEntity implements Serializable {
 
     @Column
     private Integer status; // 状态,是否可用 1:完成, 0:未完成
+
+    @Column
+    private String coord; // 坐标
 }

+ 12 - 0
src/main/java/com/fd/server/VectorServer.java

@@ -0,0 +1,12 @@
+package com.fd.server;
+
+import com.fd.util.R;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * Created by Owen on 2019/11/21 0021 15:29
+ */
+public interface VectorServer {
+
+    R uploadFile(MultipartFile file, String coord);
+}

+ 11 - 2
src/main/java/com/fd/server/impl/CmdServerImpl.java

@@ -249,12 +249,21 @@ public class CmdServerImpl implements CmdServer {
             log.info("end exeCmd : {}", isCmd);
             // 判断坐标
             if (sb.toString().contains("GEOGCS[\"China Geodetic Coordinate System 2000\"")) {
-                // 需要坐标转换
-                isCmd = 1000;  // 2:
+                // 需要普通坐标转换
+                isCmd = 1000;
+                log.info("需要坐标转换code:{}, GEOGCS[\"China Geodetic Coordinate System 2000\"", isCmd);
+            }
+
+            if (sb.toString().contains("GEOGCS[\"Xian 1980\"")) {
+                // 需要严格坐标转换
+                isCmd = 1001;  // 2:
+                log.info("需要严格坐标转换code:{}, GEOGCS[\"Xian 1980\"", isCmd);
             }
+
             if (sb.toString().contains("GEOGCS[\"WGS 84\"")) {
                 // 不需要坐标转换
                 isCmd = 0;
+                log.info("不需要坐标转换code:{}, GEOGCS[\"WGS 84\"", isCmd);
             }
         } else {
             log.info("error exeCmd wsitFore: {}", isCmd);

+ 78 - 0
src/main/java/com/fd/server/impl/VectorServerImpl.java

@@ -0,0 +1,78 @@
+package com.fd.server.impl;
+
+import com.fd.constant.MsgCode;
+import com.fd.constant.TypeCode;
+import com.fd.entity.FileEntity;
+import com.fd.repository.FileRepository;
+import com.fd.server.VectorServer;
+import com.fd.util.FileUtils;
+import com.fd.util.R;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Base64;
+import java.util.Date;
+
+
+/**
+ * Created by Owen on 2019/11/21 0021 15:29
+ */
+@Log4j2
+@Service
+public class VectorServerImpl implements VectorServer {
+
+    @Value("${input.file.path}")
+    private String INPUT_FILE_PATH;
+
+    @Value("${output.file.path}")
+    private String OUTPUT_FILE_PATH;
+
+    @Autowired
+    private FileRepository fileRepository;
+
+    @Override
+    public R uploadFile(MultipartFile file, String coord) {
+        log.warn("run uploadFile");
+        if (file.isEmpty() || file.getSize() <= 0) {
+            log.info("文件为空");
+            return new R(50001, MsgCode.E50001);
+        }
+
+        // 文件名全名
+        String fullFileName = file.getOriginalFilename();
+
+        // 拼接唯一文件名
+//        String fileName = FileUtils.dateStr() + fullFileName;
+
+        // 文件保存路径
+        String filePath = INPUT_FILE_PATH + fullFileName;
+        log.info("filePath: {}", filePath);
+
+        // 写文件到本地
+        try {
+            byte[] bytes = file.getBytes();
+            String content = Base64.getEncoder().encodeToString(bytes);
+            FileUtils.base64ToFileWriter(content, filePath);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        // 保存信息到db
+        FileEntity entity = new FileEntity();
+        entity.setFileName(fullFileName);
+        entity.setFileUrl(filePath);
+        entity.setCreateTime(new Date());
+        entity.setUpdateTime(new Date());
+        entity.setType(TypeCode.FILE_TYPE_VECTOR);
+        entity.setCoord(coord);
+        fileRepository.save(entity);
+
+        log.info("end uploadFile");
+        return new R(200, entity);
+    }
+}

+ 109 - 79
src/main/java/com/fd/util/FileUtils.java

@@ -7,6 +7,7 @@ import javax.servlet.http.HttpServletResponse;
 import java.io.*;
 import java.net.URLDecoder;
 import java.net.URLEncoder;
+import java.nio.charset.Charset;
 import java.text.SimpleDateFormat;
 import java.util.Base64;
 import java.util.Date;
@@ -195,13 +196,20 @@ public class FileUtils {
     }
 
     // 获取时间戳
-    public static String dateStr() {
+    public static String timeMillisStr() {
         SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
         String format = df.format(new Date());
         long timeMillis = System.currentTimeMillis();
         return format + "_" + timeMillis + "_";
     }
 
+    //返回年月日时分秒
+    public static String dateStr() {
+        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddhhmmss");
+        String format = df.format(new Date());
+        return format + "_";
+    }
+
     /**
      * 删除指定文件夹下所有文件
      * @param path 文件夹完整绝对路径
@@ -257,113 +265,135 @@ public class FileUtils {
 
 
     /**
-     * 解压缩方法
-     *
-     *
-     * @param zipFileName 压缩文件名
-     * @param dstPath 解压目标路径
-     *
-     * @return
+     * zip解压
+     * @param zipFileName        zip源文件
+     * @param destDirPath     解压后的目标文件夹
+     * @throws RuntimeException 解压失败会抛出运行时异常
      */
-    public static boolean unzip(String zipFileName, String dstPath) {
-        System.out.println("zip uncompressing...");
+    public static boolean unzip(String zipFileName, String destDirPath) throws RuntimeException {
+
+        File srcFile = new File(zipFileName);
+
+
+        long start = System.currentTimeMillis();
+
+        // 判断源文件是否存在
+
+        if (!srcFile.exists()) {
+
+            throw new RuntimeException(srcFile.getPath() + "所指文件不存在");
+
+        }
+
+        // 开始解压
+
+        ZipFile zipFile = null;
 
         try {
-            ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFileName));
-            ZipEntry       zipEntry       = null;
-            byte[]         buffer         = new byte[1024];//缓冲器
-            int            readLength     = 0;//每次读出来的长度
 
-            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
-                if (zipEntry.isDirectory()) {//若是zip条目目录,则需创建这个目录
-                    File dir = new File(dstPath + "/" + zipEntry.getName());
+            zipFile = new ZipFile(srcFile, Charset.forName("gbk"));
+
+            Enumeration<?> entries = zipFile.entries();
+
+            while (entries.hasMoreElements()) {
+
+                ZipEntry entry = (ZipEntry) entries.nextElement();
+
+
+                log.info("解压: " + entry.getName());
+
+                // 如果是文件夹,就创建个文件夹
+
+                if (entry.isDirectory()) {
+
+                    String dirPath = destDirPath + "/" + entry.getName();
+
+                    File dir = new File(dirPath);
 
-                    if (!dir.exists()) {
-                        dir.mkdirs();
-                        System.out.println("mkdirs: " + dir.getCanonicalPath());
+                    dir.mkdirs();
+
+                } else {
+
+                    // 如果是文件,就先创建一个文件,然后用io流把内容copy过去
+
+                    File targetFile = new File(destDirPath + "/" + entry.getName());
+
+                    // 保证这个文件的父文件夹必须要存在
+
+                    if(!targetFile.getParentFile().exists()){
+
+                        targetFile.getParentFile().mkdirs();
 
-                        continue;//跳出
                     }
-                }
 
-                File file = createFile(dstPath, zipEntry.getName());//若是文件,则需创建该文件
+                    targetFile.createNewFile();
 
-                System.out.println("file created: " + file.getCanonicalPath());
+                    // 将压缩文件内容写入到这个文件中
 
-                OutputStream outputStream = new FileOutputStream(file);
+                    InputStream is = zipFile.getInputStream(entry);
 
-                while ((readLength = zipInputStream.read(buffer, 0, 1024)) != -1) {
-                    outputStream.write(buffer, 0, readLength);
-                }
+                    FileOutputStream fos = new FileOutputStream(targetFile);
 
-                outputStream.close();
-                System.out.println("file uncompressed: " + file.getCanonicalPath());
-            }    // end while
-        } catch (FileNotFoundException e) {
-            System.out.println(e.getMessage());
-            e.printStackTrace();
-            System.out.println("unzip fail!");
+                    int len;
 
-            return false;
-        } catch (IOException e) {
-            System.out.println(e.getMessage());
-            e.printStackTrace();
-            System.out.println("unzip fail!");
+                    byte[] buf = new byte[1024];
 
-            return false;
-        }
+                    while ((len = is.read(buf)) != -1) {
 
-        System.out.println("unzip success!");
+                        fos.write(buf, 0, len);
 
-        return true;
-    }
+                    }
 
-    /**
-     * 创建文件
-     * 根据压缩包内文件名和解压缩目的路径,创建解压缩目标文件,
-     * 生成中间目录
-     * @param dstPath 解压缩目的路径
-     * @param fileName 压缩包内文件名
-     *
-     * @return 解压缩目标文件
-     *
-     * @throws IOException
-     */
-    private static File createFile(String dstPath, String fileName) throws IOException {
-        String[] dirs = fileName.split("/");//将文件名的各级目录分解
-        File     file = new File(dstPath);
+                    // 关流顺序,先打开的后关闭
 
-        if (dirs.length > 1) {//文件有上级目录
-            for (int i = 0; i < dirs.length - 1; i++) {
-                file = new File(file, dirs[i]);//依次创建文件对象知道文件的上一级目录
-            }
+                    fos.close();
 
-            if (!file.exists()) {
-                file.mkdirs();//文件对应目录若不存在,则创建
-                System.out.println("mkdirs: " + file.getCanonicalPath());
-            }
+                    is.close();
 
-            file = new File(file, dirs[dirs.length - 1]);//创建文件
+                }
 
-            return file;
-        } else {
-            if (!file.exists()) {
-                file.mkdirs();//若目标路径的目录不存在,则创建
-                System.out.println("mkdirs: " + file.getCanonicalPath());
             }
 
-            file = new File(file, dirs[0]);//创建文件
+            long end = System.currentTimeMillis();
+
+            log.info("解压完成,耗时:" + (end - start) +" ms");
+
+        } catch (Exception e) {
+
+            throw new RuntimeException("unzip error from ZipUtils", e);
+
+        } finally {
+
+            if(zipFile != null){
+
+                try {
+
+                    zipFile.close();
+
+                } catch (IOException e) {
+
+                    e.printStackTrace();
+
+                }
+
+            }
 
-            return file;
         }
+        return true;
     }
 
 
 
     public static void main(String[] args) {
-        String a = "aaaa"+ File.separator + "1111.bb";
-        String b = "aaaa\\1111.bb";
-        System.out.println(a.substring(a.lastIndexOf(File.separator)+1));
-        System.out.println(b.substring(b.lastIndexOf(File.separator)+1));
+
+//        unzip("F:\\test\\a1_shp2.zip", "F:\\test\\");
+
+        // 这个是可以的,没有目录结构
+//        unzip("F:\\test\\cesium\\clip.zip", "F:\\test\\cesium\\");
+
+        // 这个有目录的,会失败
+//        File file = new File("F:\\test\\clip.zip");
+        unzip("F:\\test\\clip.zip", "F:\\test\\");
+
     }
 }

+ 1 - 1
src/main/resources/application.properties

@@ -1,4 +1,4 @@
-server.port=8083
+server.port=8082
 
 # file multipart
 spring.profiles.active=pro