Bläddra i källkod

Merge branch 'release' into project-jp

# Conflicts:
#	src/main/java/com/fdkankan/scene/controller/SceneEditController.java
#	src/main/java/com/fdkankan/scene/controller/TestController.java
#	src/main/java/com/fdkankan/scene/generate/AutoGenerate.java
#	src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java
#	src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java
dsx 2 år sedan
förälder
incheckning
205346cee9
33 ändrade filer med 1487 tillägg och 1656 borttagningar
  1. 6 0
      pom.xml
  2. 22 0
      src/main/java/com/fdkankan/scene/bean/BodySegmentStatusBean.java
  3. 21 0
      src/main/java/com/fdkankan/scene/controller/SceneAsynOperLogController.java
  4. 29 6
      src/main/java/com/fdkankan/scene/controller/SceneController.java
  5. 8 0
      src/main/java/com/fdkankan/scene/controller/SceneEditController.java
  6. 150 0
      src/main/java/com/fdkankan/scene/controller/SceneMarkShapeController.java
  7. 26 0
      src/main/java/com/fdkankan/scene/entity/SceneEditControls.java
  8. 74 0
      src/main/java/com/fdkankan/scene/entity/SceneMarkShape.java
  9. 6 0
      src/main/java/com/fdkankan/scene/entity/ScenePlus.java
  10. 33 0
      src/main/java/com/fdkankan/scene/httpclient/MyClient.java
  11. 26 5
      src/main/java/com/fdkankan/scene/listener/RabbitMqListener.java
  12. 16 0
      src/main/java/com/fdkankan/scene/mapper/MarkShapeMapper.java
  13. 2 0
      src/main/java/com/fdkankan/scene/service/ISceneEditService.java
  14. 30 0
      src/main/java/com/fdkankan/scene/service/ISceneMarkShapeService.java
  15. 16 0
      src/main/java/com/fdkankan/scene/service/ISceneService.java
  16. 109 73
      src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java
  17. 21 0
      src/main/java/com/fdkankan/scene/service/impl/SceneEditServiceImpl.java
  18. 181 0
      src/main/java/com/fdkankan/scene/service/impl/SceneMarkShapeServiceImpl.java
  19. 38 99
      src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java
  20. 169 1473
      src/main/java/com/fdkankan/scene/service/impl/SceneServiceImpl.java
  21. 121 0
      src/main/java/com/fdkankan/scene/util/ConverxyUtil.java
  22. 98 0
      src/main/java/com/fdkankan/scene/util/OssBodySegmentUtil.java
  23. 97 0
      src/main/java/com/fdkankan/scene/util/test.java
  24. 24 0
      src/main/java/com/fdkankan/scene/vo/SceneEditControlsParamVO.java
  25. 21 0
      src/main/java/com/fdkankan/scene/vo/SceneEditControlsVO.java
  26. 6 0
      src/main/java/com/fdkankan/scene/vo/SceneInfoVO.java
  27. 39 0
      src/main/java/com/fdkankan/scene/vo/SceneMarkShapeDetectParamVO.java
  28. 36 0
      src/main/java/com/fdkankan/scene/vo/SceneMarkShapeParamVO.java
  29. 46 0
      src/main/java/com/fdkankan/scene/vo/SceneMarkShapeReDetectParamVO.java
  30. 4 0
      src/main/resources/bootstrap-prod-eur.yml
  31. 4 0
      src/main/resources/bootstrap-prod.yml
  32. 4 0
      src/main/resources/bootstrap-test-eur.yml
  33. 4 0
      src/main/resources/bootstrap-test.yml

+ 6 - 0
pom.xml

@@ -140,6 +140,12 @@
             <version>6.8.1</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>imageseg20191230</artifactId>
+            <version>1.0.5</version>
+        </dependency>
+
     </dependencies>
 
     <dependencyManagement>

+ 22 - 0
src/main/java/com/fdkankan/scene/bean/BodySegmentStatusBean.java

@@ -0,0 +1,22 @@
+package com.fdkankan.scene.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BodySegmentStatusBean {
+
+    private String uuid;
+
+    private Integer status;
+
+    private String imageUrl;
+
+
+
+}

+ 21 - 0
src/main/java/com/fdkankan/scene/controller/SceneAsynOperLogController.java

@@ -0,0 +1,21 @@
+package com.fdkankan.scene.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author 
+ * @since 2022-12-07
+ */
+@RestController
+@RequestMapping("/scene/sceneAsynOperLog")
+public class SceneAsynOperLogController {
+
+}
+

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

@@ -2,6 +2,8 @@ package com.fdkankan.scene.controller;
 
 
 import com.fdkankan.common.constant.SceneInfoReqType;
+import com.fdkankan.scene.annotation.CheckPermit;
+import com.fdkankan.scene.service.ISceneService;
 import com.fdkankan.web.response.ResultData;
 import com.fdkankan.scene.service.ISceneEditInfoService;
 import com.fdkankan.scene.service.IScenePlusService;
@@ -12,11 +14,8 @@ import com.fdkankan.scene.vo.SceneInfoVO;
 import com.fdkankan.web.controller.BaseController;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * <p>
@@ -34,6 +33,8 @@ public class SceneController extends BaseController {
     private ISceneEditInfoService sceneEditInfoService;
     @Autowired
     private IScenePlusService scenePlusService;
+    @Autowired
+    private ISceneService sceneService;
 
     /**
      * <p>
@@ -70,7 +71,6 @@ public class SceneController extends BaseController {
      * </p>
      * @author dengsixing
      * @date 2022/8/1
-     * @param param
      * @return com.fdkankan.web.response.ResultData
      **/
     @GetMapping(value = "/downLoadZSData")
@@ -78,5 +78,28 @@ public class SceneController extends BaseController {
         return scenePlusService.downLoadZSData(sceneNum);
     }
 
+    /**
+     * 上传人体抠图原图
+     * @param num
+     * @param file
+     * @return
+     * @throws Exception
+     */
+    @PostMapping(value = "/uploadBodySegment")
+    public ResultData uploadBodySegment(@RequestParam("file") MultipartFile file,
+                                        @RequestParam(value = "rotate", required = false) Integer rotate) throws Exception {
+        return sceneService.uploadBodySegment(file, rotate);
+    }
+
+    /**
+     * 获取人体抠图提取状态
+     * @return ResultData
+     * @throws Exception
+     */
+    @PostMapping(value = "/getBodySegmentStatus")
+    public ResultData getBodySegmentStatus(@RequestParam(value = "serialNum") String uuid) throws Exception {
+        return sceneService.getBodySegmentStatus(uuid);
+    }
+
 }
 

+ 8 - 0
src/main/java/com/fdkankan/scene/controller/SceneEditController.java

@@ -878,5 +878,13 @@ public class SceneEditController extends BaseController {
         return sceneAsynOperLogService.getAsynOperLog(param);
     }
 
+    /**
+     * 获取编辑器版本信息
+     * @return
+     */
+    @GetMapping("/getServiceUpTip")
+    public ResultData getServiceUpTip(){
+        return sceneEditService.getServiceUpTip();
+    }
 
 }

+ 150 - 0
src/main/java/com/fdkankan/scene/controller/SceneMarkShapeController.java

