浏览代码

Merge branch 'release-floorplanai' into release

dengsixing 1 周之前
父节点
当前提交
d317025051

+ 3 - 2
src/main/java/com/fdkankan/contro/bean/SceneJsonBean.java

@@ -1,15 +1,14 @@
 package com.fdkankan.contro.bean;
 
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.annotation.TableField;
 import com.fdkankan.contro.vo.SceneEditControlsVO;
-import java.util.List;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
 import java.util.Date;
+import java.util.List;
 
 /**
  * <p>
@@ -223,5 +222,7 @@ public class SceneJsonBean {
 
     private Integer hasRecognition;
 
+    private Integer hasFloorplanAi;
+
 
 }

+ 6 - 0
src/main/java/com/fdkankan/contro/entity/ScenePlus.java

@@ -128,4 +128,10 @@ public class ScenePlus implements Serializable {
     @TableField("source_id")
     private Long sourceId;
 
+    /**
+     * 是否有平面图i识别
+     */
+    @TableField("has_floorplan_ai")
+    private Integer hasFloorplanAi;
+
 }

+ 11 - 0
src/main/java/com/fdkankan/contro/mq/service/impl/BuildSceneServiceImpl.java

@@ -302,6 +302,17 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             //生成floorpan.json
             commonService.uploadFloorplanJson(sceneCode, path);
 
+            //江门需求,算法识别平面图
+            commonService.uploadFloorplanAi(sceneCode, path);
+
+            LinkedHashMap<Integer, Boolean> detFloorplan = message.getDetFloorplan();
+            boolean hasFloorplanAi = commonService.detFloorPlanAi(sceneCode, path, detFloorplan);
+            if(hasFloorplanAi){
+                scenePlus.setHasFloorplanAi(CommonStatus.YES.code().intValue());
+            }else{
+                scenePlus.setHasFloorplanAi(CommonStatus.NO.code().intValue());
+            }
+
             //重置异步操作记录
             commonService.removeSceneAsynOperLog(sceneCode);
 

+ 6 - 1
src/main/java/com/fdkankan/contro/service/ICommonService.java

@@ -2,9 +2,10 @@ package com.fdkankan.contro.service;
 
 import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.contro.entity.*;
-import com.fdkankan.contro.vo.ScenePlusVO;
 import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
 
+import java.io.IOException;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
 
@@ -65,4 +66,8 @@ public interface ICommonService {
 
     Integer getSlamCount(String num);
 
+    void uploadFloorplanAi(String num, String path) throws IOException;
+
+    boolean detFloorPlanAi(String num, String path, LinkedHashMap<Integer, Boolean> detFloorplan) throws IOException;
+
 }

+ 5 - 0
src/main/java/com/fdkankan/contro/service/ISceneMarkShapeService.java

