Bläddra i källkod

增加平面图ai识别

dengsixing 4 månader sedan
förälder
incheckning
64f92e19a5

+ 2 - 0
src/main/java/com/fdkankan/scene/bean/SceneJsonBean.java

@@ -242,4 +242,6 @@ public class SceneJsonBean {
 
 
     private Integer hasRecognition;
     private Integer hasRecognition;
 
 
+    private Integer hasFloorplanAi;
+
 }
 }

+ 7 - 0
src/main/java/com/fdkankan/scene/constant/CmdConstant.java

@@ -3,6 +3,9 @@ package com.fdkankan.scene.constant;
 
 
 import jdk.nashorn.internal.ir.LexicalContext;
 import jdk.nashorn.internal.ir.LexicalContext;
 
 
+import java.io.File;
+
+
 /**
 /**
  * Created by owen on 2020/12/31 0031 14:22
  * Created by owen on 2020/12/31 0031 14:22
  */
  */
@@ -153,4 +156,8 @@ public class CmdConstant {
 
 
     public final static String OBJ2_TILES ="bash /home/ubuntu/bin/Obj2Tiles.sh @inPath";
     public final static String OBJ2_TILES ="bash /home/ubuntu/bin/Obj2Tiles.sh @inPath";
     public final static String OBJ2_TILES_WIN ="Obj2Tiles.bat @inPath";
     public final static String OBJ2_TILES_WIN ="Obj2Tiles.bat @inPath";
+
+    public final static String LAYOUT_DETECT = "PotreeConverter.bat layout_detect @in @out";
+    public final static String PANO_DETECT = "PotreeConverter.bat pano_detect @in @out";
+
 }
 }

+ 30 - 0
src/main/java/com/fdkankan/scene/constant/DetectType.java

@@ -0,0 +1,30 @@
+package com.fdkankan.scene.constant;
+
+/**
+ * 用户状态
+ *
+ * @author fdkk
+ */
+public enum DetectType
+{
+    PANO(1, "全景图识别"), PLAN(2, "平面图识别");
+
+    private final Integer code;
+    private final String info;
+
+    DetectType(Integer code, String info)
+    {
+        this.code = code;
+        this.info = info;
+    }
+
+    public Integer getCode()
+    {
+        return code;
+    }
+
+    public String getInfo()
+    {
+        return info;
+    }
+}

+ 1 - 1
src/main/java/com/fdkankan/scene/controller/SceneController.java

@@ -90,7 +90,7 @@ public class SceneController extends BaseController {
     }
     }
 
 
     @PostMapping("/initScene")
     @PostMapping("/initScene")
-    public ResultData initScene(@RequestBody InitSceneParamVO param){
+    public ResultData initScene(@RequestBody InitSceneParamVO param) throws Exception {
         return scenePlusService.initScene(param.getBucket(), param.getNum(), param.getTitle(), param.getDes(),
         return scenePlusService.initScene(param.getBucket(), param.getNum(), param.getTitle(), param.getDes(),
                 param.getSceneSource(), param.getDataSource(), param.getSceneScheme(),
                 param.getSceneSource(), param.getDataSource(), param.getSceneScheme(),
                 param.getSceneResolution(), param.getSceneFrom(), param.getModelKind(), param.getAlgorithmTime(), param.getOrientation());
                 param.getSceneResolution(), param.getSceneFrom(), param.getModelKind(), param.getAlgorithmTime(), param.getOrientation());

+ 4 - 0
src/main/java/com/fdkankan/scene/entity/ScenePlus.java

@@ -133,5 +133,9 @@ public class ScenePlus implements Serializable {
     @TableField("remove_portrait")
     @TableField("remove_portrait")
     private Integer removePortrait;
     private Integer removePortrait;
 
 
+    @TableField("has_floorplan_ai")
+    private Integer hasFloorplanAi;
+
+
 
 
 }
 }

+ 12 - 0
src/main/java/com/fdkankan/scene/service/FloorplanAiService.java

@@ -0,0 +1,12 @@
+package com.fdkankan.scene.service;
+
+import java.io.IOException;
+import java.util.LinkedHashMap;
+
+public interface FloorplanAiService {
+
+    LinkedHashMap<Integer, Boolean> detFloorplan(String path)  throws Exception ;
+
+    boolean detFloorPlanAi(String num, String path, LinkedHashMap<Integer, Boolean> detFloorplan, String bucket) throws IOException;
+
+}

+ 2 - 0
src/main/java/com/fdkankan/scene/service/ISceneMarkShapeService.java

@@ -31,4 +31,6 @@ public interface ISceneMarkShapeService extends IService<SceneMarkShape> {
     List<SceneMarkShape> findByNumAndType(String num,Integer type);
     List<SceneMarkShape> findByNumAndType(String num,Integer type);
 
 
     List<SceneMarkShape> findByNum(String num);
     List<SceneMarkShape> findByNum(String num);
+
+    SceneMarkShape readDetectJson(String jsonPath);
 }
 }