@@ -0,0 +1,150 @@
+package com.fdkankan.scene.controller;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import com.fdkankan.scene.entity.SceneMarkShape;
+import com.fdkankan.scene.entity.ScenePlus;
+import com.fdkankan.scene.entity.ScenePlusExt;
+import com.fdkankan.scene.service.ISceneMarkShapeService;
+import com.fdkankan.scene.service.IScenePlusExtService;
+import com.fdkankan.scene.service.IScenePlusService;
+import com.fdkankan.scene.vo.SceneMarkShapeDetectParamVO;
+import com.fdkankan.scene.vo.SceneMarkShapeParamVO;
+import com.fdkankan.scene.vo.SceneMarkShapeReDetectParamVO;
+import com.fdkankan.web.controller.BaseController;
+import com.fdkankan.web.response.ResultData;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 初始化接口
+ *
+ * @author fdkk
+ */
+@RestController
+@RequestMapping("/service/scene/sceneMarkShape")
+@Slf4j
+public class SceneMarkShapeController extends BaseController
+{
+    @Value("${queue.scene.yolov5-detect-queue}")
+    private String yolov5DetectQueue;
+    @Autowired
+    private ISceneMarkShapeService sceneMarkShapeService;
+    @Resource
+    private FYunFileServiceInterface fYunFileService;
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
+    @Value("${fyun.host}")
+    private String ossUrlPrefix;
+    @Autowired
+    private RabbitMqProducer rabbitMqProducer;
+    @Value("${main.url}")
+    private String mainUrl;
+
+
+    /**
+     * 获取场景全景图路径连接
+     */
+    @PostMapping("/getPanorama")
+    public ResultData getPanorama(@RequestBody @Validated  SceneMarkShapeParamVO param) {
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
+        if(ObjectUtil.isNotNull(scenePlus)) {
+            ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+            if (ObjectUtil.isNotNull(scenePlus)) {
+                String publicUserPath = String.format(UploadFilePath.scene_result_data_path, param.getNum());
+                List<String> panoramaList = fYunFileService.listRemoteFiles(scenePlusExt.getYunFileBucket(), publicUserPath + "caches/images/");
+                List<String> panoramaListUrl = panoramaList.stream().filter(f -> FileUtil.extName(f).equals("jpg")).map(s -> ossUrlPrefix + s).collect(Collectors.toList());
+                return ResultData.ok(panoramaListUrl);
+            }
+        }
+        return ResultData.ok("场景数据不存在");
+    }
+    /**
+     * 根据场景码和图片名称获取数据
+     */
+    @PostMapping("/getInfo")
+    public ResultData getInfo(@RequestBody @Validated  SceneMarkShapeParamVO param) {
+        SceneMarkShape res=  sceneMarkShapeService.findByNumAndImagePath(param.getNum(),param.getImagePath());
+        return ResultData.ok(res);
+    }
+    /**
+     * 将需要推理的场景推入到队列
+     */
+    @PostMapping("/detectScene")
+    public ResultData detect(@RequestBody @Validated SceneMarkShapeDetectParamVO param) {
+        param.setWebSite(mainUrl);
+        rabbitMqProducer.sendByWorkQueue(yolov5DetectQueue, param);
+        return ResultData.ok();
+    }
+    /**
+     * 将需要训练的场景推入到队列
+     */
+    @PostMapping("/trainScene")
+    public ResultData trainScene(@RequestBody @Validated SceneMarkShapeReDetectParamVO param) {
+        sceneMarkShapeService.trainScene(param);
+        return ResultData.ok();
+    }
+    /**
+     * 将需要重新推理的场景推入到队列
+     */
+    @PostMapping("/editReDetectStatus")
+    public ResultData editReDetectStatus(@RequestBody @Validated SceneMarkShapeParamVO param) {
+        sceneMarkShapeService.editTrainStatus(param);
+        return ResultData.ok();
+    }
+    /**
+     * 保存或者修改
+     */
+    @PostMapping("/saveOrEdit")
+    public ResultData save(@RequestParam(value = "num") String num,@RequestParam("file") MultipartFile file) throws IOException {
+        sceneMarkShapeService.saveFileToDB(file,num);
+        return ResultData.ok();
+    }
+    /**
+     * 保存或者修改JSON
+     */
+    @PostMapping("/saveOrEditJson")
+    public ResultData saveOrEditJson(@RequestBody SceneMarkShape param) {
+        SceneMarkShape shape = sceneMarkShapeService.findByNumAndImagePath(param.getNum(), param.getImagePath());
+        if (ObjectUtil.isNotNull(shape)){
+            param.setId(shape.getId());
+            param.setUpdateTime(new Date());
+            return ResultData.ok(sceneMarkShapeService.updateById(param));
+        }else {
+            param.setCreateTime(new Date());
+            return ResultData.ok(sceneMarkShapeService.save(param));
+        }
+    }
+    /**
+     * 保存或者修改JSON
+     */
+    @PostMapping("/editLabel")
+    public ResultData editLabel(@RequestParam(value = "num") String num,@RequestParam(value = "imgPath") String imgPath,@RequestParam("file") MultipartFile file) throws IOException {
+        log.info("进入editLabel---num{},imgPath{}",num,imgPath);
+        return sceneMarkShapeService.editLabelByFile(num, imgPath, file);
+    }
+    /**
+     * 保存或者修改JSON
+     */
+    @PostMapping("/testquery")
+    public ResultData testquery()   {
+        Map<String, List<SceneMarkShape>> res=new HashMap<>();
+        res.put("findByReTrainStatus",sceneMarkShapeService.findByReTrainStatus(1));
+        res.put("findByToTrainStatus",sceneMarkShapeService.findByToTrainStatus(0));
+        return ResultData.ok(res);
+    }
+}

+ 26 - 0
src/main/java/com/fdkankan/scene/entity/SceneEditControls.java

