Jelajahi Sumber

多数据集点云裁剪

wuweihao 3 tahun lalu
induk
melakukan
2d3fbbbadb

+ 32 - 33
laser/src/main/java/com/fdkankan/indoor/base/util/Result.java

@@ -24,7 +24,6 @@ public class Result<T> implements Serializable {
     public static int CODE_SUCCESS = 0;
     public static int CODE_FAILURE = -1;
     public static String[] NOOP = new String[]{};
-    public static LocalDateTime dataTime = LocalDateTime.now();
 
     /**
      * 处理状态:0: 成功, 1: 失败
@@ -51,7 +50,7 @@ public class Result<T> implements Serializable {
      * @return data
      */
     public static Result success(Object data) {
-        return new Result(CODE_SUCCESS, SUCCESS_MSG, data, dataTime);
+        return new Result(CODE_SUCCESS, SUCCESS_MSG, data, LocalDateTime.now());
     }
     /**
      * 处理成功
@@ -59,7 +58,7 @@ public class Result<T> implements Serializable {
      * @return data
      */
     public static Result success() {
-        return new Result(CODE_SUCCESS, SUCCESS_MSG, NOOP, dataTime);
+        return new Result(CODE_SUCCESS, SUCCESS_MSG, NOOP, LocalDateTime.now());
     }
     /**
      * 处理成功
@@ -68,7 +67,7 @@ public class Result<T> implements Serializable {
      * @return data
      */
     public static Result success(String msg) {
-        return new Result(CODE_SUCCESS, msg, NOOP, dataTime);
+        return new Result(CODE_SUCCESS, msg, NOOP, LocalDateTime.now());
     }
     /**
      * 处理成功
@@ -78,7 +77,7 @@ public class Result<T> implements Serializable {
      * @return data
      */
     public static Result success(String msg, Object data) {
-        return new Result(CODE_SUCCESS, msg, data, dataTime);
+        return new Result(CODE_SUCCESS, msg, data, LocalDateTime.now());
     }
     /**
      * 处理失败,并返回数据(一般为错误信息)
@@ -88,7 +87,7 @@ public class Result<T> implements Serializable {
      * @return data
      */
     public static Result failure(int code, String msg) {
-        return new Result(code, msg, NOOP , dataTime);
+        return new Result(code, msg, NOOP , LocalDateTime.now());
     }
     /**
      * 处理失败
@@ -103,33 +102,33 @@ public class Result<T> implements Serializable {
     @Override
     public String toString() {
         return "JsonResult [code=" + code + ", msg=" + msg + ", data="
-                + data + ", timestamp="+ dataTime + "]";
+                + data + ", timestamp="+ timestamp + "]";
     }
 
-    /**
-     * Created by owen on 2021/7/27 0027 15:48
-     */
-    @Document
-    public static class MongoSequence {
-        @Id
-        private String id;
-
-        private int seq;
-
-        public String getId() {
-            return id;
-        }
-
-        public void setId(String id) {
-            this.id = id;
-        }
-
-        public int getSeq() {
-            return seq;
-        }
-
-        public void setSeq(int seq) {
-            this.seq = seq;
-        }
-    }
+//    /**
+//     * Created by owen on 2021/7/27 0027 15:48
+//     */
+//    @Document
+//    public static class MongoSequence {
+//        @Id
+//        private String id;
+//
+//        private int seq;
+//
+//        public String getId() {
+//            return id;
+//        }
+//
+//        public void setId(String id) {
+//            this.id = id;
+//        }
+//
+//        public int getSeq() {
+//            return seq;
+//        }
+//
+//        public void setSeq(int seq) {
+//            this.seq = seq;
+//        }
+//    }
 }

+ 25 - 5
laser/src/main/java/com/fdkankan/indoor/core/controller/CutModelController.java

@@ -3,12 +3,15 @@ package com.fdkankan.indoor.core.controller;
 import com.fdkankan.indoor.base.aop.WebControllerLog;
 import com.fdkankan.indoor.base.util.Result;
 import com.fdkankan.indoor.core.entity.dto.CropDto;