+ 1 - 1
src/main/java/com/fdkankan/scene/service/IScenePlusService.java

@@ -41,7 +41,7 @@ public interface IScenePlusService extends IService<ScenePlus> {
 
 
     ResultData initScene(String bucket, String num, String title, String des, Integer sceneSource,
     ResultData initScene(String bucket, String num, String title, String des, Integer sceneSource,
                          String dataSource, Integer sceneScheme, String sceneResolution, String sceneFrom, String mdoelKind, Date algorithmTime,
                          String dataSource, Integer sceneScheme, String sceneResolution, String sceneFrom, String mdoelKind, Date algorithmTime,
-                         String orientation);
+                         String orientation) throws Exception;
 
 
     ResultData editScene(LaserSceneBean param);
     ResultData editScene(LaserSceneBean param);
 
 

+ 149 - 0
src/main/java/com/fdkankan/scene/service/impl/FloorplanAiServiceImpl.java

@@ -0,0 +1,149 @@
+package com.fdkankan.scene.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.model.utils.ComputerUtil;
+import com.fdkankan.scene.constant.CmdConstant;
+import com.fdkankan.scene.constant.DetectType;
+import com.fdkankan.scene.entity.SceneMarkShape;
+import com.fdkankan.scene.oss.OssUtil;
+import com.fdkankan.scene.service.FloorplanAiService;
+import com.fdkankan.scene.service.ISceneMarkShapeService;
+import com.fdkankan.scene.util.CmdUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+@Slf4j
+@Service
+public class FloorplanAiServiceImpl implements FloorplanAiService {
+
+    @Autowired
+    private ISceneMarkShapeService sceneMarkShapeService;
+    @Resource
+    private OssUtil ossUtil;
+
+    @Override
+    public LinkedHashMap<Integer, Boolean> detFloorplan(String path) throws Exception {
+        LinkedHashMap<Integer, Boolean> result = new LinkedHashMap<>();
+        String workDir = path + "/detFloorplan/";
+        if(FileUtil.exist(workDir)){
+            FileUtil.del(workDir);
+        }
+        String infoJsonPath = path + "/results/floorplan/info.json";
+        if(!FileUtil.exist(infoJsonPath)){
+            return result;
+        }
+
+        JSONObject infoObj = JSON.parseObject(FileUtil.readUtf8String(infoJsonPath));
+        JSONArray floors = infoObj.getJSONArray("floors");
+        if(CollUtil.isEmpty(floors)){
+            return result;
+        }
+        for (Object o : floors) {
+            JSONObject floor = (JSONObject) o;
+            Integer subgroup = floor.getInteger("subgroup");
+            String detectPath = workDir + subgroup + "/detect.json";
+            String floorKeyPath = path + "/results/floorplan/floor_" + subgroup + ".png";
+            String parent = FileUtil.getParent(detectPath, 1);
+            FileUtil.mkdir(parent);
+            result.put(subgroup, false);
+            if(!FileUtil.exist(floorKeyPath)){
+                continue;
+            }
+            String cmd = CmdConstant.LAYOUT_DETECT;
+            cmd = cmd.replace("@in", floorKeyPath);
+            cmd = cmd.replace("@out", detectPath);
+            CmdUtils.callLineWin(cmd, 50);
+            if (ComputerUtil.checkComputeCompleted(detectPath,5, 500)) {
+                result.put(subgroup, true);
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public boolean detFloorPlanAi(String num, String path, LinkedHashMap<Integer, Boolean> detFloorplan, String bucket) throws IOException {
+
+        try {
+            String aiJsonKey = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "floorplan/ai.json";
+            //先清空历史数据,因为数据格式改动很多个版本,已经无法按照规律进行过滤删除,所以这里先删除历史数据,而后再根据算法生成去插入数据
+            sceneMarkShapeService.remove(new LambdaQueryWrapper<SceneMarkShape>().eq(SceneMarkShape::getNum, num).eq(SceneMarkShape::getType, DetectType.PLAN.getCode()));
+            if(ossUtil.doesObjectExist(bucket, aiJsonKey)){
+                ossUtil.deleteObject(bucket, aiJsonKey);
+            }
+            if(CollUtil.isEmpty(detFloorplan)){
+                return false;
+            }
+            boolean hasFloorplanAi = false;
+            String workDir = path + "/detFloorplan/";
+            for (Integer subgroup : detFloorplan.keySet()) {
+                Boolean yes = detFloorplan.get(subgroup);
+                SceneMarkShape sceneMarkShape = null;
+                if(yes){
+                    String detectPath = workDir + subgroup + "/detect.json";
+                    sceneMarkShape = sceneMarkShapeService.readDetectJson(detectPath);
+                }
+                if (ObjUtil.isNull(sceneMarkShape)){
+                    sceneMarkShape = new SceneMarkShape();
+                    String infoJsonPath = path + "/results/floorplan/info.json";
+                    JSONObject infoObj = JSON.parseObject(FileUtil.readUtf8String(infoJsonPath));
+                    JSONArray floors = infoObj.getJSONArray("floors");
+                    for (Object floor : floors) {
+                        JSONObject floorObj = (JSONObject)floor;
+                        Integer group = floorObj.getInteger("subgroup");
+                        if(!subgroup.equals(group)){
+                            continue;
+                        }
+                        JSONObject resolution = floorObj.getJSONObject("resolution");
+                        sceneMarkShape.setImageWidth(resolution.getInteger("width"));
+                        sceneMarkShape.setImageHeight(resolution.getInteger("height"));
+                    }
+                }
+                if(Objects.isNull(sceneMarkShape.getShapes())){
+                    sceneMarkShape.setShapes(new ArrayList<>());
+                }
+                sceneMarkShape.setNum(num);
+                sceneMarkShape.setCreateTime(new Date());
+                sceneMarkShape.setType(DetectType.PLAN.getCode());
+                sceneMarkShapeService.save(sceneMarkShape);
+                if(CollUtil.isNotEmpty(sceneMarkShape.getShapes())){
+                    hasFloorplanAi = true;
+                }
+            }
+
+            List<SceneMarkShape> sceneMarkShapes = sceneMarkShapeService.findByNumAndType(num, DetectType.PLAN.getCode());
+            for (SceneMarkShape ms : sceneMarkShapes) {
+                if (ObjectUtil.isNotEmpty(ms.getShapes())){
+                    for (JSONObject s : ms.getShapes()) {
+                        String category = s.getString("category");
+                        if (category.contains("Tag_")){
+                            s.put("category","Tag");
+                        }
+                    }
+                }
+            }
+
+            ossUtil.uploadFileBytes(bucket, aiJsonKey, JSON.toJSONString(sceneMarkShapes).getBytes(StandardCharsets.UTF_8));
+            return hasFloorplanAi;
+        }catch (Exception e){
+            log.error("平面图ai识别处理报错", e);
+            return false;
+        }finally {
+//            FileUtil.del(workDir);
+        }
+    }
+}

+ 2 - 0
src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java

@@ -243,6 +243,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         sceneJson.setModelKind(scenePlusExt.getModelKind());
         sceneJson.setModelKind(scenePlusExt.getModelKind());
         sceneJson.setOrientation(scenePlusExt.getOrientation());
         sceneJson.setOrientation(scenePlusExt.getOrientation());
         sceneJson.setHasRecognition(scenePlusExt.getHasRecognition());
         sceneJson.setHasRecognition(scenePlusExt.getHasRecognition());
+        sceneJson.setHasFloorplanAi(scenePlus.getHasFloorplanAi());
         if(StrUtil.isNotEmpty(scenePlusExt.getVideos())){
         if(StrUtil.isNotEmpty(scenePlusExt.getVideos())){
             sceneJson.setVideos(scenePlusExt.getVideos());
             sceneJson.setVideos(scenePlusExt.getVideos());
         }
         }
@@ -501,6 +502,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         sceneInfoVO.setStarted(JSON.parseObject(sceneEditInfoExt.getStarted()));
         sceneInfoVO.setStarted(JSON.parseObject(sceneEditInfoExt.getStarted()));
         sceneInfoVO.setOrientation(scenePlusExt.getOrientation());
         sceneInfoVO.setOrientation(scenePlusExt.getOrientation());
         sceneInfoVO.setHasRecognition(scenePlusExt.getHasRecognition());
         sceneInfoVO.setHasRecognition(scenePlusExt.getHasRecognition());
+        sceneInfoVO.setHasFloorplanAi(scenePlus.getHasFloorplanAi());
 
 
         sceneInfoVO.setBucket(mappping);
         sceneInfoVO.setBucket(mappping);
 
 

+ 28 - 0
src/main/java/com/fdkankan/scene/service/impl/SceneMarkShapeServiceImpl.java

@@ -13,8 +13,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.model.constants.ConstantFilePath;
 import com.fdkankan.model.constants.ConstantFilePath;
 import com.fdkankan.scene.entity.SceneMarkShape;
 import com.fdkankan.scene.entity.SceneMarkShape;
+import com.fdkankan.scene.entity.SceneShapeEnum;
 import com.fdkankan.scene.mapper.MarkShapeMapper;
 import com.fdkankan.scene.mapper.MarkShapeMapper;
 import com.fdkankan.scene.service.ISceneMarkShapeService;
 import com.fdkankan.scene.service.ISceneMarkShapeService;
+import com.fdkankan.scene.service.SceneShapeEnumService;
 import com.fdkankan.scene.util.ConverxyUtil;
 import com.fdkankan.scene.util.ConverxyUtil;
 import com.fdkankan.scene.vo.SceneMarkShapeParamVO;
 import com.fdkankan.scene.vo.SceneMarkShapeParamVO;
 import com.fdkankan.scene.vo.SceneMarkShapeReDetectParamVO;
 import com.fdkankan.scene.vo.SceneMarkShapeReDetectParamVO;
@@ -44,6 +46,9 @@ public class SceneMarkShapeServiceImpl extends ServiceImpl<MarkShapeMapper, Scen
 //    private String yolov5TrainQueue;
 //    private String yolov5TrainQueue;
     @Value("${main.url:xxx}")
     @Value("${main.url:xxx}")
     private String mainUrl;
     private String mainUrl;
+    @Autowired
+    private SceneShapeEnumService sceneShapeEnumService;
+
 
 
     @Override
     @Override
     public void editTrainStatus(SceneMarkShapeParamVO param) {
     public void editTrainStatus(SceneMarkShapeParamVO param) {
@@ -191,4 +196,27 @@ public class SceneMarkShapeServiceImpl extends ServiceImpl<MarkShapeMapper, Scen
         wrapper.eq(SceneMarkShape::getNum,num);
         wrapper.eq(SceneMarkShape::getNum,num);
         return list(wrapper);
         return list(wrapper);
     }
     }
+
+    @Override
+    public SceneMarkShape readDetectJson(String jsonPath) {
+        String strings = FileUtil.readString(jsonPath, "UTF-8");
+        JSONObject bbbb = JSONObject.parseObject(strings);
+        SceneMarkShape parse = JSONObject.toJavaObject(bbbb, SceneMarkShape.class);
+        if (ObjectUtil.isNull(parse.getShapes())){
+            return null;
+        }
+        List<JSONObject> shapes = parse.getShapes();
+        for (JSONObject shape : shapes) {
+            SceneShapeEnum category = sceneShapeEnumService.findByClassName(shape.getString("category"));
+            if (ObjectUtil.isNull(category)){
+                SceneShapeEnum sceneShapeEnum = new SceneShapeEnum();
+                //删除数字shape.getString("name")
+                String nameWithoutNumbers = shape.getString("name").replaceAll("\\d+", "");
+                sceneShapeEnum.setName(nameWithoutNumbers);
+                sceneShapeEnum.setClassName(shape.getString("category"));
+                sceneShapeEnumService.save(sceneShapeEnum);
+            }
+        }
+        return parse;
+    }
 }
 }

+ 17 - 3
src/main/java/com/fdkankan/scene/service/impl/ScenePlusServiceImpl.java

@@ -105,6 +105,8 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
     private ISceneDelLogService sceneDelLogService;
     private ISceneDelLogService sceneDelLogService;
     @Autowired
     @Autowired
     private ICommonService commonService;
     private ICommonService commonService;
+    @Autowired
+    private FloorplanAiService floorplanAiService;
 
 
     @Override
     @Override
     public ScenePlus getScenePlusByNum(String num) {
     public ScenePlus getScenePlusByNum(String num) {
@@ -288,7 +290,7 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
     @Override
     @Override
     public ResultData initScene(String bucket, String num, String title, String des, Integer sceneSource,
     public ResultData initScene(String bucket, String num, String title, String des, Integer sceneSource,
         String dataSource, Integer sceneScheme, String sceneResolution, String sceneFrom, String mdoelKind, Date algorithmTime,
         String dataSource, Integer sceneScheme, String sceneResolution, String sceneFrom, String mdoelKind, Date algorithmTime,
-                                String orientation) {
+                                String orientation) throws Exception {
 
 
         ScenePlus scenePlus = this.getScenePlusByNum(num);
         ScenePlus scenePlus = this.getScenePlusByNum(num);
 
 
@@ -304,7 +306,7 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
             scenePlus = new ScenePlus();
             scenePlus = new ScenePlus();
         }
         }
         scenePlus.setNum(num);
         scenePlus.setNum(num);
-        scenePlus.setSceneStatus(SceneStatus.SUCCESS.code());
+        scenePlus.setSceneStatus(SceneStatus.wait.code());
         scenePlus.setSceneSource(sceneSource);
         scenePlus.setSceneSource(sceneSource);
         scenePlus.setPayStatus(PayStatus.PAY.code());
         scenePlus.setPayStatus(PayStatus.PAY.code());
         scenePlus.setSceneType(SceneType.OTHER.code());
         scenePlus.setSceneType(SceneType.OTHER.code());
@@ -360,7 +362,6 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
         sceneEditInfoExt.setEditInfoId(sceneEditInfo.getId());
         sceneEditInfoExt.setEditInfoId(sceneEditInfo.getId());
         sceneEditInfoExt.setLinks(this.checkIsExistLinks(num) ? CommonStatus.YES.code().intValue() : CommonStatus.NO.code().intValue());
         sceneEditInfoExt.setLinks(this.checkIsExistLinks(num) ? CommonStatus.YES.code().intValue() : CommonStatus.NO.code().intValue());
         sceneEditInfoExtService.saveOrUpdate(sceneEditInfoExt);
         sceneEditInfoExtService.saveOrUpdate(sceneEditInfoExt);
-        sceneEditInfoExt = sceneEditInfoExtService.getByEditInfoId(sceneEditInfo.getId());
 
 
         //生成编辑显示控制表
         //生成编辑显示控制表
         SceneEditControls sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfo.getId());
         SceneEditControls sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfo.getId());
@@ -375,6 +376,18 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
         sceneEditControlsService.saveOrUpdate(sceneEditControls);
         sceneEditControlsService.saveOrUpdate(sceneEditControls);
         sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfo.getId());
         sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfo.getId());
 
 