@@ -88,6 +88,32 @@ public class SceneEditControls implements Serializable {
     @TableField("show_rule")
     private Integer showRule;
 
+
+    /**
+     * 是否展示标尺(0-不需要,1-需要)
+     */
+    @TableField("show_scale")
+    private Integer showScale;
+
+    /**
+     * 是否展示分享场景(0-不需要,1-需要)
+     */
+    @TableField("show_share")
+    private Integer showShare;
+
+    /**
+     * 是否展示分享热点(0-不需要,1-需要)
+     */
+    @TableField("show_tagshare")
+    private Integer showTagshare;
+
+    /**
+     * 是否展示合照开关(0-不需要,1-需要)
+     */
+    @TableField("show_capture")
+    private Integer showCapture;
+
+
     /**
      * 创建时间
      */

+ 74 - 0
src/main/java/com/fdkankan/scene/entity/SceneMarkShape.java

@@ -0,0 +1,74 @@
+package com.fdkankan.scene.entity;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ * 场景标记多边形识别数据
+ * </p>
+ *
+ * @author Xiewj
+ * @date 2023/3/30
+ */
+@Data
+@TableName(value = "t_scene_mark_shape",autoResultMap = true)
+@Accessors(chain = true)
+public class SceneMarkShape implements Serializable {
+
+      /**
+       * 主键
+       */
+      @TableId(value = "id", type = IdType.AUTO)
+      private Long id;
+
+      @TableField("version")
+      private String version;
+      @TableField(typeHandler = FastjsonTypeHandler.class, value = "flag")
+      private JSONObject flag;
+
+      @TableField(typeHandler = FastjsonTypeHandler.class, value = "shapes")
+      private List<JSONObject> shapes;
+
+      @TableField("image_path")
+      private String imagePath;
+      @TableField("image_height")
+      private Integer imageHeight;
+      @TableField("image_width")
+      private Integer imageWidth;
+      @TableField("num")
+      private String num;
+      /**
+       * 0不需要 1需要
+       */
+      @TableField("re_train")
+      private Integer reTrain;
+      /**
+       * 0需要训练 1已经训练过
+       */
+      @TableField("to_train")
+      private Integer toTrain;
+
+      @TableField("create_time")
+      private Date createTime;
+
+      @TableField("update_time")
+      private Date updateTime;
+
+      /**
+       * 记录的状态,A: 生效,I: 禁用
+       */
+      @TableField("rec_status")
+      @TableLogic(value = "A", delval = "I")
+      private String recStatus;
+
+}

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

@@ -95,6 +95,12 @@ public class ScenePlus implements Serializable {
     private Integer recommend;
 
     /**
+     * 是否有housetype文件(0-否,1-是)
+     */
+    @TableField("house_type")
+    private Integer houseType;
+
+    /**
      * 创建时间
      */
     @TableField("create_time")

+ 33 - 0
src/main/java/com/fdkankan/scene/httpclient/MyClient.java

@@ -0,0 +1,33 @@
+package com.fdkankan.scene.httpclient;
+
+
+import com.dtflys.forest.annotation.Get;
+import com.dtflys.forest.annotation.Var;
+import com.dtflys.forest.callback.OnProgress;
+import com.dtflys.forest.extensions.DownloadFile;
+import com.fdkankan.web.response.ResultData;
+
+import java.io.File;
+
+public interface MyClient {
+
+    /**
+     * 在方法上加上@DownloadFile注解
+     * dir属性表示文件下载到哪个目录
+     * filename属性表示文件下载成功后以什么名字保存,如果不填,这默认从URL中取得文件名
+     * OnProgress参数为监听上传进度的回调函数
+     */
+    @Get(url = "{url}")
+    @DownloadFile(dir = "{dir}", filename = "{filename}")
+    File downloadFile(@Var("url") String url, @Var("dir") String dir, @Var("filename")String filename);
+
+    /**
+     * 在方法上加上@DownloadFile注解
+     * dir属性表示文件下载到哪个目录
+     * filename属性表示文件下载成功后以什么名字保存,如果不填,这默认从URL中取得文件名
+     * OnProgress参数为监听上传进度的回调函数
+     */
+    @Get(url = "${url}?${params}")
+    ResultData get(@Var("url") String url, @Var("params") String params);
+
+}

+ 26 - 5
src/main/java/com/fdkankan/scene/listener/RabbitMqListener.java

@@ -1,8 +1,10 @@
 package com.fdkankan.scene.listener;
 
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.scene.entity.DownloadTourVideo;
 import com.fdkankan.scene.service.IDownloadTourVideoService;
+import com.fdkankan.scene.service.ISceneService;
 import com.rabbitmq.client.Channel;
 import java.nio.charset.StandardCharsets;
 import lombok.extern.slf4j.Slf4j;
@@ -28,11 +30,13 @@ public class RabbitMqListener {
     @Value("${queue.scene.transfer-tour-video}")
     private String downloadTourVideoQueue;
 
+    @Value("${queue.bodySegment:body-segment}")
+    private String bodySegmentQueueName;
+
     @Autowired
     private IDownloadTourVideoService downloadTourVideoService;
-
-
-
+    @Autowired
+    private ISceneService sceneService;
 
     /**
      * 开启了手动确认模式,如果没有手动确认,消费者不会重试,当服务重启时会再次消费,因为rabbitmq认为你还没有处理完你的业务
@@ -59,6 +63,25 @@ public class RabbitMqListener {
      * concurrency = "3"    设置消费线程数,每个线程每次只拉取一条消息消费
      */
     @RabbitListener(
+            queuesToDeclare = @Queue("${queue.bodySegment}"),
+            concurrency = "${maxThread.bodySegment}"
+    )
+    public void bodySegment(Channel channel, Message message) throws Exception {
+        String messageId = message.getMessageProperties().getMessageId();
+        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+        log.info("开始消费消息,id:{},queue:{},content:{}", messageId, bodySegmentQueueName, msg);
+        JSONObject jsonObject = JSON.parseObject(msg);
+        sceneService.bodySegmentHandler(jsonObject.getString("imgUrl"), jsonObject.getString("uuid"));
+        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+        log.info("结束消费消息,id:{}", messageId);
+    }
+
+    /**
+     * 开启了手动确认模式,如果没有手动确认,消费者不会重试,当服务重启时会再次消费,因为rabbitmq认为你还没有处理完你的业务
+     * queuesToDeclare = @Queue("${queue.modeling.modeling-test}"),  如果队列不不存在会自动创建队列
+     * concurrency = "3"    设置消费线程数,每个线程每次只拉取一条消息消费
+     */
+    @RabbitListener(
         queuesToDeclare = @Queue("test_dsx")
     )
     public void test(Channel channel, Message message) throws Exception {
@@ -72,6 +95,4 @@ public class RabbitMqListener {
     }
 
 
-
-
 }

+ 16 - 0
src/main/java/com/fdkankan/scene/mapper/MarkShapeMapper.java

@@ -0,0 +1,16 @@
+package com.fdkankan.scene.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.scene.entity.SceneMarkShape;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author Xiewj
+ * @date 2021/11/22
+ */
+@Mapper
+@Component("MarkShapeMapper")
+public interface MarkShapeMapper extends BaseMapper<SceneMarkShape> {
+}
+

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

@@ -26,4 +26,6 @@ public interface ISceneEditService {
 
     ResultData deleteTour(BaseSceneParamVO param) throws Exception;
 
+    ResultData getServiceUpTip();
+
 }

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

@@ -0,0 +1,30 @@
+package com.fdkankan.scene.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.scene.entity.SceneMarkShape;
+import com.fdkankan.scene.vo.SceneMarkShapeParamVO;
+import com.fdkankan.scene.vo.SceneMarkShapeReDetectParamVO;
+import com.fdkankan.web.response.ResultData;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * Created by Xiewj on 2021/11/23 0026 10:14
+ */
+public interface ISceneMarkShapeService extends IService<SceneMarkShape> {
+    void saveFileToDB(MultipartFile inPath, String num) throws IOException;
+
+    SceneMarkShape findByNumAndImagePath(String num, String imagePath);
+
+    ResultData editLabelByFile(String num, String imgPath, MultipartFile file) throws IOException;
+
+    void trainScene(SceneMarkShapeReDetectParamVO param);
+
+    List<SceneMarkShape> findByReTrainStatus(Integer reTrain);
+    List<SceneMarkShape> findByToTrainStatus(Integer toTrain);
+
+    void editTrainStatus(SceneMarkShapeParamVO param);
+}

+ 16 - 0
src/main/java/com/fdkankan/scene/service/ISceneService.java

@@ -0,0 +1,16 @@
+package com.fdkankan.scene.service;
+
+import com.fdkankan.scene.bean.BodySegmentStatusBean;
+import com.fdkankan.web.response.ResultData;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+public interface ISceneService {
+
+    ResultData uploadBodySegment(MultipartFile file,Integer rotate) throws Exception;
+
+    void bodySegmentHandler(String imgUrl, String uuid);
+
+    ResultData getBodySegmentStatus(String uuid);
+
+}

+ 109 - 73
src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java

@@ -1,10 +1,9 @@
 package com.fdkankan.scene.service.impl;
 import cn.hutool.core.net.multipart.UploadFile;
 import cn.hutool.core.util.CharsetUtil;
-import com.fdkankan.common.constant.CommonOperStatus;
-import com.fdkankan.common.constant.SceneAsynFuncType;
-import com.fdkankan.common.constant.SceneAsynModuleType;
-import com.fdkankan.common.constant.SceneAsynOperType;
+import com.fdkankan.common.constant.*;
+import com.fdkankan.common.util.FileSizeUtil;
+import com.fdkankan.common.util.MD5;
 import com.fdkankan.scene.vo.SaveFiltersParamVO;
 import io.opencensus.metrics.LongGauge;
 import java.util.Date;
@@ -21,13 +20,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fdkankan.common.constant.CommonStatus;
-import com.fdkankan.common.constant.ErrorCode;
-import com.fdkankan.common.constant.FileBizType;
-import com.fdkankan.common.constant.OperationType;
-import com.fdkankan.common.constant.SceneFrom;
-import com.fdkankan.common.constant.SceneInfoReqType;
-import com.fdkankan.common.constant.ServerCode;
 import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.common.util.FileMd5Util;
 import com.fdkankan.common.util.FileUtils;
@@ -319,7 +311,10 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
 
         //删除发布数据中的user目录
         String publicUserPath = String.format(UploadFilePath.USER_VIEW_PATH, num);
-        fYunFileService.deleteFolder(bucket, publicUserPath);
+        List<String> userViewFileList = fYunFileService.listRemoteFiles(bucket, publicUserPath);
+        if(CollUtil.isNotEmpty(userViewFileList)){
+            fYunFileService.deleteFolder(bucket, publicUserPath);
+        }
 
         //复制编辑目录到发布目录
         String editPath = String.format(UploadFilePath.USER_EDIT_PATH, param.getNum());
@@ -338,11 +333,18 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
 
         scenePlus.setTitle(sceneEditInfo.getTitle());
         scenePlus.setDescription(sceneEditInfo.getDescription());
+        scenePlus.setHouseType(this.existsHouseType(bucket, num));
         scenePlusService.updateById(scenePlus);
 
         return ResultData.ok();
     }
 
+    private int existsHouseType(String bucket, String num){
+        String houseTypePath = String.format(UploadFilePath.USER_VIEW_PATH, num) + "houseType.json";
+        boolean exist = fYunFileService.fileExist(bucket, houseTypePath);
+        return exist ? CommonStatus.YES.code().intValue() : CommonStatus.NO.code().intValue();
+    }
+
     private void publicSurveillance(String num, Integer surveillances, String bucket) throws IOException {
         String surveillanceJsonPath = String.format(UploadFilePath.USER_EDIT_PATH, num) + "surveillance.json";
         if(surveillances == CommonStatus.NO.code().intValue()){
@@ -374,7 +376,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         String imgViewPath = String.format(UploadFilePath.IMG_VIEW_PATH, num);
 
         //清除发布目录中的场景关联图片
-        fYunFileService.deleteFolder(bucket,imgViewPath + "panorama");
+        if(fYunFileService.fileExist(bucket,imgViewPath + "panorama")){
+            fYunFileService.deleteFolder(bucket,imgViewPath + "panorama");
+        }
 
         //生成links.json并上传到发布目录
         String linkPanKey = String.format(RedisKey.SCENE_LINKPAN_DATA, num);
@@ -417,7 +421,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
 
         String hotJsonPath = String.format(UploadFilePath.USER_EDIT_PATH, sceneNum) + "hot.json";
         fYunFileService.uploadFile(bucket, tags.toString().getBytes(), hotJsonPath);
-        this.saveTagsToSceneEditInfo(sceneNum, sceneEditInfo);
+//        this.saveTagsToSceneEditInfo(sceneNum, sceneEditInfo);
 
     }
 
@@ -480,6 +484,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         if(CommonStatus.YES.code().intValue() == sceneEditInfoExt.getMosaic()){
             sceneInfoVO.setMosaicList(this.getMosaicList(num));
         }
+        sceneInfoVO.setSpace(FileSizeUtil.convert(scenePlusExt.getSpace(), FileSizeUnitType.MB.code()));
 
         this.SortBoxVideos(sceneInfoVO);
 
@@ -623,7 +628,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         //处理户型图数据
         //上传floorplan_user.json文件
         FileUtils.writeFile(localDataPath + "floorplan_user.json", floorJsonData);
-        fYunFileService.uploadFile(bucket, localDataPath + "floorplan_user.json", editUserPath + "floorplan_user.json");
+        fYunFileService.uploadFile(bucket, localDataPath + "floorplan_user.json", editUserPath + "floorplan.json");
 
         //写入数据库
         Byte floorPlanUser = null;
@@ -682,17 +687,21 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         String path = scenePlusExt.getDataSource();
 
         //户型图上传
-        String  userEditPath = UploadFilePath.USER_EDIT_PATH + "floor-cad-%s.%s";
-        String floorCadPath = path + "/results/floorplan_cad";
-        List<String> floorCadList = FileUtils.getFileList(floorCadPath);
-        if(CollUtil.isNotEmpty(floorCadList)){
-            floorCadList.stream().forEach(str->{
-                String substring = str.substring(str.lastIndexOf(File.separator) + 1);
-                String[] arr = substring.split("floor");
-                String[] arr2 = arr[1].split("\\.");
-                fYunFileService.uploadFile(bucket, str, String.format(userEditPath, num, arr2[0], arr2[1]));
-            });
-        }
+        String ossResultPath = String.format(UploadFilePath.scene_result_data_path, num);
+        String floorplanCadPath = ossResultPath + "floorplan_cad/";
+        fYunFileService.copyFileBetweenBucket(bucket, floorplanCadPath, bucket, String.format(UploadFilePath.USER_EDIT_PATH, num));
+
+//        String  userEditPath = UploadFilePath.USER_EDIT_PATH + "floor-cad-%s.%s";
+//        String floorCadPath = path + "/results/floorplan_cad";
+//        List<String> floorCadList = FileUtils.getFileList(floorCadPath);
+//        if(CollUtil.isNotEmpty(floorCadList)){
+//            floorCadList.stream().forEach(str->{
+//                String substring = str.substring(str.lastIndexOf(File.separator) + 1);
+//                String[] arr = substring.split("floor");
+//                String[] arr2 = arr[1].split("\\.");
+//                fYunFileService.uploadFile(bucket, str, String.format(userEditPath, num, arr2[0], arr2[1]));
+//            });
+//        }
 
         //根据floorplan_cad.json生成houseType.json
 //        this.uploadHouseTypeJson(num, bucket);
@@ -733,6 +742,10 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         result.put("version", "2.1");
 
         String floorplanCadPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "floorplan_cad.json";
+        if(!fYunFileService.fileExist(bucket, floorplanCadPath)){
+            log.warn("生成houseType.json失败,原因:floorplan_cad.json文件不存在,num:{}", num);
+            return;
+        }
         String floorcadStr = fYunFileService.getFileContent(bucket, floorplanCadPath);
 
         JSONObject floorcadObj = JSON.parseObject(floorcadStr);
@@ -915,9 +928,11 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         String sceneJson = redisUtil.get(key);
         if(StrUtil.isNotEmpty(sceneJson)){
             SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
-            sceneJsonBean.setVersion(version);
+            if(Objects.nonNull(version)){
+                sceneJsonBean.setVersion(version);
+            }
             if(Objects.nonNull(imgVersion)){
-                sceneJsonBean.setImgVersion(imgVersion + 1);
+                sceneJsonBean.setImgVersion(imgVersion);
             }
             redisUtil.set(key, JSON.toJSONString(sceneJsonBean));
         }
@@ -927,9 +942,11 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         sceneJson= fYunFileService.getFileContent(bucket, sceneJsonPath);
         if(StrUtil.isNotEmpty(sceneJson)){
             SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
-            sceneJsonBean.setVersion(version);
+            if(Objects.nonNull(version)){
+                sceneJsonBean.setVersion(version);
+            }
             if(Objects.nonNull(imgVersion)){
-                sceneJsonBean.setImgVersion(imgVersion + 1);
+                sceneJsonBean.setImgVersion(imgVersion);
             }
             fYunFileService.uploadFile(bucket, JSON.toJSONString(sceneJsonBean).getBytes(StandardCharsets.UTF_8), sceneJsonPath);
         }
@@ -974,7 +991,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         String zipTargetFilePath = targetImagesPath + file.getOriginalFilename();
 
         //判断全景图缓存是否存在,如果不存在,从计算目录中拷贝到缓存目录
-        this.cachePanorama(path, num);
+//        this.cachePanorama(path, num);
 
         //先删除本地文件
         FileUtils.deleteDirectory(targetImagesPath);
@@ -1026,11 +1043,13 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         }
 
         //比对图片列表,不存在的要返回名称集合
-        String visionPath = path + "/results/vision.txt";
+        String ossVisionPath = String.format(UploadFilePath.IMG_VIEW_PATH, num) + "vision.txt";
+        String visionPath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, num) + "vision.txt";
+        fYunFileService.downloadFile(ossVisionPath, visionPath);
         List<String> panoramaImageList = SceneUtil.getPanoramaImageList(visionPath);
         List<String> notExistFileList = uploadFileList.stream().filter(filePath -> {
             filePath = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
-            if(panoramaImageList.contains(filePath)){
+            if(CollUtil.isEmpty(panoramaImageList) || panoramaImageList.contains(filePath)){
                 return false;
             }
             return true;
@@ -1062,8 +1081,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         CreateObjUtil.convertVisionmodeldataToTxt(target + File.separator + "extras" + File.separator + "vision.modeldata",
             target + File.separator + "extras" + File.separator + "vision.txt");
 
-        FileUtils.copyFile(path + File.separator + "data.json", target + File.separator+"data.json", true);
-        FileUtils.copyFile(path + File.separator + "project.json", target + File.separator+"project.json", true);
+        String ossResultPath = String.format(UploadFilePath.scene_result_data_path, num);
+        fYunFileService.downloadFile(bucket, ossResultPath + "data.json", target + File.separator+"data.json");
+        fYunFileService.downloadFile(bucket, ossResultPath + "project.json", target + File.separator+"project.json");
 
         //data.json增加extras为执行重建算法
         String data = FileUtils.readFile(target + File.separator+"data.json");
@@ -1097,10 +1117,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         if(new File(target + File.separator + "results").exists()){
             FileUtils.delAllFile(target + File.separator + "results");
         }
-//        if(FYunTypeEnum.AWS.code().equals(fyunType)){
-//            //亚马逊保持旧方式,超链接capture
-//            CreateObjUtil.createSoftConnection(path + File.separator + "capture", target + File.separator + "capture");
-//        }
+
         fYunFileService.downloadFile(ConstantFilePath.OSS_PREFIX + path.replace(ConstantFilePath.BUILD_MODEL_PATH, "") + "/data.fdage", target + File.separator + "capture/data.fdage");
 
         //如果部分成功,则需要返回成功数量和失败列表
@@ -1226,16 +1243,17 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
                 continue;
             }
         }
-        if(map.size()>0) {
-            fYunFileService.uploadMulFiles(bucket, map);
-        }
 
-        //拷贝修改后的全景图到缓存目录
-        String cachedImagesPath = String.format(ConstantFilePath.SCENE_CACHE_IMAGES, num);
+        //用户上传的全景图上传到ossresult目录
+        String ossCachesImagesPath = String.format(UploadFilePath.scene_result_data_path, num) + "caches/images/";
         uploadFileList.stream().forEach(srcPath->{
-            cn.hutool.core.io.FileUtil.copy(srcPath, srcPath.replace(targetImagesPath, cachedImagesPath), true);
+            map.put(srcPath, srcPath.replace(targetImagesPath, ossCachesImagesPath));
         });
 
+        if(map.size()>0) {
+            fYunFileService.uploadMulFiles(bucket, map);
+        }
+
         //更新数据库版本号
         ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
         SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
@@ -1272,32 +1290,37 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         String cacheImageFormat = "downloads/scene/%s/caches/images/";
 
         //判断全景图缓存是否存在,如果不存在,从计算目录中拷贝到缓存目录
-        this.cachePanorama(scenePlusExt.getDataSource(), num);
+//        this.cachePanorama(scenePlusExt.getDataSource(), num);
+
+        //根据vision.txt获取到有效的全景图名称
+        String ossVisionPath = String.format(UploadFilePath.IMG_VIEW_PATH, num) + "vision.txt";
+        String visionPath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, num) + "vision.txt";
+        fYunFileService.downloadFile(ossVisionPath, visionPath);
+        List<String> panoramaImageList = SceneUtil.getPanoramaImageList(visionPath);
+        if(CollUtil.isEmpty(panoramaImageList)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
+        }
 
         Map<String, Object> map = new HashMap<>();
 
         //标记是否是异步操作,默认是同步操作
         //如果入参文件名不为空,则是单个文件下载,不需要打包
+        String ossResultPath = String.format(UploadFilePath.scene_result_data_path, num) + "caches/images/";
         if(StrUtil.isNotEmpty(fileName)){
             //如果是单张图片,直接提供oss url
-            String localFilePath = localImagesPath + fileName;
-            String ossFilePath = imgCachePath + fileName;
-            if(!cn.hutool.core.io.FileUtil.exist(localFilePath)){
+//            if(!fYunFileService.fileExist(bucket, ossResultPath + fileName)){
+//                throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
+//            }
+            if(!panoramaImageList.contains(fileName)){
                 throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
             }
-            fYunFileService.uploadFile(bucket, localFilePath, ossFilePath);
-            String url = ossUrlPrefix + ossFilePath;
+            String url = ossUrlPrefix + ossResultPath + fileName;
             String downloadName = fileName;
             map.put("asyn", CommonStatus.NO.code());
             map.put("fileUrl", url + "?t=" + System.currentTimeMillis());
             map.put("fileName", downloadName);
             return ResultData.ok(map);
         }else{
-            if(!cn.hutool.core.io.FileUtil.exist(localImagesPath)
-                || cn.hutool.core.io.FileUtil.isDirEmpty(new File(localImagesPath))){
-                throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
-            }
-
             //清除旧的下载记录
             sceneAsynOperLogService.remove(
                 new LambdaQueryWrapper<SceneAsynOperLog>()
@@ -1317,6 +1340,18 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
                 sceneAsynOperLog.setVersion(sceneEditInfo.getImgVersion());
                 sceneAsynOperLogService.save(sceneAsynOperLog);
                 try {
+
+                    //下载到本地目录
+                    FileUtil.del(localImagesPath);
+                    fYunFileService.downloadFileByCommand(bucket, localImagesPath, ossResultPath);
+                    //移除非必须文件
+                    List<String> fileNames = FileUtil.listFileNames(localImagesPath);
+                    fileNames.stream().forEach(name->{
+                        if(!panoramaImageList.contains(name)){
+                            FileUtil.del(localImagesPath + name);
+                        }
+                    });
+
                     String downloadName = num + "_images.zip";
                     long start = Calendar.getInstance().getTimeInMillis();
                     //打包
@@ -1555,8 +1590,8 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
             fYunFileService.uploadFile(bucket, target + File.separator + "extras/video/" + videoName.replace("mp4", "flv"),videosViewPath + videoName.replace("mp4", "flv"));
 
             //覆盖原始视频资源
-            FileUtils.copyFile(target + File.separator + "extras/video/" + videoName,
-                path + File.separator + "caches/videos/" + videoName, true);
+//            FileUtils.copyFile(target + File.separator + "extras/video/" + videoName,
+//                path + File.separator + "caches/videos/" + videoName, true);
 
         }
         FileUtils.deleteDirectory(target + File.separator + "extras/video/");
@@ -1628,15 +1663,20 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
             if(new File(target + File.separator + "results").exists()){
                 FileUtils.delAllFile(target + File.separator + "results");
             }
+
             //创建文件夹,并link文件夹
             new File(target + File.separator + "caches").mkdirs();
-            CreateObjUtil.createSoftConnection(path + File.separator + "capture", target + File.separator + "capture");
+            fYunFileService.downloadFileByCommand(target + File.separator + "capture", SceneUtil.getHomePath(path));
+//            CreateObjUtil.createSoftConnection(path + File.separator + "capture", target + File.separator + "capture");
             if(new File(path + File.separator + "caches" + File.separator + "images").exists()){
                 CreateObjUtil.createSoftConnection(path + File.separator + "caches" + File.separator + "images", target + File.separator + "caches" + File.separator + "images");
             }
 
-            FileUtils.copyFile(path + File.separator + "data.json", target + File.separator+"data.json", true);
-            FileUtils.copyFile(path + File.separator + "project.json", target + File.separator+"project.json", true);
+            String ossResultPath = String.format(UploadFilePath.scene_result_data_path, num);
+            fYunFileService.downloadFile(bucket, ossResultPath + "data.json", target + File.separator+"data.json");
+            fYunFileService.downloadFile(bucket, ossResultPath + "project.json", target + File.separator+"project.json");
+//            FileUtils.copyFile(path + File.separator + "data.json", target + File.separator+"data.json", true);
+//            FileUtils.copyFile(path + File.separator + "project.json", target + File.separator+"project.json", true);
 
             //data.json增加extras为执行重建算法
             String project = FileUtils.readFile(target + File.separator+"project.json");
@@ -1908,7 +1948,6 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
         String bucket = scenePlusExt.getYunFileBucket();
 
-        String localDataPath = String.format(ConstantFilePath.DATABUFFER_FORMAT, num);
         String localImagesPath = String.format(ConstantFilePath.IMAGESBUFFER_FORMAT, num);
         String path = scenePlusExt.getDataSource();
         String target = localImagesPath + "panorama/" + sid;
@@ -1923,8 +1962,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         file.transferTo(targetFile);
 
         //调用算法切全景图
-        FileUtils.copyFile(path + File.separator + "data.json", target + File.separator+"data.json", true);
-        FileUtils.copyFile(path + File.separator + "project.json", target + File.separator+"project.json", true);
+        String ossResultPath = String.format(UploadFilePath.scene_result_data_path, num);
+        fYunFileService.downloadFile(bucket, ossResultPath + "data.json", target + File.separator+"data.json");
+        fYunFileService.downloadFile(bucket, ossResultPath + "project.json", target + File.separator+"project.json");
         JSONObject visionJson = new JSONObject();
         JSONArray visionArray = new JSONArray();
         visionJson.put("uuid", sid);
@@ -1933,9 +1973,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         visionArray.add(visionJson);
         JSONObject vision = new JSONObject();
         vision.put("sweepLocations", visionArray);
-        cn.hutool.core.io.FileUtil.writeString(vision.toString(),
-            target + "/extras" + File.separator + "vision.txt",
-            StandardCharsets.UTF_8);
+        cn.hutool.core.io.FileUtil.writeString(vision.toString(), target + "/extras" + File.separator + "vision.txt", StandardCharsets.UTF_8);
 
         //data.json增加extras为执行重建算法
         String type = "4k";
@@ -1963,8 +2001,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
             }
             dataJson.put("skybox_type", skyboxType);
 
-            cn.hutool.core.io.FileUtil.writeString(dataJson.toString(),
-                target + File.separator+"data.json", StandardCharsets.UTF_8);
+            cn.hutool.core.io.FileUtil.writeString(dataJson.toString(), target + File.separator+"data.json", StandardCharsets.UTF_8);
         }
 
         //创建文件夹软连接并且复制data.json和project.json
@@ -1979,10 +2016,6 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
             cn.hutool.core.io.FileUtil.del(resultPath);
         }
         //下载data.fdage
-//        if(FYunTypeEnum.AWS.code().equals(this.fyunType)){
-//            //亚马逊保持旧方式,超链接capture
-//            CreateObjUtil.createSoftConnection(path + File.separator + "capture", capturePath);
-//        }
         fYunFileService.downloadFile(ConstantFilePath.OSS_PREFIX + path.replace(ConstantFilePath.BUILD_MODEL_PATH, "") + "/data.fdage", capturePath + "/data.fdage");
         CreateObjUtil.build3dModel(target , "1");
 
@@ -2765,6 +2798,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         sceneEditInfoExt.setFilters(filters);
         sceneEditInfoExtService.updateById(sceneEditInfoExt);
 
+        //更新版本号
+        this.upgradeVersionById(sceneEditInfoExt.getEditInfoId());
+
         return ResultData.ok();
 
     }