+import com.fdkankan.indoor.core.entity.dto.MultipleCropDto;
 import com.fdkankan.indoor.core.service.CutModelService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 /**
  * Created by owen on 2021/8/17 0017 15:10
  */
@@ -28,9 +31,9 @@ public class CutModelController {
 
 //    @WebControllerLog(description = "剪切模型-剪切模型")
 //    @ApiOperation("剪切模型")
-//    @PostMapping("indoor/{sceneCode}/api/pointcloud/crop")
+//    @PostMapping("indoor/{sceneCode}/api/pointcloud/crop1")
 //    public Object crop(@PathVariable String sceneCode, @RequestBody CropDto param){
-//        Result result = entityService.crop(sceneCode, param);
+//        Result result = entityService.crop1(sceneCode, param);
 //        return  result.getData();
 //    }
 
@@ -40,11 +43,28 @@ public class CutModelController {
      * @param sceneCode
      * @return
      */
+//    @WebControllerLog(description = "剪切模型-剪切模型")
+//    @ApiOperation("剪切模型")
+//    @PostMapping("indoor/{sceneCode}/api/pointcloud/crop")
+//    public Object multipleCrop(@PathVariable String sceneCode){
+//        Result result = entityService.multipleCrop(sceneCode);
+//        return  result.getData();
+//    }
+
+
+    /***
+     * 2021-11-10
+     * 剪裁模型
+     * 更新,支持多数据集点云剪裁,并下载点云数据
+     * @param sceneCode
+     * @param param
+     * @return
+     */
     @WebControllerLog(description = "剪切模型-剪切模型")
-    @ApiOperation("剪切模型")
+    @ApiOperation("剪切模型2")
     @PostMapping("indoor/{sceneCode}/api/pointcloud/crop")
-    public Object multipleCrop(@PathVariable String sceneCode){
-        Result result = entityService.multipleCrop(sceneCode);
+    public Object multipleCrop(@PathVariable String sceneCode, @RequestBody MultipleCropDto param){
+        Result result = entityService.multipleCrop2(sceneCode, param);
         return  result.getData();
     }
 

+ 23 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/dto/Crop.java

@@ -0,0 +1,23 @@
+package com.fdkankan.indoor.core.entity.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * Created by owen on 2021/11/10 0010 15:11
+ */
+@Data
+public class Crop {
+
+    @ApiModelProperty(value = "数据集id")
+    private Integer id;
+
+    @ApiModelProperty(value = "矩阵(包含剪切参数)")
+    private Double[] matrix;
+
+    @NotBlank(message = "偏移摆放矩阵参数不能为空")
+    @ApiModelProperty(value = "偏移摆放矩阵", required = true)
+    private Double[] modelMatrix;
+}

+ 25 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/dto/MultipleCropDto.java

@@ -0,0 +1,25 @@
+package com.fdkankan.indoor.core.entity.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.util.List;
+
+/**
+ * Created by owen on 2021/11/10 0010 14:57
+ *
+ * 多数据集剪裁参数
+ */
+@Data
+public class MultipleCropDto {
+
+    @ApiModelProperty(value = "剪裁参数")
+    private List<Crop> transformation_matrix;
+
+    @NotBlank(message = "剪裁参数不能为空")
+    @ApiModelProperty(value = "剪裁参数", required = true)
+    private String aabb;
+
+
+}

+ 2 - 0
laser/src/main/java/com/fdkankan/indoor/core/mapper/MergeInfoMapper.java

@@ -26,4 +26,6 @@ public interface MergeInfoMapper extends MongoRepository<MergeInfoEntity, String
     void deleteBySceneCode(String sceneCode);
 
     MergeInfoEntity findBySceneCodeAndDataSetId(String sceneCode, Integer dataSetId);
+
+    List<MergeInfoEntity> findBySceneCode(String sceneCode);
 }

+ 5 - 4
laser/src/main/java/com/fdkankan/indoor/core/service/CutModelService.java

@@ -1,11 +1,10 @@
 package com.fdkankan.indoor.core.service;
 
-import com.alibaba.fastjson.JSONArray;
 import com.fdkankan.indoor.base.util.Result;
 import com.fdkankan.indoor.core.entity.dto.CropDto;
-import org.springframework.web.multipart.MultipartFile;
+import com.fdkankan.indoor.core.entity.dto.MultipleCropDto;
 
-import java.util.Map;
+import java.util.List;
 
 /**
  * Created by owen on 2021/7/28 0028 20:05
@@ -15,9 +14,11 @@ public interface CutModelService {
 
 //    Result cutModel(String sceneCode);
 
-//    Result crop(String sceneCode, CropDto param);
+    Result crop1(String sceneCode, CropDto param);
 
     Result findByDataId(String sceneCode, Integer dataId);
 
     Result multipleCrop(String sceneCode);
+
+    Result multipleCrop2(String sceneCode, MultipleCropDto param);
 }

+ 2 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/MergeInfoService.java

@@ -15,6 +15,8 @@ public interface MergeInfoService {
 
     List<MergeInfoEntity> findBySceneCode(String sceneCode, Integer display);
 
+    List<MergeInfoEntity> findBySceneCode(String sceneCode);
+
     List<MergeInfoEntity> findByMergeCode(String mergeCode);
 
     List<MergeInfoEntity> findBySceneCodeAndMergeCode(String sceneCode, String mergeCode);

+ 170 - 99
laser/src/main/java/com/fdkankan/indoor/core/service/impl/CutModelServiceImpl.java

@@ -13,9 +13,7 @@ import com.fdkankan.indoor.base.util.AliYunOssUtil;
 import com.fdkankan.indoor.base.util.CmdUtils;
 import com.fdkankan.indoor.base.util.Result;
 import com.fdkankan.indoor.core.entity.*;
-import com.fdkankan.indoor.core.entity.dto.CropDto;
-import com.fdkankan.indoor.core.entity.dto.CutModelDto;
-import com.fdkankan.indoor.core.entity.dto.MapDto;
+import com.fdkankan.indoor.core.entity.dto.*;
 import com.fdkankan.indoor.core.entity.po.DataSetPo;
 import com.fdkankan.indoor.core.entity.po.MapPo;
 import com.fdkankan.indoor.core.mapper.CutModelMapper;
@@ -150,100 +148,100 @@ public class CutModelServiceImpl extends IBaseServiceImpl implements CutModelSer
 //        return null;
 //    }
 
-//    @Override
-//    public Result crop(String sceneCode, CropDto param) {
-//        Double[] transformation_matrix = param.getTransformation_matrix();
-//        String matrix = format(transformation_matrix);
-//        JSONObject pa = new JSONObject();
-//        log.info("aa: {}", matrix);
-//        pa.put("aabb", "b-0.5 -0.5 -0.5 0.5 0.5 0.5");
-//        pa.put("cut_transformation", "b" + matrix);
-//
-//        InitEntity entity = initService.findById(sceneCode);
-//        if (entity == null) {
-//            throw new BaseRuntimeException("对象不存在");
-//
-//        }
-//
-//        String path = entity.getPath();
-////        String basePath = path + "/laserData/";
-//        String basePath = path ;
-//
-//        String savePath = basePath + "cut_param.json";
-//        log.info("剪切参数:{}", savePath);
-//        FileUtil.writeUtf8String(pa.toJSONString(), savePath);
-//        log.info("剪切参数json写入完成");
-//
-//        // 调用命令切模型
-//        String cmd = CmdConstant.CUT_MODEL;
-//        String inPath = basePath + "laser.las";
-//
-//        String time = DateUtil.format(LocalDateTime.now(), "yyyyMMdd_HHmmss");
-//        String cutDir = basePath + "cut/";
-//        String outPath = cutDir + time + ".las";
-//        // 检查目录
-//        if (!FileUtil.isFile(cutDir)) {
-//            FileUtil.mkdir(cutDir);
-//        }
-//        String cutParam = basePath + "cut_param.json";
-//
-//        cmd = cmd.replace("@inPath", inPath);
-//        cmd = cmd.replace("@outPath", outPath);
-//        cmd = cmd.replace("@cutParam", cutParam);
-//
-//        CmdUtils.callLineSh(cmd);
-//        log.info("剪切模型完成: {}", outPath);
-//
-//        // 将剪裁后的las上传oss
-//        String ossPath = "data/" +sceneCode + "/data/chunk1/cut/" + time + ".las";
-//        aliYunOssUtil.upload(outPath, ossPath);
-//
-//        String ossUrl = configConstant.ossDomain + ossPath;
-//        log.info("剪切模型上传oss完成: {}", ossUrl);
-//
-//        // 保存数据到数据库
-//        Integer maxId = 0;
-//        CutModelEntity cutEntity = findById(sceneCode);
-//        if (cutEntity == null) {
-//            cutEntity = new CutModelEntity();
-//            cutEntity.setId(sceneCode);
-//            cutEntity.setCreateTime(LocalDateTime.now());
-//            cutEntity.setData(initCutModelDto(ossUrl, null));
-//            maxId = 1;
-//        } else {
-//            // 修改一次,加一条记录
-//            cutEntity.setUpdateTime(LocalDateTime.now());
-//
-//
-//
-//            List<CutModelDto> data = getDataBySceneCode(sceneCode);
-//            if (data.size() != 0){
-//
-//                // 遍历参数,获取id, 保存新list
-//                List<Integer> collectId = data.stream().map(CutModelDto::getId).collect(Collectors.toList());
-//                log.info("参数id: {}", collectId);
-//                // 获取最大id
-//                if (data.size() != 0) {
-//                    Optional<CutModelDto> max = data.stream().max(Comparator.comparingInt(CutModelDto::getId));
-//                    maxId = max.get().getId();
-//                    maxId ++;
-//                }
-//
-//            }
-//
-//
-//            List<CutModelDto> cutModelDtos = initCutModelDto(ossUrl, maxId);
-//            // 合并两个流,
-//            data.addAll(cutModelDtos);
-//            cutEntity.setData(data);
-//
-//        }
-//        entityMapper.save(cutEntity);
-//
-//        JSONObject result = new JSONObject();
-//        result.put("job_id", maxId);
-//        return Result.success(result);
-//    }
+    @Override
+    public Result crop1(String sceneCode, CropDto param) {
+        Double[] transformation_matrix = param.getTransformation_matrix();
+        String matrix = format(transformation_matrix);
+        JSONObject pa = new JSONObject();
+        log.info("matrix: {}", matrix);
+        pa.put("aabb", "b-0.5 -0.5 -0.5 0.5 0.5 0.5");
+        pa.put("cut_transformation", "b" + matrix);
+
+        InitEntity entity = initService.findById(sceneCode);
+        if (entity == null) {
+            throw new BaseRuntimeException("对象不存在");
+
+        }
+
+        String path = entity.getPath();
+//        String basePath = path + "/laserData/";
+        String basePath = path ;
+
+        String savePath = basePath + "cut_param.json";
+        log.info("剪切参数:{}", savePath);
+        FileUtil.writeUtf8String(pa.toJSONString(), savePath);
+        log.info("剪切参数json写入完成");
+
+        // 调用命令切模型
+        String cmd = CmdConstant.CUT_MODEL;
+        String inPath = basePath + "laser.las";
+
+        String time = DateUtil.format(LocalDateTime.now(), "yyyyMMdd_HHmmss");
+        String cutDir = basePath + "cut/";
+        String outPath = cutDir + time + ".las";
+        // 检查目录
+        if (!FileUtil.isFile(cutDir)) {
+            FileUtil.mkdir(cutDir);
+        }
+        String cutParam = basePath + "cut_param.json";
+
+        cmd = cmd.replace("@inPath", inPath);
+        cmd = cmd.replace("@outPath", outPath);
+        cmd = cmd.replace("@cutParam", cutParam);
+
+        CmdUtils.callLineSh(cmd);
+        log.info("剪切模型完成: {}", outPath);
+
+        // 将剪裁后的las上传oss
+        String ossPath = "data/" +sceneCode + "/data/chunk1/cut/" + time + ".las";
+        aliYunOssUtil.upload(outPath, ossPath);
+
+        String ossUrl = configConstant.ossDomain + ossPath;
+        log.info("剪切模型上传oss完成: {}", ossUrl);
+
+        // 保存数据到数据库
+        Integer maxId = 0;
+        CutModelEntity cutEntity = findById(sceneCode);
+        if (cutEntity == null) {
+            cutEntity = new CutModelEntity();
+            cutEntity.setId(sceneCode);
+            cutEntity.setCreateTime(LocalDateTime.now());
+            cutEntity.setData(initCutModelDto(ossUrl, null));
+            maxId = 1;
+        } else {
+            // 修改一次,加一条记录
+            cutEntity.setUpdateTime(LocalDateTime.now());
+
+
+
+            List<CutModelDto> data = getDataBySceneCode(sceneCode);
+            if (data.size() != 0){
+
+                // 遍历参数,获取id, 保存新list
+                List<Integer> collectId = data.stream().map(CutModelDto::getId).collect(Collectors.toList());
+                log.info("参数id: {}", collectId);
+                // 获取最大id
+                if (data.size() != 0) {
+                    Optional<CutModelDto> max = data.stream().max(Comparator.comparingInt(CutModelDto::getId));
+                    maxId = max.get().getId();
+                    maxId ++;
+                }
+
+            }
+
+
+            List<CutModelDto> cutModelDtos = initCutModelDto(ossUrl, maxId);
+            // 合并两个流,
+            data.addAll(cutModelDtos);
+            cutEntity.setData(data);
+
+        }
+        entityMapper.save(cutEntity);
+
+        JSONObject result = new JSONObject();
+        result.put("job_id", maxId);
+        return Result.success(result);
+    }
 
     @Override
     public Result findByDataId(String sceneCode, Integer dataId) {
@@ -375,9 +373,10 @@ public class CutModelServiceImpl extends IBaseServiceImpl implements CutModelSer
 
         for (DataSetPo po : dataSetInfos) {
             Double[] location = po.getLocation();
-            // gis坐标转本地坐标
+            // gis坐标转本地坐标, 平移坐标
             double[] doubles = GisCoordinateUtil.transformBLToLocation(location[0], location[1], pointCalculate);
 
+            // 旋转角度
             Double orientation = po.getOrientation();
 
             // 将本地坐标, 旋转角度按顺序封装起来
@@ -401,7 +400,9 @@ public class CutModelServiceImpl extends IBaseServiceImpl implements CutModelSer
                 cutJson.put("dataSetId", dataSetId);
                 // 算法要求用空格隔开
                 cutJson.put("file", basePath + "/laser.las");
+                // 平移参数
                 cutJson.put("translation", point[0] + " " + point[1] + " " + point[2]);
+                // 旋转参数
                 cutJson.put("rotation", point[3]);
                 models.add(cutJson);
             } else { // 多数据集
@@ -425,7 +426,9 @@ public class CutModelServiceImpl extends IBaseServiceImpl implements CutModelSer
                     cutJson.put("dataSetId", dataSetId);
                     // 算法要求用空格隔开
                     cutJson.put("file", info.getPath() + "/laser.las");
+                    // 平移参数
                     cutJson.put("translation", point[0] + " " + point[1] + " " + point[2]);
+                    // 旋转参数
                     cutJson.put("rotation", point[3]);
                     models.add(cutJson);
                 }
@@ -437,7 +440,7 @@ public class CutModelServiceImpl extends IBaseServiceImpl implements CutModelSer
             // 修剪模型参数
             JSONObject mergeCut = new JSONObject();
             mergeCut.put("model", models);
-            // 这个值目前写死
+            // 这个值目前写死, 剪切参数
             mergeCut.put("aabb", "b-0.5 -0.5 -0.5 0.5 0.5 0.5");
 
             // 剪切模型参数json写入服务器
@@ -467,6 +470,74 @@ public class CutModelServiceImpl extends IBaseServiceImpl implements CutModelSer
 
     }
 
+
+    @Override
+    public Result multipleCrop2(String sceneCode, MultipleCropDto param) {
+
+        // 1. 合并场景表(t_merge_info)获取dataSetId, 场景码
+        List<MergeInfoEntity> mergeInfo = mergeInfoService.findBySceneCode(sceneCode);
+
+        HashMap<Integer, MergeInfoEntity> mergeMap = new HashMap<>();
+        for (MergeInfoEntity infoEntity : mergeInfo) {
+            mergeMap.put(infoEntity.getDataSetId(), infoEntity);
+        }
+
+        // models参数
+        JSONArray models = new JSONArray();
+        List<Crop> cropMatrix = param.getTransformation_matrix();
+        for (Crop crop : cropMatrix) {
+            Integer dataSetId = crop.getId();
+            if (dataSetId==null) {
+                throw new BaseRuntimeException("剪切模型参数,数据集id不能为空");
+            }
+
+            MergeInfoEntity infoEntity = mergeMap.get(dataSetId);
+            JSONObject model = new JSONObject();
+            model.put("sceneCode", infoEntity.getMergeCode());
+            model.put("dataSetId", dataSetId);
+            // 算法要求用空格隔开
+            model.put("file", infoEntity.getPath() + "/laser.las");
+            // 矩阵(剪裁参数已包含在里面的)
+            model.put("cut_transformation", format(crop.getMatrix()));
+            model.put("modelMatrix", format(crop.getModelMatrix()));
+
+            models.add(model);
+
+        }
+
+        // 修剪模型参数
+        JSONObject mergeCut = new JSONObject();
+        mergeCut.put("model", models);
+        // 剪裁参数
+        mergeCut.put("aabb", param.getAabb());
+        log.info("剪切参数json:", mergeCut);
+
+
+        String basePath = redisPath(sceneCode);
+
+        // 剪切模型参数json写入服务器
+
+        if ("dev".equals(configConstant.active)){
+            basePath = configConstant.serverBasePath + "/" + sceneCode + "/results/laserData";
+        }
+        String savePath = basePath + "/merge_cut_param.json";
+        log.info("剪切参数保存路径:{}", savePath);
+        FileUtil.writeUtf8String(mergeCut.toJSONString(), savePath);
+        log.info("剪切参数json写入完成");
+
+        // 剪切并oss上传模型
+        String ossUrl = cutLas(basePath, sceneCode);
+
+        // 数据更新到数据库
+        saveLasInfo(sceneCode, ossUrl);
+
+        JSONObject result = new JSONObject();
+        // 返回值id, 默认1
+        result.put("job_id", 1);
+        return Result.success(result);
+
+    }
+
     /**
      * 2021-11-04
      * 处理剪切模型参数并剪切模型,结果上传oss

+ 5 - 1
laser/src/main/java/com/fdkankan/indoor/core/service/impl/MergeInfoServiceImpl.java

@@ -34,11 +34,15 @@ public class MergeInfoServiceImpl extends IBaseServiceImpl implements MergeInfoS
 
     @Override
     public List<MergeInfoEntity> findBySceneCode(String sceneCode, Integer display) {
-
         return entityMapper.findBySceneCodeAndDisplay(sceneCode, display);
     }
 
     @Override
+    public List<MergeInfoEntity> findBySceneCode(String sceneCode) {
+        return entityMapper.findBySceneCode(sceneCode);
+    }
+
+    @Override
     public List<MergeInfoEntity> findByMergeCode(String mergeCode) {
         return entityMapper.findByMergeCode(mergeCode);
     }