Browse Source

Merge branch 'release-v4.14.0' into release

# Conflicts:
#	src/main/java/com/fdkankan/scene/entity/ScenePlusExt.java
dengsixing 4 months ago
parent
commit
5041808e5d
27 changed files with 741 additions and 55 deletions
  1. 1 0
      src/main/java/com/fdkankan/scene/bean/SceneJsonBean.java
  2. 51 0
      src/main/java/com/fdkankan/scene/controller/SceneEditAiController.java
  3. 24 2
      src/main/java/com/fdkankan/scene/controller/SceneEditController.java
  4. 74 0
      src/main/java/com/fdkankan/scene/dto/GeoPoint.java
  5. 12 0
      src/main/java/com/fdkankan/scene/entity/SceneEditControls.java
  6. 6 0
      src/main/java/com/fdkankan/scene/entity/SceneMarkShape.java
  7. 3 0
      src/main/java/com/fdkankan/scene/entity/ScenePlusExt.java
  8. 61 0
      src/main/java/com/fdkankan/scene/entity/SceneShapeEnum.java
  9. 17 0
      src/main/java/com/fdkankan/scene/mapper/SceneShapeEnumMapper.java
  10. 8 0
      src/main/java/com/fdkankan/scene/service/ICommonService.java
  11. 4 0
      src/main/java/com/fdkankan/scene/service/ISceneMarkShapeService.java
  12. 6 10
      src/main/java/com/fdkankan/scene/service/ISceneProService.java
  13. 2 1
      src/main/java/com/fdkankan/scene/service/IVisionService.java
  14. 16 0
      src/main/java/com/fdkankan/scene/service/SceneShapeEnumService.java
  15. 29 0
      src/main/java/com/fdkankan/scene/service/impl/CommonServiceImpl.java
  16. 22 1
      src/main/java/com/fdkankan/scene/service/impl/SceneCopyServiceImpl.java
  17. 2 0
      src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java
  18. 14 0
      src/main/java/com/fdkankan/scene/service/impl/SceneMarkShapeServiceImpl.java
  19. 122 21
      src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java
  20. 10 1
      src/main/java/com/fdkankan/scene/service/impl/SceneServiceImpl.java
  21. 24 0
      src/main/java/com/fdkankan/scene/service/impl/SceneShapeEnumServiceImpl.java
  22. 57 18
      src/main/java/com/fdkankan/scene/service/impl/VisionServiceImpl.java
  23. 162 0
      src/main/java/com/fdkankan/scene/util/CoordinateUtil.java
  24. 2 1
      src/main/java/com/fdkankan/scene/vo/SceneEditControlsParamVO.java
  25. 4 0
      src/main/java/com/fdkankan/scene/vo/SceneEditControlsVO.java
  26. 2 0
      src/main/java/com/fdkankan/scene/vo/SceneInfoVO.java
  27. 6 0
      src/main/java/com/fdkankan/scene/vo/SceneMarkShapeParamVO.java

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

@@ -240,5 +240,6 @@ public class SceneJsonBean {
 
     private String orientation;
 
+    private Integer hasRecognition;
 
 }

+ 51 - 0
src/main/java/com/fdkankan/scene/controller/SceneEditAiController.java

@@ -0,0 +1,51 @@
+package com.fdkankan.scene.controller;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.scene.annotation.CheckPermit;
+import com.fdkankan.scene.entity.SceneMarkShape;
+import com.fdkankan.scene.entity.SceneShapeEnum;
+import com.fdkankan.scene.service.ISceneMarkShapeService;
+import com.fdkankan.scene.service.SceneShapeEnumService;
+import com.fdkankan.scene.vo.SceneMarkShapeParamVO;
+import com.fdkankan.web.response.ResultData;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+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 java.util.List;
+
+@RestController
+@RequestMapping("/service/scene/edit/ai")
+public class SceneEditAiController {
+
+    @Autowired
+    private ISceneMarkShapeService sceneMarkShapeService;
+    @Autowired
+    private SceneShapeEnumService sceneShapeEnumService;
+
+    @CheckPermit
+    @PostMapping("/box4/getInfos")
+    public ResultData box4GetInfos(@RequestBody @Validated SceneMarkShapeParamVO param) {
+        List<SceneMarkShape> sceneMarkShapes = sceneMarkShapeService.findByNumAndType(param.getNum(),param.getType());
+        for (SceneMarkShape sceneMarkShape : sceneMarkShapes) {
+            if (ObjectUtil.isNotEmpty(sceneMarkShape.getShapes())){
+                for (JSONObject shape : sceneMarkShape.getShapes()) {
+                    String category = shape.getString("category");
+                    SceneShapeEnum sceneShapeEnum = sceneShapeEnumService.findByClassName(category);
+                    if (ObjectUtil.isNotNull(sceneShapeEnum)){
+                        shape.put("name",sceneShapeEnum.getName());
+                    }
+                    if (category.contains("Tag_")){
+                        shape.put("category","Tag");
+                    }
+                }
+            }
+        }
+        return ResultData.ok(sceneMarkShapes);
+    }
+
+}

+ 24 - 2
src/main/java/com/fdkankan/scene/controller/SceneEditController.java