+ 21 - 0
src/main/java/com/fdkankan/scene/service/impl/SceneEditServiceImpl.java

@@ -11,6 +11,7 @@ import com.fdkankan.common.constant.CommonStatus;
 import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.model.constants.UploadFilePath;
 import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.scene.httpclient.MyClient;
 import com.fdkankan.web.response.ResultData;
 import com.fdkankan.common.util.DateExtUtil;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
@@ -67,6 +68,12 @@ import org.springframework.util.ObjectUtils;
 @RefreshScope
 public class SceneEditServiceImpl implements ISceneEditService {
 
+    @Value("${4dkk.manageService.basePath}")
+    private String manageServiceUrl;
+
+    @Value("${4dkk.manageService.api.getServiceUpTip}")
+    private String getServiceUpTipApi;
+
     @Autowired
     ISceneProService sceneProService;
     @Autowired
@@ -97,6 +104,9 @@ public class SceneEditServiceImpl implements ISceneEditService {
     @Value("${scene.expired.month:#{null}}")
     private Integer expiredMonth;
 
+    @Autowired
+    private MyClient myClient;
+
     @Override
     public SceneAuthVO getAuth(String num, SSOUser ssoUser){
 
@@ -206,4 +216,15 @@ public class SceneEditServiceImpl implements ISceneEditService {
         return ResultData.ok();
     }
 
+    @Override
+    public ResultData getServiceUpTip() {
+        try {
+            String url = this.manageServiceUrl.concat(this.getServiceUpTipApi);
+            String params = "type=" + 0;
+            ResultData resultData = myClient.get(url, params);
+            return ResultData.ok(resultData.getData());
+        }catch (Exception e){
+            return ResultData.ok();
+        }
+    }
 }

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

@@ -0,0 +1,181 @@
+package com.fdkankan.scene.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.UUID;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.model.constants.ConstantFilePath;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import com.fdkankan.scene.entity.SceneMarkShape;
+import com.fdkankan.scene.mapper.MarkShapeMapper;
+import com.fdkankan.scene.service.ISceneMarkShapeService;
+import com.fdkankan.scene.util.ConverxyUtil;
+import com.fdkankan.scene.vo.SceneMarkShapeParamVO;
+import com.fdkankan.scene.vo.SceneMarkShapeReDetectParamVO;
+import com.fdkankan.web.response.ResultData;
+import lombok.extern.slf4j.Slf4j;
+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.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * Created by Xiewj on 2021/11/23 0026 10:14
+ */
+@Slf4j
+@Service
+public class SceneMarkShapeServiceImpl extends ServiceImpl<MarkShapeMapper, SceneMarkShape> implements ISceneMarkShapeService {
+    @Autowired
+    private RabbitMqProducer rabbitMqProducer;
+    @Value("${queue.scene.yolov5-train-queue}")
+    private String yolov5TrainQueue;
+    @Value("${main.url}")
+    private String mainUrl;
+
+    @Override
+    public void editTrainStatus(SceneMarkShapeParamVO param) {
+        SceneMarkShape byNumAndImagePath = findByNumAndImagePath(param.getNum(), param.getImagePath());
+        if (ObjectUtil.isNotNull(byNumAndImagePath)){
+            byNumAndImagePath.setReTrain(0);
+            byNumAndImagePath.setToTrain(1);
+            updateById(byNumAndImagePath);
+        }
+    }
+
+    @Override
+    public List<SceneMarkShape> findByReTrainStatus(Integer reTrain){
+        LambdaQueryWrapper<SceneMarkShape> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(SceneMarkShape::getReTrain,reTrain);
+        return list(wrapper);
+    }
+
+    @Override
+    public List<SceneMarkShape> findByToTrainStatus(Integer toTrain) {
+        QueryWrapper queryWrapper = new QueryWrapper();
+        queryWrapper.select("DISTINCT num")
+                .eq("to_train",toTrain) ;
+        return getBaseMapper().selectList(queryWrapper);
+    }
+
+    @Override
+    public void trainScene(SceneMarkShapeReDetectParamVO param) {
+        //查询需要重新训练的图片
+        List<SceneMarkShape> reDetectStatuList = findByReTrainStatus(1);
+        for (SceneMarkShape shape : reDetectStatuList) {
+            SceneMarkShapeReDetectParamVO paramVO=new SceneMarkShapeReDetectParamVO();
+            paramVO.setWebSite(mainUrl);
+            if (StrUtil.isNotEmpty(param.getSaveDir())){
+                paramVO.setSaveDir(param.getSaveDir());
+            }
+            paramVO.setNum(shape.getNum());
+            paramVO.setImagePath(shape.getImagePath());
+            paramVO.setDetectType(1);
+            rabbitMqProducer.sendByWorkQueue(yolov5TrainQueue,paramVO);
+        }
+        //查询需要进入训练的场景
+        List<SceneMarkShape> byToDetectStatus = findByToTrainStatus(0);
+        for (SceneMarkShape shape : byToDetectStatus) {
+            SceneMarkShapeReDetectParamVO paramVO=new SceneMarkShapeReDetectParamVO();
+            paramVO.setWebSite(mainUrl);
+            if (StrUtil.isNotEmpty(param.getSaveDir())){
+                paramVO.setSaveDir(param.getSaveDir());
+            }
+            paramVO.setNum(shape.getNum());
+            paramVO.setDetectType(2);
+            rabbitMqProducer.sendByWorkQueue(yolov5TrainQueue,paramVO);
+        }
+    }
+
+    @Override
+    public ResultData editLabelByFile(String num, String imgPath, MultipartFile file) throws IOException {
+
+        SceneMarkShape shape = findByNumAndImagePath(num, imgPath);
+        if (ObjectUtil.isNotNull(shape)){
+            String uuid = UUID.randomUUID().toString();
+            String fileName = file.getOriginalFilename();
+            String extName = FileUtil.extName(fileName);
+            String tempFileName = uuid + "." + extName;
+            String srcPath = ConstantFilePath.SCENE_V4_PATH + num + "/markShapes/" + tempFileName;
+            File tempFile = new File(srcPath);
+            if(!tempFile.getParentFile().exists()){
+                tempFile.getParentFile().mkdirs();
+            }
+            file.transferTo(tempFile);
+
+            List<String> s = FileUtil.readUtf8Lines(tempFile);
+            List<JSONObject> shapeJsons=new ArrayList<>();
+            //转换labelimg标注处理的结果
+            log.info("转换labelimg标注处理的结果开始");
+            for (String s1 : s) {
+                int[] ints = ConverxyUtil.centerWh2xyxy(s1, 4096,2048);
+                String[] s2 = s1.split(" ");
+                JSONObject shapeJson=new JSONObject();
+                shapeJson.put("bbox",ints);
+                shapeJson.put("color",ConverxyUtil.getColor(s2[0]));
+                shapeJson.put("label",s1);
+                shapeJson.put("category",ConverxyUtil.getLabelVal(s2[0]));
+                shapeJson.put("score",0);
+                shapeJsons.add(shapeJson);
+            }
+            log.info("转换labelimg标注处理的结果结束,{}",shapeJsons);
+            shape.setShapes(shapeJsons);
+            shape.setReTrain(1);
+            shape.setUpdateTime(new Date());
+            updateById(shape);
+            return ResultData.ok(shape);
+        }else {
+            return ResultData.error(ErrorCode.NOT_RECORD);
+        }
+    }
+
+    @Override
+    public SceneMarkShape findByNumAndImagePath(String num, String imagePath) {
+        LambdaQueryWrapper<SceneMarkShape> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(SceneMarkShape::getNum,num);
+        wrapper.eq(SceneMarkShape::getImagePath,imagePath);
+        return getOne(wrapper);
+    }
+
+    @Override
+    public void saveFileToDB(MultipartFile file, String num) throws IOException {
+        String uuid = UUID.randomUUID().toString();
+        String fileName = file.getOriginalFilename();
+        String extName = cn.hutool.core.io.FileUtil.extName(fileName);
+        String tempFileName = uuid + "." + extName;
+        String srcPath = ConstantFilePath.SCENE_V4_PATH + num + "/markShapes/" + tempFileName;
+        File tempFile = new File(srcPath);
+        if(!tempFile.getParentFile().exists()){
+            tempFile.getParentFile().mkdirs();
+        }
+        file.transferTo(tempFile);
+        String s = FileUtil.readUtf8String(tempFile);
+        JSONObject jsonObject = JSONObject.parseObject(s);
+        tempFile.delete();
+        SceneMarkShape sceneMarkShape= JSON.toJavaObject(jsonObject,SceneMarkShape.class);
+        sceneMarkShape.setNum(num);
+        SceneMarkShape shape = findByNumAndImagePath(sceneMarkShape.getNum(), sceneMarkShape.getImagePath());
+        if (ObjectUtil.isNotNull(shape)){
+            log.info("shape-替换id修改---{}",sceneMarkShape);
+            sceneMarkShape.setId(shape.getId());
+            updateById(sceneMarkShape);
+        }else {
+            log.info("新增-替换id修改---{}",sceneMarkShape);
+            log.info("MarkShapeMapper---{}",sceneMarkShape);
+            save(sceneMarkShape);
+        }
+    }
+}

+ 38 - 99
src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java

@@ -664,14 +664,11 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
             editInfo.setScenePlusId(scenePlus.getId());
             sceneEditInfoService.save(editInfo);
         }else{
-            sceneEditInfoService.upgradeVersionById(editInfo.getId());
+            sceneEditInfoService.upgradeVersionAndImgVersionById(editInfo.getId());
             //更新scenejson缓存和oss文件版本号
-            sceneEditInfoService.upgradeSceneJsonVersion(param.getNum(), editInfo.getVersion() + 1, null, bucket);
+            sceneEditInfoService.upgradeSceneJsonVersion(param.getNum(), editInfo.getVersion() + 1, editInfo.getImgVersion() + 1, bucket);
         }
 
-        //更新scene.json版本号
-//        sceneEditInfoService.upgradeVersionToSceneJson(param.getNum());
-
         return ResultData.ok();
     }
 