+        //平面图ai识别
+        LinkedHashMap<Integer, Boolean> detFloorplan = floorplanAiService.detFloorplan(dataSource);
+        boolean hasFloorplanAi = floorplanAiService.detFloorPlanAi(num, dataSource, detFloorplan, bucket);
+        if(hasFloorplanAi){
+            scenePlus.setHasFloorplanAi(CommonStatus.YES.code().intValue());
+        }else{
+            scenePlus.setHasFloorplanAi(CommonStatus.NO.code().intValue());
+        }
+        scenePlus.setSceneStatus(SceneStatus.SUCCESS.code());
+        this.saveOrUpdate(scenePlus);
+
+
         //清除用户编辑业务数据
         //清除用户编辑业务数据
         Set<String> bizs = new HashSet<>();
         Set<String> bizs = new HashSet<>();
         bizs.add(UserEditDataType.BOX_MODEL.message());
         bizs.add(UserEditDataType.BOX_MODEL.message());
@@ -405,6 +418,7 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
             List<JSONObject> mosaicList = JSON.parseObject(oldSceneJson, SceneJsonBean.class).getMosaicList();
             List<JSONObject> mosaicList = JSON.parseObject(oldSceneJson, SceneJsonBean.class).getMosaicList();
             sceneJson.setMosaicList(mosaicList);
             sceneJson.setMosaicList(mosaicList);
         }
         }