@@ -100,6 +100,30 @@ public class SceneEditController extends BaseController {
 
     /**
      * <p>
+      热点切图上传
+     * </p>
+     * @author dengsixing
+     * @date 2022/1/12
+     * @return com.fdkankan.web.response.ResultData
+     **/
+    @CheckPermit
+    @PostMapping(value = "/tag/img/upload")
+    public ResultData uploadTagImg(@RequestParam(value = "num") String num,
+                                   MultipartFile file,
+                                   @RequestParam(value = "sid") String sid,
+                                   @RequestParam(value = "size", defaultValue = "320") Integer size,
+                                   @RequestParam(value = "tileSize", defaultValue = "511") Integer tileSize) throws Exception {
+        return sceneProService.uploadTagImg(num, file, sid, size, tileSize);
+    }
+
+    @CheckPermit
+    @PostMapping(value = "/tag/img/delete")
+    public ResultData uploadTagImg(@RequestBody @Validated DeleteSidListParamVO param) throws Exception {
+        return sceneProService.deleteTagImg(param);
+    }
+
+    /**
+     * <p>
         新增或修改场景热点
      * </p>
      * @author dengsixing
@@ -321,7 +345,6 @@ public class SceneEditController extends BaseController {
      * </p>
      * @author dengsixing
      * @date 2022/1/20
-     * @param param
      * @return com.fdkankan.web.response.ResultData
      **/
     @CheckPermit
@@ -336,7 +359,6 @@ public class SceneEditController extends BaseController {
      * </p>
      * @author dengsixing
      * @date 2022/1/20
-     * @param param
      * @return com.fdkankan.web.response.ResultData
      **/
     @CheckPermit

+ 74 - 0
src/main/java/com/fdkankan/scene/dto/GeoPoint.java

@@ -0,0 +1,74 @@
+package com.fdkankan.scene.dto;
+
+import lombok.Data;
+
+import java.util.Objects;
+
+/**
+ * @author Xiewj
+ * @date 2021/11/9
+ */
+@Data
+public class GeoPoint {
+
+    public GeoPoint() {
+    }
+
+    public GeoPoint(Double lon, Double lat) {
+        this.lon = lon;
+        this.lat = lat;
+    }
+    public GeoPoint(Double[] point) {
+        if (point != null && point.length != 0) {
+            if (point.length == 1) {
+                this.lon = point[0];
+            } else {
+                this.lon = point[0];
+                this.lat = point[1];
+            }
+        } else {
+            this.lon = 0.0D;
+            this.lat = 0.0D;
+        }
+    }
+    public Double[] getCoordinates() {
+        if(Objects.isNull(this.lon) || Objects.isNull(this.lat) || Objects.isNull(this.alt)){
+            return new Double[]{};
+        }
+        return new Double[]{this.lon, this.lat, this.alt};
+    }
+
+    public void setCoordinates(Double[] coordinates) {
+        if (coordinates != null && coordinates.length != 0) {
+            if (coordinates.length == 1) {
+                this.lon = coordinates[0];
+            } else {
+                this.lon = coordinates[0];
+                this.lat = coordinates[1];
+                this.alt = coordinates[2];
+            }
+        } else {
+            this.lon = 0.0D;
+            this.lat = 0.0D;
+            this.alt = 0.0D;
+        }
+    }
+
+    /* 经度 */
+    private Double lon;
+    /* 纬度 */
+    private Double lat;
+
+    private Double alt;
+
+    private Double[] location;
+
+    private Long id;
+    private Long uuid;
+
+    private int statusIndicator;
+
+    private boolean pointA;
+
+    private boolean pointB;
+}

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

@@ -187,5 +187,17 @@ public class SceneEditControls implements Serializable {
     @TableLogic(value = "A", delval = "I")
     private String recStatus;
 
+    /**
+     * 是否显示ai识别
+     */
+    @TableField("show_ai")
+    private Integer showAi;
+
+    /**
+     * 是否显示点云跳转按钮
+     */
+    @TableField("show_laser")
+    private Integer showLaser;
+
 
 }

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

@@ -71,4 +71,10 @@ public class SceneMarkShape implements Serializable {
       @TableLogic(value = "A", delval = "I")
       private String recStatus;
 
+      /**
+       * 推理类型 1,全景图识别 2,平面图识别
+       */
+      @TableField("type")
+      private Integer type;
+
 }

+ 3 - 0
src/main/java/com/fdkankan/scene/entity/ScenePlusExt.java

@@ -181,4 +181,7 @@ public class ScenePlusExt implements Serializable {
 
     @TableField("location")
     private Integer location;
+
+    @TableField("has_recognition")
+    private Integer hasRecognition;
 }

+ 61 - 0
src/main/java/com/fdkankan/scene/entity/SceneShapeEnum.java

@@ -0,0 +1,61 @@
+package com.fdkankan.scene.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * 标注框模型表
+ *
+ * @author Xiewj
+ * @since 2023-11-09 11:53
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@TableName("t_scene_shape_enum")
+public class SceneShapeEnum {
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 属性名
+     */
+    private String name;
+
+    /**
+     * 类名
+     */
+    private String className;
+
+    /**
+     * 资源类型ID
+     */
+    private String resourceId;
+
+    /**
+     * 设备类型ID
+     */
+    private String typeId;
+
+    /**
+     * 记录的状态,A: 生效,I: 禁用
+     */
+    private String recStatus;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+}

+ 17 - 0
src/main/java/com/fdkankan/scene/mapper/SceneShapeEnumMapper.java

@@ -0,0 +1,17 @@
+package com.fdkankan.scene.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.scene.entity.SceneShapeEnum;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Component;
+
+/**
+* 标注框模型表 Mapper
+*
+* @author Xiewj
+* @since 2023-11-09 11:53
+*/
+@Mapper
+@Component("SceneShapeEnumMapper")
+public interface SceneShapeEnumMapper extends BaseMapper<SceneShapeEnum> {
+}

+ 8 - 0
src/main/java/com/fdkankan/scene/service/ICommonService.java

@@ -1,9 +1,17 @@
 package com.fdkankan.scene.service;
 
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.scene.bean.SceneJsonBean;
+
+import java.util.Map;
+
 public interface ICommonService {
 
     void transferToFlv(String num, String fileName, String bucket) throws Exception;
 
+    void updateViewGetInfo(String num, Map<String, Object> param);
+
+    JSONObject getInfoJson(String num);
 
 
 }

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

@@ -27,4 +27,8 @@ public interface ISceneMarkShapeService extends IService<SceneMarkShape> {
     List<SceneMarkShape> findByToTrainStatus(Integer toTrain);
 
     void editTrainStatus(SceneMarkShapeParamVO param);
+
+    List<SceneMarkShape> findByNumAndType(String num,Integer type);
+
+    List<SceneMarkShape> findByNum(String num);
 }

+ 6 - 10
src/main/java/com/fdkankan/scene/service/ISceneProService.java

@@ -2,18 +2,10 @@ package com.fdkankan.scene.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fdkankan.scene.bean.SceneBean;
+import com.fdkankan.scene.vo.*;
 import com.fdkankan.web.response.ResultData;
 import com.fdkankan.scene.entity.ScenePro;
-import com.fdkankan.scene.vo.BaseDataParamVO;
-import com.fdkankan.scene.vo.DeleteHotIconParamVO;
-import com.fdkankan.scene.vo.DeleteHotParamVO;
-import com.fdkankan.scene.vo.FileNameAndDataParamVO;
-import com.fdkankan.scene.vo.FileParamVO;
-import com.fdkankan.scene.vo.SaveTagsParamVO;
-import com.fdkankan.scene.vo.SaveTagsVisibleParamVO;
-import com.fdkankan.scene.vo.SceneEditParamVO;
-import com.fdkankan.scene.vo.SceneParamVO;
-import com.fdkankan.scene.vo.SceneVO;
+
 import java.util.List;
 import java.util.Set;
 
@@ -34,6 +26,10 @@ public interface ISceneProService extends IService<ScenePro> {
 
     ResultData addOrUpdateTag(SaveTagsParamVO param) throws Exception;
 
+    ResultData uploadTagImg(String num, MultipartFile file, String sid, Integer size, Integer tileSize) throws Exception;
+
+    ResultData deleteTagImg(DeleteSidListParamVO param);
+
     ResultData deleteTag(DeleteHotParamVO param) throws Exception;
 
     ResultData deleteIcons(DeleteHotIconParamVO param) throws Exception;

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

@@ -1,5 +1,6 @@
 package com.fdkankan.scene.service;
 
+import com.fdkankan.scene.dto.GeoPoint;
 import com.fdkankan.web.response.ResultData;
 
 import java.util.List;
@@ -7,6 +8,6 @@ import java.util.Map;
 
 public interface IVisionService {
 
-    List<Map<String, Object>> getPointLatAndLon(String num);
+    List<GeoPoint> getPointLatAndLon(String num);
 
 }

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

@@ -0,0 +1,16 @@
+package com.fdkankan.scene.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.scene.entity.SceneShapeEnum;
+
+/**
+ * 标注框模型表 服务类接口
+ *
+ * @author Xiewj
+ * @since 2023-11-09 11:53
+ */
+public interface SceneShapeEnumService extends IService<SceneShapeEnum> {
+
+      SceneShapeEnum findByClassName(String className);
+}

+ 29 - 0
src/main/java/com/fdkankan/scene/service/impl/CommonServiceImpl.java

@@ -1,21 +1,30 @@
 package com.fdkankan.scene.service.impl;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.common.util.FileUtils;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.model.constants.ConstantFilePath;
 import com.fdkankan.model.constants.UploadFilePath;
 import com.fdkankan.model.utils.CreateObjUtil;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.scene.bean.SceneJsonBean;
 import com.fdkankan.scene.service.ICommonService;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
 
 @Service
 public class CommonServiceImpl implements ICommonService {
 
     @Resource
     private FYunFileServiceInterface fYunFileService;
+    @Resource
+    private RedisUtil redisUtil;
 
     @Override
     public void transferToFlv(String num, String fileName, String bucket) throws Exception {
@@ -44,4 +53,24 @@ public class CommonServiceImpl implements ICommonService {
         String flvFileName = fileName.replace("mp4", "flv");
         fYunFileService.uploadFile(bucket, localFilePath.replace("mp4", "flv"), userEditPath+flvFileName);
     }
+
+    @Override
+    public void updateViewGetInfo(String num, Map<String, Object> param) {
+        JSONObject infoJson = this.getInfoJson(num);
+        param.keySet().stream().forEach(k->{
+            infoJson.put(k, param.get(k));
+        });
+        String sceneJsonKey = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "scene.json";
+        fYunFileService.uploadFile(infoJson.toJSONString().getBytes(StandardCharsets.UTF_8), sceneJsonKey);
+
+        String redisKey = String.format(RedisKey.SCENE_JSON, num);
+        redisUtil.del(redisKey);
+    }
+
+    @Override
+    public JSONObject getInfoJson(String num) {
+        String sceneJsonKey = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "scene.json";
+        String fileContent = fYunFileService.getFileContent(sceneJsonKey);
+        return JSON.parseObject(fileContent);
+    }
 }

+ 22 - 1
src/main/java/com/fdkankan/scene/service/impl/SceneCopyServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fdkankan.scene.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.qrcode.QrCodeUtil;
@@ -22,6 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
 import java.io.File;
 import java.util.*;
 
@@ -50,10 +52,13 @@ public class SceneCopyServiceImpl implements ISceneCopyService {
 
     @Autowired
     ILaserService laserService;
-    @Autowired
+    @Resource
     FYunFileServiceInterface fYunFileServiceInterface;
     @Autowired
     RabbitMqProducer rabbitMqProducer;
+    @Autowired
+    ISceneMarkShapeService sceneMarkShapeService;
+
     @Override
     public void copyScene(String oldNum, String newNum) {
         ScenePro scenePro = sceneProService.getByNum(oldNum);
@@ -141,6 +146,8 @@ public class SceneCopyServiceImpl implements ISceneCopyService {
 
             this.copyOssAndNasV4(oldNum,newNum);
 
+            this.copyMarkShape(oldNum,newNum);
+
             //修改 oss status.json ,nas scene.json
             String targetData = String.format(SceneResourcePath.DATA_VIEW_PATH,newNum);
             this.updateOssJson(targetData,oldNum,newNum,"status.json");
@@ -162,6 +169,20 @@ public class SceneCopyServiceImpl implements ISceneCopyService {
 
     }
 
+    private void copyMarkShape(String oldNum, String newNum){
+        List<SceneMarkShape> sceneMarkShapes = sceneMarkShapeService.findByNum(oldNum);
+        if(CollUtil.isEmpty(sceneMarkShapes)){
+            return;
+        }
+        sceneMarkShapes.stream().forEach(v->{
+            v.setId(null);
+            v.setNum(newNum);
+            v.setCreateTime(new Date());
+            v.setUpdateTime(null);
+        });
+        sceneMarkShapeService.saveBatch(sceneMarkShapes);
+    }
+
     private void cpV3(ScenePro scenePro ,String oldNum,String newNum) {
         try {
             Long sceneProId = scenePro.getId();

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

@@ -244,6 +244,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         sceneJson.setSceneKind(scenePlusExt.getSceneKind());
         sceneJson.setModelKind(scenePlusExt.getModelKind());
         sceneJson.setOrientation(scenePlusExt.getOrientation());
+        sceneJson.setHasRecognition(scenePlusExt.getHasRecognition());
         if(StrUtil.isNotEmpty(scenePlusExt.getVideos())){
             sceneJson.setVideos(scenePlusExt.getVideos());
         }
@@ -501,6 +502,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         sceneInfoVO.setSns(JSON.parseObject(sceneEditInfoExt.getSnsInfo()));
         sceneInfoVO.setStarted(JSON.parseObject(sceneEditInfoExt.getStarted()));
         sceneInfoVO.setOrientation(scenePlusExt.getOrientation());
+        sceneInfoVO.setHasRecognition(scenePlusExt.getHasRecognition());
 
         this.SortBoxVideos(sceneInfoVO);
 

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

@@ -178,4 +178,18 @@ public class SceneMarkShapeServiceImpl extends ServiceImpl<MarkShapeMapper, Scen
             save(sceneMarkShape);
         }
     }
+    @Override
+    public List<SceneMarkShape> findByNumAndType(String num,Integer type) {
+        LambdaQueryWrapper<SceneMarkShape> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(SceneMarkShape::getNum,num);
+        wrapper.eq(SceneMarkShape::getType,type);
+        return list(wrapper);
+    }
+
+    @Override
+    public List<SceneMarkShape> findByNum(String num) {
+        LambdaQueryWrapper<SceneMarkShape> wrapper = Wrappers.lambdaQuery();
+        wrapper.eq(SceneMarkShape::getNum,num);
+        return list(wrapper);
+    }
 }

+ 122 - 21
src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java

@@ -5,6 +5,7 @@ import cn.hutool.core.date.DateField;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.XmlUtil;
 import cn.hutool.core.util.ZipUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
@@ -14,6 +15,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fdkankan.common.constant.*;
 import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.util.CmdUtils;
 import com.fdkankan.common.util.FileUtils;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.model.constants.ConstantFileName;
@@ -42,6 +44,8 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 
 import javax.annotation.Resource;
 import java.io.File;
@@ -159,6 +163,90 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         return ResultData.ok();
     }
 
+    @Override
+    public ResultData uploadTagImg(String num, MultipartFile file, String sid, Integer size, Integer tileSize) throws Exception {
+        String extName = FileUtil.extName(file.getOriginalFilename());
+        String fragmentPath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "hot_img_fragment/";
+        String workPath = fragmentPath + sid;
+        String dziPath = workPath + ".dzi";
+        String outFilesPath = workPath + "_files/";
+        Integer height = null;
+        Integer width = null;
+        try {
+            FileUtil.mkdir(workPath);
+
+            //保存到本地
+            String origFilePath = workPath + "/" + sid + "." + extName;
+            file.transferTo(new File(origFilePath));
+
+            String ossPath = String.format(UploadFilePath.USER_EDIT_PATH, num) + "hotspot/" + sid + "/";
+            Map<String, String> uploadMap = new HashMap<>();
+
+            //切图
+            String fragmentCmd = "vips dzsave --tile-size "  + tileSize + " " + origFilePath + " " +  workPath;
+            CmdUtils.callLine(fragmentCmd);
+            if(!ComputerUtil.checkComputeCompleted(dziPath, 5, 200)){
+                throw new BusinessException(ErrorCode.FAILURE_CODE_5052);
+            }
+            List<File> files = FileUtil.loopFiles(outFilesPath);
+            files.stream().forEach(v->{
+                uploadMap.put(v.getAbsolutePath(), v.getAbsolutePath().replace(outFilesPath, ossPath));
+            });
+
+            //是否缩放缩略图,判断:读取dzi中的w h,只要有一个超过320,则进行缩放,如果前端传参,则以传参值为准, 缩放默认值320,否则拿原图作为缩略图,
+            String thumbnailName = "thumbnail." + extName;
+            Document document = XmlUtil.readXML(new File(dziPath));
+            Element rootElement = XmlUtil.getRootElement(document);
+            Element sizeElement = XmlUtil.getElement(rootElement, "Size");
+            height = Integer.valueOf(sizeElement.getAttribute("Height"));
+            width = Integer.valueOf(sizeElement.getAttribute("Width"));
+            Integer maxSize = height > width ? height : width;
+            if(maxSize > size){
+                String thumbnailPath =  workPath + "/" + thumbnailName;
+                String scaleCmd = "vipsthumbnail " + origFilePath  + " -s " + size + " -o " + thumbnailPath;
+                CmdUtils.callLine(scaleCmd);
+                if(!ComputerUtil.checkComputeCompleted(thumbnailPath, 5, 200)){
+                    throw new BusinessException(ErrorCode.FAILURE_CODE_5052);
+                }
+                uploadMap.put(thumbnailPath, ossPath + thumbnailName);
+            }else{
+                uploadMap.put(origFilePath, ossPath + thumbnailName);
+            }
+
+            //上传
+            uploadMap.entrySet().stream().forEach(entry->{
+                fYunFileService.uploadFile(entry.getKey(), entry.getValue());
+            });
+
+            //上传原图
+            fYunFileService.uploadFile(origFilePath, ossPath + sid + "." + extName);
+
+        }finally {
+            FileUtil.del(workPath);
+            FileUtil.del(dziPath);
+            FileUtil.del(outFilesPath);
+        }
+
+        Map<String, Object> hw = new HashMap<>();
+        hw.put("height",height);
+        hw.put("width",width);
+        hw.put("sid",sid);
+        hw.put("tileSize",tileSize);
+        return ResultData.ok(hw);
+    }
+
+    @Override
+    public ResultData deleteTagImg(DeleteSidListParamVO param) {
+        param.getSidList().stream().forEach(sid->{
+            String ossPath = String.format(UploadFilePath.USER_EDIT_PATH, param.getNum()) + "hotspot/" + sid + "/";
+            if(CollUtil.isNotEmpty(fYunFileService.listRemoteFiles(ossPath))){
+                fYunFileService.deleteFolder(ossPath);
+            }
+        });
+
+        return ResultData.ok();
+    }
+
     private void addOrUpdateHotData(String num, List<HotParamVO> hotDataList) throws Exception{
         Map<String, String> addOrUpdateMap = new HashMap<>();
         int i = 0;
@@ -531,6 +619,7 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         }
         //删除图片音频视频等资源文件
         List<String> deleteFileList = new ArrayList<>();
+        List<String> deleteKeys = new ArrayList<>();
         for (String data : hotdataList) {
             if(StrUtil.isBlank(data)){
                 continue;
@@ -554,23 +643,20 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
                 JSONArray media = jsonObject.getJSONArray("media");
                 media.stream().forEach(v->{
                     JSONObject o = (JSONObject) v;
-                    String src = o.getString("src");
-                    if(StrUtil.isNotEmpty(src)){
-                        deleteFileList.add(src);
+                    String fileSid = o.getString("sid");
+                    if(o.containsKey("tileSize")){//4.14.0版本,图片类型热点不调用通用上传接口上传,改为切图接口上传,所以这里直接删除整个文件目录
+                        String ossPath = String.format(UploadFilePath.USER_EDIT_PATH, num) + "hotspot/" + fileSid + "/";
+                        deleteKeys.add(ossPath);
+                    }else{
+                        String src = o.getString("src");
+                        if(StrUtil.isNotEmpty(src)){
+                            deleteFileList.add(src);
+                        }
                     }
+
                 });
             }
 
-            /* v4.12版本之前是这种方式
-            "media": {
-                "image": [
-                {
-                    "src": "FfRdi413774.jpg"
-                }
-		    ]
-            },
-            "type": "image"
-             */
             if("image".equals(type) || "audio".equals(type) || "video".equals(type)){
                 //删除图片、视频
                 JSONObject media = jsonObject.getJSONObject("media");
@@ -585,14 +671,19 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
             }
         }
 
-        if(CollUtil.isEmpty(deleteFileList)){
-            return;
+        if(CollUtil.isNotEmpty(deleteFileList)){
+            sceneUploadService.delete(
+                    DeleteFileParamVO.builder()
+                            .num(num)
+                            .fileNames(deleteFileList)
+                            .bizType("tag-media").build());
         }
-        sceneUploadService.delete(
-                DeleteFileParamVO.builder()
-                        .num(num)
-                        .fileNames(deleteFileList)
-                        .bizType("tag-media").build());
+        if(CollUtil.isNotEmpty(deleteKeys)){
+            deleteKeys.stream().forEach(key->{
+                fYunFileService.deleteFolder(key);
+            });
+        }
+
     }
 
     @Override
@@ -1214,8 +1305,18 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
 
     public static void main(String[] args) throws Exception {
 
-        ConvertUtils.convertVisionModelDataToTxt( "D:\\test\\vision.modeldata", "D:\\test\\vision.json");
+//        ConvertUtils.convertVisionModelDataToTxt( "D:\\test\\vision.modeldata", "D:\\test\\vision.json");
+        Document document = XmlUtil.readXML(new File("D:\\Downloads\\aaa.dzi"));
+//        XmlUtil.readObjectFromXml()
+//        Element image = document.getElementById("Image");
+//        getAttribute("size");
+
+        Element rootElement = XmlUtil.getRootElement(document);
+        Element size = XmlUtil.getElement(rootElement, "Size");
+        String Height = size.getAttribute("Height");
+        String Width = size.getAttribute("Width");
 
+        System.out.println(123);
     }
 
 

+ 10 - 1
src/main/java/com/fdkankan/scene/service/impl/SceneServiceImpl.java

@@ -20,6 +20,7 @@ import com.fdkankan.redis.util.RedisUtil;
 import com.fdkankan.scene.bean.BodySegmentStatusBean;
 import com.fdkankan.scene.entity.ScenePlus;
 import com.fdkankan.scene.entity.ScenePlusExt;
+import com.fdkankan.scene.service.ICommonService;
 import com.fdkankan.scene.service.IScenePlusExtService;
 import com.fdkankan.scene.service.IScenePlusService;
 import com.fdkankan.scene.service.ISceneService;
@@ -32,6 +33,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 import sun.rmi.runtime.Log;
 
+import javax.annotation.Resource;
 import javax.imageio.ImageIO;
 import java.awt.*;
 import java.awt.image.BufferedImage;
@@ -60,7 +62,7 @@ public class SceneServiceImpl implements ISceneService {
     private RedisUtil redisUtil;
     @Autowired
     private RabbitMqProducer rabbitMqProducer;
-    @Autowired
+    @Resource
     private FYunFileServiceInterface fYunFileService;
     @Autowired
     public FYunFileConfig fYunFileConfig;
@@ -68,6 +70,8 @@ public class SceneServiceImpl implements ISceneService {
     public IScenePlusService scenePlusService;
     @Autowired
     public IScenePlusExtService scenePlusExtService;
+    @Autowired
+    private ICommonService commonService;
 
     @Override
     public ResultData uploadBodySegment(MultipartFile file, Integer rotate) throws Exception {
@@ -181,6 +185,11 @@ public class SceneServiceImpl implements ISceneService {
             scenePlusExt.setOrientation(orientation);
             scenePlusExtService.updateById(scenePlusExt);
         }
+
+        //查看页生效
+        Map<String, Object> param = new HashMap<>();
+        param.put("orientation", orientation);
+        commonService.updateViewGetInfo(num,param);
     }
 
     @Override

+ 24 - 0
src/main/java/com/fdkankan/scene/service/impl/SceneShapeEnumServiceImpl.java

@@ -0,0 +1,24 @@
+package com.fdkankan.scene.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.scene.entity.SceneShapeEnum;
+import com.fdkankan.scene.mapper.SceneShapeEnumMapper;
+import com.fdkankan.scene.service.SceneShapeEnumService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 标注框模型表 服务实现类
+ *
+ * @author Xiewj
+ * @since 2023-11-09 11:53
+ */
+@Service
+public class SceneShapeEnumServiceImpl extends ServiceImpl<SceneShapeEnumMapper, SceneShapeEnum> implements SceneShapeEnumService {
+    @Override
+    public SceneShapeEnum findByClassName(String className) {
+        return this.getOne(new LambdaQueryWrapper<SceneShapeEnum>().eq(SceneShapeEnum::getClassName, className));
+    }
+
+
+}

+ 57 - 18
src/main/java/com/fdkankan/scene/service/impl/VisionServiceImpl.java

@@ -1,22 +1,23 @@
 package com.fdkankan.scene.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.scene.dto.GeoPoint;
 import com.fdkankan.scene.service.IVisionService;
+import com.fdkankan.scene.util.CoordinateUtil;
 import com.google.common.collect.Lists;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
+import java.util.stream.Collectors;
 
 @Service
 @Slf4j
@@ -26,33 +27,71 @@ public class VisionServiceImpl implements IVisionService {
     private FYunFileServiceInterface fYunFileService;
 
     @Override
-    public List<Map<String, Object>> getPointLatAndLon(String num) {
-        List<Map<String, Object>> list = Lists.newArrayList();
+    public List<GeoPoint> getPointLatAndLon(String num) {
         String visionTxt = fYunFileService.getFileContent(String.format(UploadFilePath.IMG_VIEW_PATH, num) + "vision.txt");
         JSONObject visionJson = JSON.parseObject(visionTxt);
         if(!visionJson.containsKey("sweepLocations")){
-            return list;
+            return null;
         }
         JSONArray sweepLocations = visionJson.getJSONArray("sweepLocations");
+        List<GeoPoint> geoPoints = new ArrayList<>();
         for (int i = 0; i < sweepLocations.size(); ++i) {
             JSONObject sweepItem = sweepLocations.getJSONObject(i);
-            String id = sweepItem.getString("id");
-            String uuid = sweepItem.getString("uuid");
+            Long id = sweepItem.getLong("id");
+            Long uuid = sweepItem.getLong("uuid");
             JSONObject ggaLocation = sweepItem.getJSONObject("ggaLocation");
+            GeoPoint geoPoint = new GeoPoint();
+            geoPoint.setId(id);
+            geoPoint.setUuid(uuid);
             if (Objects.nonNull(ggaLocation)
                     && StrUtil.isNotEmpty(ggaLocation.getString("lon"))
                     && StrUtil.isNotEmpty(ggaLocation.getString("lat"))
                     && StrUtil.isNotEmpty(ggaLocation.getString("alt"))) {
-                Map<String, Object> item = new HashMap<>();
-                item.put("lon", ggaLocation.getString("lon"));
-                item.put("lat", ggaLocation.getString("lat"));
-                item.put("alt", ggaLocation.getString("alt"));
-                item.put("id", id);
-                item.put("uuid", uuid);
-                list.add(item);
+                Double[] ggaLocationGps = new Double[3];
+                if(Objects.nonNull(ggaLocation.getDouble("lon"))
+                        && Objects.nonNull(ggaLocation.getDouble("lat"))
+                        && Objects.nonNull(ggaLocation.getDouble("alt"))){
+                    ggaLocationGps[0] = ggaLocation.getDouble("lon");
+                    ggaLocationGps[1] = ggaLocation.getDouble("lat");
+                    ggaLocationGps[2] = ggaLocation.getDouble("alt");
+                }
+                geoPoint.setCoordinates(ggaLocationGps);
+                geoPoint.setStatusIndicator(ggaLocation.getInteger("StatusIndicator"));
+
+            }
+            if (sweepItem.containsKey("puck")){
+                JSONObject puck = sweepItem.getJSONObject("puck");
+                Double[] floor_location = new Double[3];
+                floor_location[0] = puck.getDouble("x");
+                floor_location[1] = puck.getDouble("y");
+                floor_location[2] = puck.getDouble("z");
+                geoPoint.setLocation(floor_location);
             }
+            geoPoints.add(geoPoint);
         }
-
-        return list;
+        if (CollUtil.isNotEmpty(geoPoints) && geoPoints.size() >= 2) {
+            Map<String, GeoPoint> res = new HashMap<>();
+            List<GeoPoint> statusFourPoints  = geoPoints.stream().filter(item -> item.getStatusIndicator() == 4 || item.getStatusIndicator() == 100 || item.getStatusIndicator() == 104).collect(Collectors.toList());
+            if (statusFourPoints.size() >= 2) {
+                CoordinateUtil.divide(0, statusFourPoints.size() - 1, statusFourPoints.toArray(new GeoPoint[0]), res);
+            }else {
+                return null ;
+            }
+            for (GeoPoint geoPoint : geoPoints) {
+                if (res.containsKey("pointA")) {
+                    GeoPoint pointA = res.get("pointA");
+                    if (geoPoint.getId()==pointA.getId()){
+                        geoPoint.setPointA(true);
+                    }
+                }
+                if (res.containsKey("pointB")) {
+                    GeoPoint pointB = res.get("pointB");
+                    if (geoPoint.getId()==pointB.getId()){
+                        geoPoint.setPointB(true);
+                    }
+                }
+            }
+        }
+        return geoPoints;
     }
 }

+ 162 - 0
src/main/java/com/fdkankan/scene/util/CoordinateUtil.java

@@ -0,0 +1,162 @@
+package com.fdkankan.scene.util;
+
+
+import com.fdkankan.scene.dto.GeoPoint;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 距离 范围 计算工具类
+ * @author Xiewj
+ * @date 2021/11/23
+ */
+public class CoordinateUtil {
+   /**
+    * 计算经纬度围成的实际面积(平方公里)
+    * @return
+    */
+   public static BigDecimal getArea(List<GeoPoint> ring){
+      double sJ = 6378137;
+      double Hq = 0.017453292519943295;
+      double c = sJ *Hq;
+      double d = 0;
+
+      if (3 > ring.size()) {
+         return new BigDecimal( 0);
+      }
+
+      for (int i = 0; i < ring.size() - 1; i ++){
+         GeoPoint h = ring.get(i);
+         GeoPoint k = ring.get(i + 1);
+         double u = h.getLon() * c * Math.cos(h.getLat() * Hq);
+
+         double hhh = h.getLat() * c;
+         double v = k.getLon() * c * Math.cos(k.getLat() *Hq);
+         d = d + (u * k.getLat() * c - v * hhh);
+      }
+
+      GeoPoint g1 = ring.get(ring.size()-1);
+      GeoPoint point = ring.get(0);
+      double eee = g1.getLon() * c * Math.cos(g1.getLat() * Hq);
+      double g2 = g1.getLat() * c;
+
+      double k = point.getLon() * c * Math.cos(point.getLat() * Hq);
+      d += eee * point.getLat() * c - k * g2;
+      return new BigDecimal( 0.5*Math.abs(d));
+   }
+
+   // WGS84标准参考椭球中的地球长半径(单位:米)
+   private static final double EARTH_RADIUS_WGS84 = 6378137.0;
+   public static  GeoPoint pointA = new GeoPoint();
+   public static  GeoPoint pointB = new GeoPoint();
+
+   /**
+    * 计算两个坐标的距离(粗略计算,单位:米)
+    * 计算公式参照 google map 的距离计算
+    *
+    * @param gps1 坐标1
+    * @param gps2 坐标2
+    * @return
+    */
+   public static double distance(GeoPoint gps1, GeoPoint gps2) {
+
+      double radLat1 = Math.toRadians(gps1.getLat());
+      double radLat2 = Math.toRadians(gps2.getLat());
+
+      double a = radLat1 - radLat2;
+      double b = Math.toRadians(gps1.getLon()) - Math.toRadians(gps2.getLon());
+
+      double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
+              Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
+
+      return Math.round(s * EARTH_RADIUS_WGS84);
+
+   }
+
+
+   public static void distance(List<Object> pointList) {
+
+
+   }
+   /*
+    * @Title divide
+    * @Description 求平面上距离最近的两个点
+    * @author 滑技工厂
+    * @Date 2020/3/28
+    * @param [left, right, points]
+    * @return double
+    * @throws
+    */
+   public static double divide(int left, int right, GeoPoint[] points, Map<String, GeoPoint> res) {
+      // 当前最小两点距离,初始值设置为无穷大
+      double curMaxDis = 1e20;
+      // 如果只有一个点,则不存在最近两点距离,返回无穷大
+      if (left == right) {
+         return curMaxDis;
+      }
+      // 这里是判断是否为只有两个点,如果只有两个点的话那么直接求解。
+      if (left + 1 == right) {
+         res.put("pointA",points[left]);
+         res.put("pointB",points[right]);
+         return distance(points[left], points[right]);
+      }
+
+      // 分治法:第一步:分区,并求取左右分区最小两点距离
+      // 通过右移运算除2,对区域进行合理的划分,使得左右两边保持大致相等个数点
+      int middle = (left + right) >> 1;
+      double leftMinDis = divide(left, middle, points,res);
+      double rightMinDis = divide(middle, right, points,res);
+
+      curMaxDis = (leftMinDis <= rightMinDis) ? leftMinDis : leftMinDis;
+
+      // 分治法:第二步:假设距离最近的两点分别在左右分区中
+      // 关键代码,距离最近的两个点,一个位于左边区域,一个位于右边区域,x轴搜索范围[middle-curMaxDis, middle+curMaxDis]
+      // 记录搜索区间内的点的索引,便于进一步计算最小距离
+      List<Integer> validPointIndex = new ArrayList<>();
+      for (int i = left; i <= right; i++) {
+         if (Math.abs(points[middle].getLat() - points[i].getLat()) <= curMaxDis) {
+            validPointIndex.add(i);
+         }
+      }
+      // 基于索引,进一步计算区间内最小两点距离
+      for (int i = 0; i < validPointIndex.size() - 1; i++) {
+         for (int j = i + 1; j < validPointIndex.size(); j++) {
+            // 如果区间内的两点y轴距离大于curMinDis,则没必要计算了,因为,它们的距离肯定大于curMinDis,
+            if (Math.abs(points[validPointIndex.get(i)].getLon()
+                    - points[validPointIndex.get(j)].getLon()) > curMaxDis) {
+               continue;
+            }
+            double tempDis = distance(points[validPointIndex.get(i)],
+                    points[validPointIndex.get(j)]);
+
+            if (tempDis > curMaxDis){
+               curMaxDis=tempDis;
+               res.put("pointA",points[validPointIndex.get(i)]);
+               res.put("pointB",points[validPointIndex.get(j)]);
+            }
+         }
+      }
+      return curMaxDis;
+   }
+
+
+   public static void main(String[] args) {
+//      int i=500;
+//      List<GeoPoint> ring = new ArrayList<>();
+//
+//      for (int i1 = i; i1 > 0; i1--) {
+//         double a = RandomUtil.randomDouble(113.0000001, 113.9999999);
+//         double b = RandomUtil.randomDouble(22.0000001,22.9999999);
+//         GeoPoint d=new GeoPoint(a,b);
+//         ring.add(d);
+//      }
+//      JSONObject res=new JSONObject();
+//      TimeInterval timer = DateUtil.timer();
+//      System.out.println(divide(0, ring.size()-1, ring.toArray(new GeoPoint[0]),res));
+//      System.out.println(res);
+//      System.out.println("使用秒数"+timer.intervalMs());
+   }
+}

+ 2 - 1
src/main/java/com/fdkankan/scene/vo/SceneEditControlsParamVO.java

@@ -133,7 +133,8 @@ public class SceneEditControlsParamVO implements Serializable {
 
     private Integer showPanos;
 
+    private Integer showAi;
 
-
+    private Integer showLaser;
 
 }

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

@@ -123,5 +123,9 @@ public class SceneEditControlsVO implements Serializable {
 
     private Integer showPanos;
 
+    private Integer showAi;
+
+    private int showLaser;
+
 
 }

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

@@ -268,4 +268,6 @@ public class SceneInfoVO {
 
     private String orientation;
 
+    private Integer hasRecognition;
+
 }

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

@@ -32,5 +32,11 @@ public class SceneMarkShapeParamVO {
      */
     private String imagePath;
 
+    /**
+     * 推理类型 1,全景图识别 2,平面图识别 为了兼容默认给1
+     */
+
+    private Integer type =1 ;
+
 
 }