@@ -723,7 +720,8 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
                     .set(SceneEditInfo::getIsUploadObj, CommonStatus.YES.code())
                     .eq(SceneEditInfo::getId, sceneEditInfo.getId()));
 
-            sceneEditInfoService.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1, bucket);        }
+            sceneEditInfoService.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1, bucket);
+        }
 
         return ResultData.ok();
     }
@@ -758,7 +756,7 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         }
 
         //算法计算完后,生成压缩文件,上传到oss
-        this.uploadFileofterRebuildPanoram(path, num, bucket);
+        this.uploadFileofterRebuildPanoram(path, filePath, num, bucket);
     }
 
     /**
@@ -859,7 +857,7 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
 
     }
 
-    private void uploadFileofterRebuildPanoram(String path, String sceneNum, String bucket) throws Exception {
+    private void uploadFileofterRebuildPanoram(String path, String filePath, String sceneNum, String bucket) throws Exception {
         //因为共享目录有延迟,这里循环检测算法是否计算完毕3次,每次隔五秒
         String uploadJsonPath = path + File.separator + "results" +File.separator+"upload.json";
         boolean exist = ComputerUtil.checkComputeCompleted(uploadJsonPath, maxCheckTimes, waitTime);
@@ -905,6 +903,13 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
 //        map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k.dam.lzma", imgViewPath +ConstantFileName.modelUUID+"_50k.dam.lzma");
         map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k.dam", imgViewPath+ConstantFileName.modelUUID+"_50k.dam");
 
+        String ossMeshPath = String.format(UploadFilePath.DATA_VIEW_PATH, sceneNum) + "mesh";
+        //删除oss中的mesh
+        fYunFileService.deleteFolder(bucket, ossMeshPath);
+        //上传obj相关文件
+        List<String> fileNames = FileUtil.listFileNames(filePath);
+        fileNames.stream().forEach(name->map.put(filePath + name, ossMeshPath + File.separator + name));
+
         fYunFileService.uploadMulFiles(bucket, map);
     }
 
@@ -1033,7 +1038,7 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
             return this.downloadModel43dtiles(num, bucket, scenePlusExt, sceneEditInfo);
         }
 
-        return this.downloadModel4Dam(num, bucket, scenePlusExt, sceneEditInfo);
+        return this.downloadModel4Dam(num, bucket);
     }
 
     @Override
@@ -1068,106 +1073,38 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
     }
 
 
-    private ResultData downloadModel4Dam(String num, String bucket, ScenePlusExt scenePlusExt, SceneEditInfo sceneEditInfo){
+    private ResultData downloadModel4Dam(String num, String bucket){
         String localImagePath = String.format(ConstantFilePath.IMAGESBUFFER_FORMAT, num);
         if(!new File(localImagePath).exists()){
             new File(localImagePath).mkdirs();
         }
 
-
-        String newData =  scenePlusExt.getDataSource() + "_obj2txt/extras";
-        String newResultData = scenePlusExt.getDataSource() + "_obj2txt/results/upload.json";
         String zipName = num + "_extras.zip";
         String zipPath = localImagePath + zipName;
-        //如果用户上传过模型,就打包上传到oss,直接返回
-        if(CommonStatus.YES.code().equals(sceneEditInfo.getIsUploadObj())
-                && new File(newData).exists()
-                && new File(newResultData).exists()){
-            //打包
-            ZipUtil.zip(newData, zipPath);
-            //上传压缩包
-            fYunFileService.uploadFile(bucket, zipPath, "downloads/extras/" + zipName);
-            String url = ossUrlPrefix + "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
-            return ResultData.ok(url);
-        }
-
 
-        String buildType = scenePlusExt.getBuildType();
-        if("V3".equals(buildType)){
-            String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, num);
-            //V3版本去oss下载2048模型
-            String meshPath =  String.format(ConstantFilePath.DATABUFFER_FORMAT, num) + "mesh";
-            FileUtils.deleteDirectory(meshPath);
-            fYunFileService.downloadFileByCommand(bucket, meshPath, dataViewPath + "mesh");
-            log.info("meshPath="+meshPath);
-            if(!new File(meshPath).exists()){
-                throw new BusinessException(ErrorCode.FAILURE_CODE_7006);
-            }
-            log.info(new File(meshPath).listFiles().toString());
-            if(new File(meshPath).listFiles().length > 0){
-                for(File file : new File(meshPath).listFiles()){
-                    if(file.isDirectory()){
-                        for (File item : file.listFiles()) {
-                            if(item.getName().endsWith(".obj") && !"output.house.obj".equals(item.getName()) &&
-                                    !"mesh.obj".equals(item.getName())){
-                                item.delete();
-                            }
-                            if(item.getName().endsWith(".mtl") && !"output.house.mtl".equals(item.getName()) &&
-                                    !"mesh.mtl".equals(item.getName())){
-                                item.delete();
-                            }
-                        }
-                        continue;
-                    }
-                    if(file.getName().endsWith(".obj") && !"output.house.obj".equals(file.getName()) &&
-                            !"mesh.obj".equals(file.getName())){
-                        file.delete();
+        String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, num);
+        //V3版本去oss下载2048模型
+        String meshPath =  String.format(ConstantFilePath.DATABUFFER_FORMAT, num) + "mesh";
+        FileUtils.deleteDirectory(meshPath);
+        fYunFileService.downloadFileByCommand(bucket, meshPath, dataViewPath + "mesh");
+        log.info("meshPath="+meshPath);
+        if(!new File(meshPath).exists() || new File(meshPath).listFiles().length < 1){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_7006);
+        }
+        for(File file : new File(meshPath).listFiles()){
+            if(file.isDirectory()){
+                for (File item : file.listFiles()) {
+                    if(item.getName().endsWith(".obj") && !"output.house.obj".equals(item.getName()) &&
+                            !"mesh.obj".equals(item.getName())){
+                        item.delete();
                     }
-                    if(file.getName().endsWith(".mtl") && !"output.house.mtl".equals(file.getName()) &&
-                            !"mesh.mtl".equals(file.getName())){
-                        file.delete();
+                    if(item.getName().endsWith(".mtl") && !"output.house.mtl".equals(item.getName()) &&
+                            !"mesh.mtl".equals(item.getName())){
+                        item.delete();
                     }
                 }
-                //打包
-                ZipUtil.zip(meshPath, zipPath);
-                //上传压缩包
-                fYunFileService.uploadFile(bucket, zipPath, "downloads/extras/" + zipName);
-                String url = ossUrlPrefix + "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
-//                FileUtil.del(zipPath);
-                return ResultData.ok(url);
-            }
-        }
-
-        //V2版本在本地获取模型资源
-        //修改过的资源
-        String editData =  scenePlusExt.getDataSource() + "_edit/caches/tex";
-        String results = scenePlusExt.getDataSource() + "_edit/results";
-        if (new File(editData).exists() && new File(results).exists()){
-            for(File file : new File(editData).listFiles()){
-                if(file.getName().endsWith(".obj") && !"output.house.obj".equals(file.getName()) &&
-                        !"mesh.obj".equals(file.getName())){
-                    file.delete();
-                }
-                if(file.getName().endsWith(".mtl") && !"output.house.mtl".equals(file.getName()) &&
-                        !"mesh.mtl".equals(file.getName())){
-                    file.delete();
-                }
+                continue;
             }
-
-            ZipUtil.zip(editData, zipPath);
-            //上传压缩包
-            fYunFileService.uploadFile(bucket, zipPath, "downloads/extras/" + zipName);
-            String url = ossUrlPrefix + "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
-            return ResultData.ok(url);
-        }
-
-        //没上传过返回源资源
-        String dataPath = scenePlusExt.getDataSource() + "/caches/tex";
-        File dataFile = new File(dataPath);
-        if(!dataFile.exists()){
-            throw new BusinessException(ErrorCode.FAILURE_CODE_3018);
-        }
-        for(File file : dataFile.listFiles()){
             if(file.getName().endsWith(".obj") && !"output.house.obj".equals(file.getName()) &&
                     !"mesh.obj".equals(file.getName())){
                 file.delete();
@@ -1177,11 +1114,13 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
                 file.delete();
             }
         }
-
-        ZipUtil.zip(dataPath, zipPath);
+        //打包
+        ZipUtil.zip(meshPath, zipPath);
         //上传压缩包
         fYunFileService.uploadFile(bucket, zipPath, "downloads/extras/" + zipName);
         String url = ossUrlPrefix + "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
+        FileUtil.del(zipPath);
         return ResultData.ok(url);
     }
+
 }

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 169 - 1473
src/main/java/com/fdkankan/scene/service/impl/SceneServiceImpl.java


+ 121 - 0
src/main/java/com/fdkankan/scene/util/ConverxyUtil.java

@@ -0,0 +1,121 @@
+package com.fdkankan.scene.util;
+
+import cn.hutool.core.io.FileUtil;
+import com.alibaba.fastjson.JSONObject;
+
+import java.io.File;
+import java.math.BigDecimal;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Xiewj
+ * @date 2023/4/11
+ */
+public class ConverxyUtil {
+   static Map<String,String> label=new HashMap<>();
+   static Map<String,int[]> color=new HashMap<>();
+
+   static void init() {
+      label.put("0","cabinet");
+      label.put("1","air");
+      label.put("2","battery");
+
+      color.put("0",new int[]{56,56,255});
+      color.put("1",new int[]{151,157,255});
+      color.put("2",new int[]{31,112,255});
+   }
+   public static String getLabelVal(String key) {
+      if (label.size()==0){
+         init();
+      }
+      //标签类型初始化
+     return label.get(key);
+   }
+   public static int[] getColor(String key) {
+      if (color.size()==0){
+         init();
+      }
+      //标签类型初始化
+      return color.get(key);
+   }
+      // 将中心宽高格式转换为左上角点和右下角点格式
+   /**
+    * 将xywh格式的目标框转换为xyxy格式
+    * @param xywh xywh格式的目标框,格式为"x,y,w,h"
+    * @return xyxy格式的目标框,格式为"x1,y1,x2,y2"
+    */
+   public static int[] centerWh2xyxy(String xywh,int w1,int h1){
+      String[] values = xywh.split(" ");
+      if (values.length<4){
+         return null;
+      }
+      float x = Float.parseFloat(values[1]);
+      float y = Float.parseFloat(values[2]);
+      float w = Float.parseFloat(values[3]);
+      float h = Float.parseFloat(values[4]);
+      int[] xyxy = new int[4];
+      xyxy[0] = (int) ((x - w / 2) * w1); // x1
+      xyxy[1] = (int) ((y - h / 2)* h1); // y1
+      xyxy[2] = (int) ((x + w / 2)* w1); // x2
+      xyxy[3] = (int) ((y+ h / 2)* h1); // y2
+      return xyxy;
+   }
+
+   // 将左上角点和右下角点格式转换为中心宽高格式
+   public static double[] xyxy2centerWh(int x1, int y1, int x2, int y2,int w1,int h1){
+
+      double[] centerWh = new double[4];
+      BigDecimal dx1=BigDecimal.valueOf(x1);
+      BigDecimal  dy1=BigDecimal.valueOf(y1);
+      BigDecimal  dx2=BigDecimal.valueOf(x2);
+      BigDecimal dy2= BigDecimal.valueOf(y2);
+      BigDecimal  dw1=BigDecimal.valueOf(w1);
+      BigDecimal  dh1=BigDecimal.valueOf(h1);
+
+
+      centerWh[0] =((dx1.add(dx2)).divide(BigDecimal.valueOf(2))).divide(dw1).doubleValue(); // centerX
+      centerWh[1] = ((dy1.add(dy2)).divide(BigDecimal.valueOf(2))).divide(dh1).doubleValue(); // centerX
+      centerWh[2] = dx2.subtract(dx1).divide(dw1).doubleValue(); // width
+      centerWh[3] =  dy2.subtract(dy1).divide(dh1).doubleValue(); // width
+
+      return centerWh;
+   }
+   public static void main(String[] args) {
+      // 中心宽高格式转换为左上角点和右下角点格式
+//      int[] xyxy = ConverxyUtil.centerWh2xyxy("0.215149 0.557373 0.067749 0.329590",8192,4096);
+//
+//      System.out.println("x1=" + xyxy[0] + ", y1=" + xyxy[1] + ", x2=" + xyxy[2] + ", y2=" + xyxy[3]);
+//
+//      // 左上角点和右下角点格式转换为中心宽高格式
+//      double[] centerWh = ConverxyUtil.xyxy2centerWh(xyxy[0], xyxy[1], xyxy[2], xyxy[3],8192,4096);
+//      System.out.println("centerX=" + centerWh[0] + ", centerY=" + centerWh[1] + ", width=" + centerWh[2] + ", height=" + centerWh[3]);
+//      int[] xyxy1 = ConverxyUtil.centerWh2xyxy("0.21514892578125 0.5572509765625 0.0677490234375 0.329833984375",8192,4096);
+//      System.out.println("x1=" + xyxy1[0] + ", y1=" + xyxy1[1] + ", x2=" + xyxy1[2] + ", y2=" + xyxy1[3]);
+//
+////      Object labelVal = ConverxyUtil.getLabelVal("1");
+////      System.out.println(labelVal);
+
+      File tempFile=new File("C:\\Users\\4DAGE\\Downloads\\KK-UR4UGMSHEK3\\images\\0.txt");
+      List<String> s = FileUtil.readUtf8Lines(tempFile);
+
+
+      List<JSONObject> shapeJsons=new ArrayList<>();
+      //转换labelimg标注处理的结果
+      for (String s1 : s) {
+         int[] ints = ConverxyUtil.centerWh2xyxy(s1, 4096,2048);
+         String[] s2 = s1.split(" ");
+         JSONObject shapeJson=new JSONObject();
+         shapeJson.put("bbox",ints);
+         shapeJson.put("color",ConverxyUtil.getColor(s2[0]));
+         shapeJson.put("label",s1);
+         shapeJson.put("category",ConverxyUtil.getLabelVal(s2[0]));
+         shapeJson.put("score",0);
+         shapeJsons.add(shapeJson);
+      }
+      System.out.println(shapeJsons);
+   }
+}