+        sceneJson.setHasFloorplanAi(scenePlus.getHasFloorplanAi());
         //本地写sceneJson文件
         //本地写sceneJson文件
         ossUtil.uploadFileBytes(bucket, sceneJsonPath, JSON.toJSONString(sceneJson).getBytes(StandardCharsets.UTF_8));
         ossUtil.uploadFileBytes(bucket, sceneJsonPath, JSON.toJSONString(sceneJson).getBytes(StandardCharsets.UTF_8));
 
 

+ 1 - 1
src/main/java/com/fdkankan/scene/util/CmdUtils.java

@@ -57,7 +57,7 @@ public class CmdUtils {
      *
      *
      * @param command
      * @param command
      */
      */
-    private static void callLineWin(String command, Integer lineSize) {
+    public static void callLineWin(String command, Integer lineSize) {
         CmdUtils.log.info("cmd: " + command);
         CmdUtils.log.info("cmd: " + command);
         try {
         try {
             String[] cmd = new String[]{"cmd ", "/c", command};
             String[] cmd = new String[]{"cmd ", "/c", command};

+ 2 - 0
src/main/java/com/fdkankan/scene/vo/SceneInfoVO.java

@@ -272,4 +272,6 @@ public class SceneInfoVO {
 
 
     private Integer hasRecognition;
     private Integer hasRecognition;
 
 
+    private Integer hasFloorplanAi;
+
 }
 }