浏览代码

江门1.6.0

dengsixing 8 月之前
父节点
当前提交
9dd11ae436

+ 27 - 0
src/main/java/com/fdkankan/contro/bean/TagBean.java

@@ -0,0 +1,27 @@
+package com.fdkankan.contro.bean;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/3/24
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class TagBean {
+
+    private Long createTime;
+
+    private JSONObject tag;
+
+}

+ 5 - 2
src/main/java/com/fdkankan/contro/entity/ScenePlusExt.java

@@ -12,10 +12,10 @@ import lombok.Setter;
 
 /**
  * <p>
- * 
+ *
  * </p>
  *
- * @author 
+ * @author
  * @since 2022-03-16
  */
 @Getter
@@ -184,4 +184,7 @@ public class ScenePlusExt implements Serializable {
      */
     @TableField("is_obj")
     private int isObj;
+
+    @TableField("orientation")
+    private String orientation;
 }

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

@@ -145,6 +145,8 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
     private IOrigFileUploadBatchService origFileUploadBatchService;
     @Autowired
     private IOrigFileUploadService origFileUploadService;
+    @Autowired
+    private ILinkPanService linkPanService;
 
     public static void main(String[] args) {
         SceneJsonBean sceneJson = new SceneJsonBean();
@@ -199,6 +201,16 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             //下载资源到本地
             this.downLoadSource(message, message.getPath());
 
+            List<String> linkPanTargetList = linkPanService.genLinkPanPre(num);
+            if(CollUtil.isNotEmpty(linkPanTargetList)){
+                Map<String, Object> ext = message.getExt();
+                if(Objects.isNull(ext)){
+                    ext = new HashMap<>();
+                    message.setExt(ext);
+                }
+                ext.put("linkPanTargetList", linkPanTargetList);
+            }
+
             JSONObject fdageJson = JSONObject.parseObject(FileUtils.readFile(message.getPath().concat("/capture/data.fdage")));
 
             boolean rewrite = false;
@@ -419,6 +431,9 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             boolean existHouseType = this.uploadHouseTypeJson(sceneCode, path);
             scenePlus.setHouseType(existHouseType ? CommonStatus.YES.code().intValue() : CommonStatus.NO.code().intValue());
 
+            //生成场景关联数据
+            Integer links = linkPanService.genLinkPanPost(sceneCode);
+
             //生成floorpan.json
             commonService.uploadFloorplanJson(sceneCode, path);
 
@@ -452,6 +467,8 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             //统计原始资源大小
             scenePlusExt.setOrigSpace(FileUtil.size(new File(path.concat(File.separator).concat("capture"))));
 
+            scenePlusExt.setOrientation(fdageData.getString("orientation"));
+
             if (cameraType == 14) {
                 //计算成功  激光转台相机 同步 请求
                 fdkkLaserService.syncBuildResult(scenePlus.getNum(), path, scenePlus.getCreateTime(), Calendar.getInstance().getTime(), scenePlusExt.getShootCount(), scenePlus.getPayStatus());

+ 11 - 0
src/main/java/com/fdkankan/contro/service/ILinkPanService.java

@@ -0,0 +1,11 @@
+package com.fdkankan.contro.service;
+
+import java.util.List;
+
+public interface ILinkPanService {
+
+    List<String> genLinkPanPre(String num) throws Exception;
+
+    Integer genLinkPanPost(String num) throws Exception;
+
+}

+ 370 - 0
src/main/java/com/fdkankan/contro/service/impl/LinkPanServiceImpl.java

@@ -0,0 +1,370 @@
+package com.fdkankan.contro.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.CommonStatus;
+import com.fdkankan.contro.bean.TagBean;
+import com.fdkankan.contro.entity.ScenePlus;
+import com.fdkankan.contro.entity.ScenePlusExt;
+import com.fdkankan.contro.service.ILinkPanService;
+import com.fdkankan.contro.service.IScenePlusExtService;
+import com.fdkankan.contro.service.IScenePlusService;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.model.constants.ConstantFilePath;
+import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.util.RedisUtil;
+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.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class LinkPanServiceImpl implements ILinkPanService {
+
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
+    @Resource
+    private RedisUtil redisUtil;
+    @Resource
+    private FYunFileServiceInterface fYunFileService;
+
+    @Override
+    public Integer genLinkPanPost(String num) throws Exception {
+        log.info("开始计算场景关联,num:{}", num);
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+        ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+        String dataSource = scenePlusExt.getDataSource();
+        String baseCapturePath = dataSource + File.separator + "capture" + File.separator;
+        String dataFdagePath = baseCapturePath + "data.fdage";
+        String dataFdageStr = FileUtil.readUtf8String(dataFdagePath);
+        JSONObject dataFdageObj = JSON.parseObject(dataFdageStr);
+        Integer links = 0;
+        if ( dataFdageObj.containsKey("points")){
+            JSONArray points = dataFdageObj.getJSONArray("points");
+            log.info("points:{}", JSON.toJSONString(points));
+            if(ObjUtil.isNotNull(points)){
+                for (Object point : points) {
+                    JSONObject pointObj = (JSONObject) point;
+                    Integer panoId = pointObj.getInteger("index");
+                    List<String> panos = (List<String>)pointObj.get("panos");
+                    log.info("panos:{}", JSON.toJSONString(panos));
+                    if(panos==null ||  ArrayUtil.isEmpty(panos)){
+                        continue;
+                    }
+                    for (String pano : panos) {
+
+                        String sid = FileUtil.getPrefix(pano);
+
+                        String localImagesPath = dataSource + File.separator + "linkPan" +  File.separator;
+                        String target = localImagesPath + "panorama" + File.separator + sid;
+                        String filePath = target + File.separator + "extras" + File.separator + "images" + File.separator + pano;
+                        String resultPath = target + File.separator + "results";
+                        JSONArray array = this.getUploadArray(resultPath + "/upload.json");
+                        JSONObject fileJson;
+                        String uploadFile, uploadFilePath;
+                        String imgEditPath = String.format(UploadFilePath.IMG_EDIT_PATH, num);
+                        String imgViewPath = String.format(UploadFilePath.IMG_VIEW_PATH, num);
+                        for(int i = 0, len = array.size(); i < len; i++){
+                            fileJson = array.getJSONObject(i);
+                            uploadFile = fileJson.getString("file");
+                            uploadFilePath = resultPath +File.separator + uploadFile;
+                            //文件不存在抛出异常
+
+                            if(!cn.hutool.core.io.FileUtil.exist(uploadFilePath)){
+                                throw new Exception(uploadFilePath + "文件不存在");
+                            }
+
+                            Integer clazz = fileJson.getIntValue("clazz");
+                            if(Objects.isNull(clazz)){
+                                continue;
+                            }
+                            if(clazz == 4 || clazz == 5 || clazz == 7){
+                                fYunFileService.uploadFile(uploadFilePath, imgEditPath + "panorama/" + sid + File.separator + uploadFile);
+                                fYunFileService.uploadFile(uploadFilePath, imgViewPath + "panorama/" + sid + File.separator + uploadFile);
+
+                            }
+                        }
+                        fYunFileService.uploadFile(filePath, imgEditPath + "panorama/" + sid + "/high/" + pano);
+                        fYunFileService.uploadFile(filePath, imgViewPath + "panorama/" + sid + "/high/" + pano);
+
+                        this.addOrUpdateLinPan(num, pano, panoId, sid);
+                    }
+                }
+
+                log.info("开始links.json文件");
+                links = this.publicLinkSceneData(num);
+                log.info("结束生成links.json文件");
+            }
+        }
+        log.info("结束计算场景关联,num:{}", num);
+
+        return links;
+    }
+
+    @Override
+    public List<String> genLinkPanPre(String num) throws Exception {
+
+        List<String> panoTargetList = new ArrayList<>();
+
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+        ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+        String dataSource = scenePlusExt.getDataSource();
+        String baseCapturePath = dataSource + File.separator + "capture" + File.separator;
+        String dataFdagePath = baseCapturePath + "data.fdage";
+        String dataFdageStr = FileUtil.readUtf8String(dataFdagePath);
+        JSONObject dataFdageObj = JSON.parseObject(dataFdageStr);
+        if ( dataFdageObj.containsKey("points")){
+            JSONArray points = dataFdageObj.getJSONArray("points");
+            log.info("points:{}", JSON.toJSONString(points));
+            if(ObjUtil.isNotNull(points)){
+                for (Object point : points) {
+                    JSONObject pointObj = (JSONObject) point;
+                    List<String> panos = (List<String>)pointObj.get("panos");
+                    log.info("panos:{}", JSON.toJSONString(panos));
+                    if(panos==null ||  ArrayUtil.isEmpty(panos)){
+                        continue;
+                    }
+                    for (String pano : panos) {
+
+                        String sid = FileUtil.getPrefix(pano);
+
+                        String localImagesPath = dataSource + File.separator + "linkPan" +  File.separator;
+                        String target = localImagesPath + "panorama" + File.separator + sid;
+                        FileUtil.del(target);
+
+                        //文件写如本地磁盘
+                        String filePath = target + File.separator + "extras" + File.separator + "images" + File.separator + pano;
+                        File targetFile = new File(filePath);
+                        if(!targetFile.getParentFile().exists()){
+                            targetFile.getParentFile().mkdirs();
+                        }
+                        FileUtil.copy(baseCapturePath + pano, filePath, true);
+
+                        //生成vision.txt
+                        this.writeVisionTxt(sid, target);
+
+                        //data.json增加extras为执行重建算法
+                        this.writeDataJson(scenePlusExt.getSceneScheme(), scenePlusExt.getSceneResolution(), target);
+
+                        //创建文件夹软连接并且复制data.json和project.json
+                        String capturePath = target + File.separator + "capture";
+                        String resultPath = target + File.separator + "results";
+                        log.info("场景关联上传全景图:capturePath={}", capturePath);
+                        log.info("场景关联上传全景图:resultPath={}", resultPath);
+                        if(cn.hutool.core.io.FileUtil.exist(capturePath)){
+                            cn.hutool.core.io.FileUtil.del(capturePath);
+                        }
+                        if(cn.hutool.core.io.FileUtil.exist(resultPath)){
+                            cn.hutool.core.io.FileUtil.del(resultPath);
+                        }
+                        //下载data.fdage
+                        FileUtil.copy(dataFdagePath, capturePath + File.separator + "/data.fdage", true);
+
+                        panoTargetList.add(target);
+
+                    }
+                }
+            }
+        }
+        return panoTargetList;
+    }
+
+    public Integer publicLinkSceneData(String num){
+
+        String userEditPath = String.format(UploadFilePath.USER_EDIT_PATH, num);
+        String userViewPath = String.format(UploadFilePath.USER_VIEW_PATH, num);
+
+        //生成links.json并上传到发布目录
+        String linkPanKey = String.format(RedisKey.SCENE_LINKPAN_DATA, num);
+        Map<String, String> linkPanMap = redisUtil.hmget(linkPanKey);
+        if(CollUtil.isEmpty(linkPanMap)){
+            return CommonStatus.NO.code().intValue();
+        }
+        List<JSONObject> tags = Lists.newArrayList();
+        List<TagBean> tagBeanList = new ArrayList<>();
+        if(CollUtil.isNotEmpty(linkPanMap)){
+            linkPanMap.entrySet().stream().forEach(entry -> {
+                JSONObject jsonObject = JSON.parseObject(entry.getValue());
+                tagBeanList.add(
+                        TagBean.builder()
+                                .createTime(jsonObject.getLong("createTime"))
+                                .tag(jsonObject).build());
+            });
+            //按创建时间倒叙排序
+            tagBeanList.sort(Comparator.comparingLong(TagBean::getCreateTime).reversed());
+
+            //移除createTime字段
+            tags = tagBeanList.stream().map(tagBean -> {
+                JSONObject tag = tagBean.getTag();
+                tag.remove("createTime");
+                return tag;
+            }).collect(Collectors.toList());
+        }
+        String linkScenePath = userEditPath + "links.json";
+        String linkSceneViewPath = userViewPath + "links.json";
+        fYunFileService.uploadFile(tags.toString().getBytes(StandardCharsets.UTF_8), linkScenePath);
+        fYunFileService.uploadFile(tags.toString().getBytes(StandardCharsets.UTF_8), linkSceneViewPath);
+
+        return CommonStatus.YES.code().intValue();
+    }
+
+    private void addOrUpdateLinPan(String num, String pano, Integer panoId, String sid) throws Exception{
+
+        log.info("开始设置linksjson缓存");
+
+        List<JSONObject> linkPanList = new ArrayList<>();
+        JSONObject linkObj = new JSONObject();
+        linkPanList.add(linkObj);
+        JSONObject styleObj = new JSONObject();
+        linkObj.put("style", styleObj);
+        Map<String, String> enter = new HashMap<>();
+        styleObj.put("enter", enter);
+        enter.put("name", "default");
+        enter.put("url", "");
+        Map<String, String> exit = new HashMap<>();
+        styleObj.put("exit", exit);
+        exit.put("name", "out");
+        exit.put("url", "");
+        linkObj.put("resolution", "2k");
+        linkObj.put("thumb", pano);
+        linkObj.put("title", FileUtil.getPrefix(pano));
+        linkObj.put("type", "pano");
+        linkObj.put("panoId", panoId);
+        linkObj.put("sid", sid);
+
+        Map<String, String> addOrUpdateMap = new HashMap<>();
+        int i = 0;
+        for (JSONObject jsonObject : linkPanList) {
+            jsonObject.put("createTime", Calendar.getInstance().getTimeInMillis() + i++);
+            addOrUpdateMap.put(jsonObject.getString("sid"), jsonObject.toJSONString());
+        }
+
+        //处理新增和修改数据
+        log.info("开始redis缓存inksjson");
+        this.addOrUpdateLinkPanHandler(num, addOrUpdateMap);
+        log.info("结束redis缓存inksjson");
+
+        //场景关联数据备份到本地
+        log.info("开始本地备份inksjson缓存");
+        this.writeLinkScene(num);
+        log.info("结束本地备份inksjson缓存");
+
+        log.info("结束设置linksjson缓存");
+    }
+
+    private void addOrUpdateLinkPanHandler(String num, Map<String, String> addOrUpdateMap){
+        if(CollUtil.isEmpty(addOrUpdateMap))
+            return;
+
+        //批量写入缓存
+        String key = String.format("scene:LinkPan:num:%s", num);
+        log.info("linkjson key : {}", key);
+        log.info("linkjson value : {}", JSON.toJSONString(addOrUpdateMap));
+        redisUtil.hmset(key, addOrUpdateMap);
+    }
+
+    private void writeLinkScene(String num) throws Exception{
+
+        String dataKey = String.format(RedisKey.SCENE_LINKPAN_DATA, num);
+        Map<String, String> tagMap = redisUtil.hmget(dataKey);
+        List<String> tagList = Lists.newArrayList();
+        tagMap.entrySet().stream().forEach(entry->{
+            if(StrUtil.isNotEmpty(entry.getValue())){
+                tagList.add(entry.getValue());
+            }
+        });
+        JSONObject jsonObject = new JSONObject();
+        JSONArray tagJsonArr = new JSONArray();
+        if(CollUtil.isNotEmpty(tagList)){
+            tagList.stream().forEach(linkPan->{
+                tagJsonArr.add(JSONObject.parseObject(linkPan));
+            });
+        }
+        jsonObject.put("tags", tagJsonArr);
+
+        String stylesKey = String.format(RedisKey.SCENE_LINKPAN_STYLES, num);
+        Map<String, String> styleMap = redisUtil.hmget(stylesKey);
+        List<JSONObject> styleList = Lists.newArrayList();
+        if(CollUtil.isNotEmpty(styleMap)){
+            styleMap.values().stream().forEach(style->{
+                styleList.add(JSONObject.parseObject(style));
+            });
+        }
+        jsonObject.put("styles", styleList);
+
+        String linkScenePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "links.json";
+        FileUtil.writeUtf8String(jsonObject.toJSONString(), linkScenePath);
+    }
+
+    private JSONArray getUploadArray(String uploadJsonPath){
+        if(!FileUtil.exist(uploadJsonPath)){
+            throw new RuntimeException("build link pan fail, upload.json is not exist");
+        }
+        String uploadData = FileUtil.readUtf8String(uploadJsonPath);
+        JSONArray array = null;
+        if (StrUtil.isNotEmpty(uploadData)) {
+            JSONObject uploadJson = JSONObject.parseObject(uploadData);
+            array = uploadJson.getJSONArray("upload");
+        }
+
+        if (CollUtil.isEmpty(array)) {
+            throw new RuntimeException("build link pan fail, array is empty");
+        } else {
+            return array;
+        }
+    }
+
+    private void writeVisionTxt(String sid, String target){
+        JSONObject visionJson = new JSONObject();
+        JSONArray visionArray = new JSONArray();
+        visionJson.put("uuid", sid);
+        visionJson.put("group", 1);
+        visionJson.put("subgroup", 0);
+        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);
+    }
+
+    private void writeDataJson(Integer sceneScheme, String sceneResolution, String target){
+        JSONObject floorplanJson = new JSONObject();
+        floorplanJson.put("has_source_images", true);
+        floorplanJson.put("has_vision_txt", true);
+
+        JSONObject dataJson = new JSONObject();
+        dataJson.put("extras", floorplanJson);
+        dataJson.put("split_type", "SPLIT_V8");//替换全景图算法
+
+        String skyboxType = "SKYBOX_V7";//默认2k minion
+        if("4k".equals(sceneResolution)){
+            skyboxType = "SKYBOX_V6";
+        }
+        if(sceneScheme == 3){
+            skyboxType = "SKYBOX_V13";
+            if("4k".equals(sceneResolution)){
+                skyboxType = "SKYBOX_V14";
+            }
+        }
+        dataJson.put("skybox_type", skyboxType);
+        cn.hutool.core.io.FileUtil.writeString(dataJson.toString(), target + File.separator+"data.json", StandardCharsets.UTF_8);
+
+
+
+    }
+}