+ 98 - 0
src/main/java/com/fdkankan/scene/util/OssBodySegmentUtil.java

@@ -0,0 +1,98 @@
+package com.fdkankan.scene.util;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.http.HttpUtil;
+import com.aliyun.imageseg20191230.models.SegmentBodyResponse;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.tea.TeaException;
+import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.scene.httpclient.MyClient;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.File;
+
+@Slf4j
+@Component
+@RefreshScope
+public class OssBodySegmentUtil {
+
+    @Value("${oss.bodySegment.point:oss-cn-shanghai.aliyuncs.com}")
+    private String endPoint;
+
+    @Value("${oss.bodySegment.imagesegPoint:imageseg.cn-shanghai.aliyuncs.com}")
+    private String imagesegEndPoint;
+
+    @Value("${fyun.key}")
+    private String accessKeyId;
+
+    @Value("${fyun.secret}")
+    private String accessKeySecret;
+
+    @Value("${oss.bodySegment.bucket:4dkankan-huadong}")
+    private String bucket;
+
+    @Resource
+    private MyClient myClient;
+
+    public void uploadOss(String filePath, String key){
+        OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);
+        try {
+            File file = new File(filePath);
+            if (!file.exists()) {
+                log.error("要上传的文件不存在:" + filePath);
+                return;
+            }
+            ossClient.putObject(bucket, key, new File(filePath));
+        } catch (Exception e) {
+            log.error(e.toString() + filePath);
+        } finally {
+            ossClient.shutdown();
+        }
+    }
+
+    public void extracted(String imageUrl, String dir, String fileName) throws Exception {
+        try {
+            com.aliyun.imageseg20191230.Client client = this.createClient();
+            com.aliyun.imageseg20191230.models.SegmentBodyRequest segmentBodyRequest =
+                    new com.aliyun.imageseg20191230.models.SegmentBodyRequest().setImageURL(imageUrl);
+            com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
+            // 复制代码运行请自行打印 API 的返回值
+            SegmentBodyResponse segmentBodyResponse = client.segmentBodyWithOptions(segmentBodyRequest, runtime);
+            String imageURL = segmentBodyResponse.getBody().getData().getImageURL();
+            log.info("人体抠图imageURL:{}", imageURL);
+            myClient.downloadFile(imageURL, dir, fileName);
+        }catch (Exception e){
+            log.error("人体抠图失败,imageUrl:" + imageUrl, e);
+            myClient.downloadFile(imageUrl, dir, fileName);
+        }
+
+    }
+
+    public static void main(String[] args) {
+        FileUtils.downLoadFromUrl("http://vibktprfx-prod-prod-damo-eas-cn-shanghai.oss-cn-shanghai.aliyuncs.com/segment-body/2023-02-24/5d44fe44-308c-44c3-8e1d-2d4cbe601f86/image.png?Expires=1677208715&OSSAccessKeyId=LTAI4FoLmvQ9urWXgSRpDvh1&Signature=4ZyzaOz6W1nBD9s3KQuFN10c%2BPw%3D",
+                "1.png","D:\\test");
+    }
+
+    /**
+     * 使用AK&SK初始化账号Client
+     * @return Client
+     * @throws Exception
+     */
+    public com.aliyun.imageseg20191230.Client createClient() throws Exception {
+        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
+                // 必填,您的 AccessKey ID
+                .setAccessKeyId(accessKeyId)
+                // 必填,您的 AccessKey Secret
+                .setAccessKeySecret(accessKeySecret);
+        // 访问的域名
+        config.endpoint = this.imagesegEndPoint;
+        return new com.aliyun.imageseg20191230.Client(config);
+    }
+
+}