@@ -10,6 +10,11 @@ import java.util.List;
  * Created by Xiewj on 2021/11/23 0026 10:14
  */
 public interface ISceneMarkShapeService extends IService<SceneMarkShape> {
+
+    SceneMarkShape readDetectJson(String jsonPath);
+
+    List<SceneMarkShape> readDetectJsonStr(String num,String context);
+
     SceneMarkShape findByNumAndImagePathAndType(String num, String imagePath,Integer type);
 
     List<SceneMarkShape> findByNumAndType(String num, Integer type);

+ 111 - 12
src/main/java/com/fdkankan/contro/service/impl/CommonServiceImpl.java

@@ -3,25 +3,24 @@ package com.fdkankan.contro.service.impl;
 import cn.hutool.core.bean.BeanUtil;
 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 cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.ZipUtil;
 import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.fdkankan.common.constant.*;
-import com.fdkankan.common.util.FileUtils;
-import cn.hutool.core.util.StrUtil;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.common.constant.*;
 import com.fdkankan.common.util.FileUtils;
 import com.fdkankan.contro.bean.SceneJsonBean;
+import com.fdkankan.contro.constant.DetectType;
 import com.fdkankan.contro.entity.*;
 import com.fdkankan.contro.factory.UserEditData.UserEditDataHandler;
 import com.fdkankan.contro.factory.UserEditData.UserEditDataHandlerFactory;
-import com.fdkankan.contro.service.ICommonService;
 import com.fdkankan.contro.service.*;
 import com.fdkankan.contro.vo.SceneEditControlsVO;
-import com.fdkankan.contro.vo.ScenePlusVO;
 import com.fdkankan.fyun.config.FYunFileConfig;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.model.constants.ConstantFileName;
@@ -46,13 +45,8 @@ import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
 import java.io.File;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.security.GeneralSecurityException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.Objects;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -122,6 +116,8 @@ public class CommonServiceImpl implements ICommonService {
     private ISceneInfoSyncMqConfigService sceneInfoSyncMqConfigService;
     @Resource
     private FYunFileServiceInterface fYunFileService;
+    @Autowired
+    private ISceneMarkShapeService sceneMarkShapeService;
 
     @Override
     public void uploadBuildResultData(String num, String dataSource, String version) {
@@ -488,6 +484,7 @@ public class CommonServiceImpl implements ICommonService {
         sceneJson.setVideos(scenePlusExt.getVideos());
         sceneJson.setPayStatus(scenePlus.getPayStatus());
         sceneJson.setHasRecognition(scenePlusExt.getHasRecognition());
+        sceneJson.setHasFloorplanAi(scenePlus.getHasFloorplanAi());
         if(StrUtil.isNotEmpty(oldSceneJson)){
             SceneJsonBean oldSceneJsonBean = JSON.parseObject(oldSceneJson, SceneJsonBean.class);
             List<JSONObject> mosaicList = JSON.parseObject(oldSceneJson, SceneJsonBean.class).getMosaicList();
@@ -860,4 +857,106 @@ public class CommonServiceImpl implements ICommonService {
 
         return slamCount;
     }
+
+    @Override
+    public void uploadFloorplanAi(String num, String path) throws IOException {
+        String floorplanPath = path + "/results/floorplan/";
+        List<File> files = FileUtil.loopFiles(floorplanPath);
+        String ossPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "floorplan/";
+        if(CollUtil.isNotEmpty(files)){
+            for (File file : files) {
+                fYunFileService.uploadFile(file.getAbsolutePath(), file.getAbsolutePath().replace(floorplanPath, ossPath));
+            }
+        }
+    }
+
+    @Override
+    public boolean detFloorPlanAi(String num, String path, LinkedHashMap<Integer, Boolean> detFloorplan) throws IOException {
+
+        try {
+            String aiJsonKey = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "floorplan/ai.json";
+            String aiEntireJsonKey = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "floorplan/ai-entire.json";
+            //先清空历史数据,因为数据格式改动很多个版本,已经无法按照规律进行过滤删除,所以这里先删除历史数据,而后再根据算法生成去插入数据
+            sceneMarkShapeService.remove(new LambdaQueryWrapper<SceneMarkShape>().eq(SceneMarkShape::getNum, num).eq(SceneMarkShape::getType, DetectType.PLAN.getCode()));
+            if(fYunFileService.fileExist(aiJsonKey)){
+                fYunFileService.deleteFile(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");
+                        }
+                    }
+                }
+            }
+            //先上传一份带门窗的,完整的,绘图功能要用
+            fYunFileService.uploadFile(JSON.toJSONString(sceneMarkShapes).getBytes(StandardCharsets.UTF_8), aiEntireJsonKey);
+
+            //上传一份过滤掉门窗的,徐总要求过滤
+            for (SceneMarkShape sceneMarkShape : sceneMarkShapes) {
+                //徐总要求去掉门窗(因为门窗不属于家具)
+                List<JSONObject> shapes = sceneMarkShape.getShapes().stream().filter(v -> {
+                    String category = v.getString("category");
+                    if (StrUtil.isNotEmpty(category) && (category.contains("Door") || category.contains("Window"))) {
+                        return false;
+                    }
+                    return true;
+                }).collect(Collectors.toList());
+                sceneMarkShape.setShapes(shapes);
+            }
+            fYunFileService.uploadFile(JSON.toJSONString(sceneMarkShapes).getBytes(StandardCharsets.UTF_8), aiJsonKey);
+
+            return hasFloorplanAi;
+        }catch (Exception e){
+            log.error("平面图ai识别处理报错", e);
+            return false;
+        }finally {
+//            FileUtil.del(workDir);
+        }
+    }
+
+
 }

+ 55 - 1
src/main/java/com/fdkankan/contro/service/impl/SceneMarkShapeServiceImpl.java

@@ -1,9 +1,15 @@
 package com.fdkankan.contro.service.impl;
 
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.contro.constant.DetectType;
 import com.fdkankan.contro.entity.SceneMarkShape;
+import com.fdkankan.contro.entity.SceneShapeEnum;
 import com.fdkankan.contro.mapper.MarkShapeMapper;
 import com.fdkankan.contro.service.ISceneMarkShapeService;
 import com.fdkankan.contro.service.SceneShapeEnumService;
@@ -11,6 +17,7 @@ import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.ArrayList;
 import java.util.List;
 
 
@@ -22,7 +29,54 @@ import java.util.List;
 public class SceneMarkShapeServiceImpl extends ServiceImpl<MarkShapeMapper, SceneMarkShape> implements ISceneMarkShapeService {
 
     @Autowired
-    SceneShapeEnumService sceneShapeEnumService;
+    private SceneShapeEnumService sceneShapeEnumService;
+
+    @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;
+    }
+
+
+    @Override
+    public List<SceneMarkShape> readDetectJsonStr(String num,String context) {
+        JSONObject bbbb = JSONObject.parseObject(context);
+        JSONArray imgBoxsList = bbbb.getJSONArray("imgBoxsList");
+        List<SceneMarkShape> list = new ArrayList<>();
+        for (Object o : imgBoxsList) {
+            SceneMarkShape parse = JSONObject.toJavaObject(JSONObject.parseObject(String.valueOf(o)), SceneMarkShape.class);
+            System.out.println(parse);
+            if (ObjectUtil.isNull(parse.getShapes())){
+                return null;
+            }
+            parse.setType(DetectType.PANO.getCode());
+            parse.setNum(num);
+            List<JSONObject> shapes = parse.getShapes();
+            for (JSONObject shape : shapes) {
+                shape.remove("name");
+            }
+            list.add(parse);
+        }
+
+        return list;
+    }
 
     @Override
     public SceneMarkShape findByNumAndImagePathAndType(String num, String imagePath, Integer type) {