+ 97 - 0
src/main/java/com/fdkankan/scene/util/test.java

@@ -0,0 +1,97 @@
+package com.fdkankan.scene.util;
+// This file is auto-generated, don't edit it. Thanks.
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.thread.ThreadUtil;
+import cn.hutool.http.HttpUtil;
+import com.aliyun.imageseg20191230.Client;
+import com.aliyun.imageseg20191230.models.SegmentBodyResponse;
+import com.aliyun.tea.TeaException;
+import com.aliyun.teautil.Common;
+
+import java.io.File;
+
+public class test {
+
+    /**
+     * 使用AK&SK初始化账号Client
+     *
+     * @param accessKeyId
+     * @param accessKeySecret
+     * @return Client
+     * @throws Exception
+     */
+    public static com.aliyun.imageseg20191230.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
+        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
+                // 必填,您的 AccessKey ID
+                .setAccessKeyId(accessKeyId)
+                // 必填,您的 AccessKey Secret
+                .setAccessKeySecret(accessKeySecret);
+        // 访问的域名
+        config.endpoint = "imageseg.cn-shanghai.aliyuncs.com";
+        return new com.aliyun.imageseg20191230.Client(config);
+    }
+
+    public static void main(String[] args_) throws Exception {
+
+        java.util.List<String> args = java.util.Arrays.asList(args_);
+        // 工程代码泄露可能会导致AccessKey泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378657.html
+        com.aliyun.imageseg20191230.Client client = test.createClient("LTAIUrvuHqj8pvry", "JLOVl0k8Ke0aaM8nLMMiUAZ3EiiqI4");
+        ThreadUtil.execAsync(() -> {
+            extracted(client, "https://4dkankan-huadong.oss-cn-shanghai.aliyuncs.com/segment/1.jpg", "1");
+
+        });
+        ThreadUtil.execAsync(() -> {
+            extracted(client, "https://4dkankan-huadong.oss-cn-shanghai.aliyuncs.com/segment/2.jpg", "2");
+
+        });
+        ThreadUtil.sleep(1000);
+        ThreadUtil.execAsync(() -> {
+            extracted(client, "https://4dkankan-huadong.oss-cn-shanghai.aliyuncs.com/segment/3.jpg", "3");
+
+        });
+        ThreadUtil.execAsync(() -> {
+            extracted(client, "https://4dkankan-huadong.oss-cn-shanghai.aliyuncs.com/segment/4.webp", "4");
+
+        });
+//      ThreadUtil.sleep(2000);
+//      ThreadUtil.sleep(3000);
+
+//      ThreadUtil.sleep(4000);
+
+
+    }
+
+    private static void extracted(Client client, String imageUrl, String imgName) {
+
+        com.aliyun.imageseg20191230.models.SegmentBodyRequest segmentBodyRequest = new com.aliyun.imageseg20191230.models.SegmentBodyRequest()
+                .setImageURL(imageUrl);
+        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
+        try {
+            // 复制代码运行请自行打印 API 的返回值
+            long stime = System.currentTimeMillis();
+            System.out.println("开始-----------" + imgName);
+            SegmentBodyResponse segmentBodyResponse = client.segmentBodyWithOptions(segmentBodyRequest, runtime);
+            String imageURL = segmentBodyResponse.getBody().getData().getImageURL();
+            long etime = System.currentTimeMillis();
+            System.out.printf("执行时长:%d 毫秒.----%s", (etime - stime), imgName);
+            File file = FileUtil.file("C:\\Users\\4DAGE\\Downloads\\抠像测试\\抠像测试\\1\\" + imgName + ".png");
+            if (FileUtil.exist(file)) {
+                FileUtil.del(file);
+            }
+            System.out.println(imageURL);
+            ThreadUtil.sleep(1000);
+            HttpUtil.downloadFile(imageURL, FileUtil.file(file));
+        } catch (TeaException error) {
+            // 如有需要,请打印 error
+            String s = Common.assertAsString(error.message);
+            System.out.println("错误1" + s);
+        } catch (Exception _error) {
+            TeaException error = new TeaException(_error.getMessage(), _error);
+            // 如有需要,请打印 error
+            String s = Common.assertAsString(error.message);
+            System.out.println("错误2" + s);
+
+        }
+    }
+}

+ 24 - 0
src/main/java/com/fdkankan/scene/vo/SceneEditControlsParamVO.java

@@ -1,5 +1,6 @@
 package com.fdkankan.scene.vo;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -76,5 +77,28 @@ public class SceneEditControlsParamVO implements Serializable {
      */
     private Integer showRule;
 
+    /**
+     * 是否展示标尺(0-不需要,1-需要)
+     */
+    private Integer showScale;
+
+    /**
+     * 是否展示分享场景(0-不需要,1-需要)
+     */
+    private Integer showShare;
+
+    /**
+     * 是否展示分享热点(0-不需要,1-需要)
+     */
+    private Integer showTagshare;
+
+    /**
+     * 是否展示合照开关(0-不需要,1-需要)
+     */
+    private Integer showCapture;
+
+
+
+
 
 }

+ 21 - 0
src/main/java/com/fdkankan/scene/vo/SceneEditControlsVO.java

@@ -1,5 +1,6 @@
 package com.fdkankan.scene.vo;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -66,5 +67,25 @@ public class SceneEditControlsVO implements Serializable {
      */
     private Integer showRule;
 
+    /**
+     * 是否展示标尺(0-不需要,1-需要)
+     */
+    private Integer showScale;
+
+    /**
+     * 是否展示分享场景(0-不需要,1-需要)
+     */
+    private Integer showShare;
+
+    /**
+     * 是否展示分享热点(0-不需要,1-需要)
+     */
+    private Integer showTagshare;
+
+    /**
+     * 是否展示合照开关(0-不需要,1-需要)
+     */
+    private Integer showCapture;
+
 
 }

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

@@ -2,6 +2,7 @@ package com.fdkankan.scene.vo;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.annotation.TableField;
 import java.util.List;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
@@ -228,5 +229,10 @@ public class SceneInfoVO {
      */
     private Integer surveillances;
 
+    /**
+     * 场景容量 单位 MB
+     */
+    private Integer space;
+
 
 }

+ 39 - 0
src/main/java/com/fdkankan/scene/vo/SceneMarkShapeDetectParamVO.java

@@ -0,0 +1,39 @@
+package com.fdkankan.scene.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/1/19
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SceneMarkShapeDetectParamVO {
+
+    /**
+     * 场景码
+     */
+    @NotBlank(message = "场景码不能为空")
+    private String num;
+
+    /**
+     *  推送域名
+     */
+    private String webSite;
+
+    /**
+     *  保存路径。可以为空,不为空可以查看结果
+     */
+    private String saveDir="";
+}

+ 36 - 0
src/main/java/com/fdkankan/scene/vo/SceneMarkShapeParamVO.java

@@ -0,0 +1,36 @@
+package com.fdkankan.scene.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/1/19
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SceneMarkShapeParamVO {
+
+    /**
+     * 场景码
+     */
+    @NotBlank(message = "场景码不能为空")
+    private String num;
+
+    /**
+     * 图片名称路径
+     */
+    private String imagePath;
+
+
+}

+ 46 - 0
src/main/java/com/fdkankan/scene/vo/SceneMarkShapeReDetectParamVO.java

@@ -0,0 +1,46 @@
+package com.fdkankan.scene.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/1/19
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SceneMarkShapeReDetectParamVO {
+
+    /**
+     * 场景码
+     */
+    private String num;
+
+    /**
+     *  推送域名
+     */
+    private String webSite;
+    /**
+     *  图片名称
+     */
+    private String imagePath;
+
+    /**
+     *  保存路径。可以为空,不为空可以查看结果
+     */
+    private String saveDir="";
+
+    /**
+     *  1,场景的单张图片重新进入训练  2,整个场景的推理进入训练
+     */
+    private Integer detectType;
+
+}

+ 4 - 0
src/main/resources/bootstrap-prod-eur.yml

@@ -28,5 +28,9 @@ spring:
           - data-id: common-rabbitmq-config.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: forest-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
       discovery:
         namespace: ${spring.cloud.nacos.namespace}

+ 4 - 0
src/main/resources/bootstrap-prod.yml

@@ -28,6 +28,10 @@ spring:
           - data-id: common-rabbitmq-config.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: forest-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
       discovery:
         namespace: ${spring.cloud.nacos.namespace}
 

+ 4 - 0
src/main/resources/bootstrap-test-eur.yml

@@ -28,6 +28,10 @@ spring:
           - data-id: common-rabbitmq-config.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: forest-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
       discovery:
         namespace: ${spring.cloud.nacos.namespace}
 

+ 4 - 0
src/main/resources/bootstrap-test.yml

@@ -28,6 +28,10 @@ spring:
           - data-id: common-rabbitmq-config.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: forest-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
       discovery:
         namespace: ${spring.cloud.nacos.namespace}