瀏覽代碼

完成平面图相关功能

wuweihao 3 年之前
父節點
當前提交
1eef9eb3d7

+ 14 - 1
laser/src/main/java/com/fdkankan/indoor/base/constant/CmdConstant.java

@@ -58,11 +58,24 @@ public class CmdConstant {
 
     /**
      * 2021-09-23
-     * 多数据集模型剪切
+     * 英达:多数据集模型剪切
      * bash /home/ubuntu/bin/PotreeConverter.sh "" xxx/xxx.las xxx/merge_cut_param.json"
      * 三个参数,合并裁剪的,第一个参数为空字符串"", 第二个是输出.las路径,第三个是merge_cut_param.json文件路径
      * outPath: 是输出.las路径
      * inPath: merge_cut_param.json文件路径
      */
     public final static String MERGE_CUT_MODEL = "bash /home/ubuntu/bin/PotreeConverter.sh '' @outPath @inPath";
+
+    /**
+     * 2021-09-24
+     * 世超: 平面图切图
+     * 需要参数:
+     *      工作目录
+     *          data.json -> {"split_type":"SPLIT_V15","skybox_type":"SKYBOX_V5"}
+     *          extras
+     *              info.json
+     *              xxx.png
+     * bash /home/ubuntu/bin/Launcher.sh ${工作路径}
+     */
+    public final static String TILED_MAP = "bash /home/ubuntu/bin/Launcher.sh @inPath";
 }

+ 3 - 1
laser/src/main/java/com/fdkankan/indoor/base/convert/quadTree/Solution.java

@@ -151,7 +151,9 @@ public class Solution {
 			}
 		}
 
-		int max = Math.max(maxX, maxY);
+//		int max = Math.max(maxX, maxY);
+		//2021-09-24 加1的原因是从0开始数的
+		int max = Math.max(maxX+1, maxY+1);
 		max = getMaxDepth(max);
 		int[][] numthree = new int[max][max];
 

+ 9 - 9
laser/src/main/java/com/fdkankan/indoor/core/controller/TiledMapController.java

@@ -67,19 +67,19 @@ public class TiledMapController {
         return Result.success();
     }
 
+//    @WebControllerLog(description = "平面图-上传平面图")
+//    @ApiOperation(value = "上传平面图", notes = "只支持zip, 压缩文件不能包含目录")
+//    @PostMapping("indoor/{sceneCode}/api/tiled_maps/upload")
+//    public Result upload(@PathVariable String sceneCode, MultipartFile file){
+//        return entityMap.upload(sceneCode, file);
+//    }
+
+
     @WebControllerLog(description = "平面图-上传平面图")
     @ApiOperation(value = "上传平面图", notes = "只支持zip, 压缩文件不能包含目录")
     @PostMapping("indoor/{sceneCode}/api/tiled_maps/upload")
     public Result upload(@PathVariable String sceneCode, MultipartFile file){
-        return entityMap.upload(sceneCode, file);
-    }
-
-
-    @WebControllerLog(description = "平面图-上传平面图")
-    @ApiOperation(value = "上传平面图2", notes = "只支持zip, 压缩文件不能包含目录")
-    @PostMapping("indoor/{sceneCode}/api/tiled_maps/upload2")
-    public Result upload2(@PathVariable String sceneCode, MultipartFile file){
-        return entityMap.upload(sceneCode, file);
+        return entityMap.upload2(sceneCode, file);
     }
 
     @ApiOperation(value = "下载平面图", notes = "下载zip包, 前端自己拼接oss域名")

+ 3 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/dto/TiledMapDto.java

@@ -64,6 +64,9 @@ public class TiledMapDto {
 
     private String type;
 
+    @ApiModelProperty(value = "场景码")
+    private String sceneCode;
+
 
 
 }

+ 4 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/TiledMapService.java

@@ -37,4 +37,8 @@ public interface TiledMapService {
     Result upload(String sceneCode, MultipartFile file);
 
     Result download(String sceneCode);
+
+    Result upload2(String sceneCode, MultipartFile file);
+
+    void removeMerge(String sceneCode, String mergeCode);
 }

+ 13 - 14
laser/src/main/java/com/fdkankan/indoor/core/service/impl/InitServiceImpl.java

@@ -23,6 +23,7 @@ import lombok.extern.slf4j.Slf4j;
 import net.sf.json.JSONArray;
 import net.sf.json.JSONObject;
 import org.junit.Test;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -113,28 +114,27 @@ public class InitServiceImpl implements InitService {
             throw new BaseRuntimeException("场景码不能为空");
         }
 
-        String path = param.getPath();
-        String title = param.getTitle();
-
         // 防止为四维看看重复调用重算
         InitEntity init = findById(sceneCode);
         if (init != null) {
             log.info("初始化数据已存在: {}", sceneCode);
             // 重算
-
             if ("recount".equals(from)) {
                 log.info("进行手动重新");
-//                path = init.getPath();
-//                title = init.getTitle();
-
+            } else {
+                log.info("算法重算");
+                init.setPath(param.getPath());
+                init.setTitle(param.getTitle());
+                init.setUpdateTime(LocalDateTime.now());
+                initMapper.save(init);
             }
         } else {
             // 新场景
             init = new InitEntity();
             init.setId(sceneCode);
-            init.setPath(path);
+            init.setPath(param.getPath());
             init.setCreateTime(LocalDateTime.now());
-            init.setTitle(title);
+            init.setTitle(param.getTitle());
             init.setChildName(param.getChildName());
             init.setSnCode(param.getSnCode());
             init.setShootTime(param.getCreateTime());
@@ -151,8 +151,8 @@ public class InitServiceImpl implements InitService {
         // 删除旧数据, 重算使用
         initRemove(sceneCode);
 
-        path = init.getPath();
-        title = init.getTitle();
+        String path = init.getPath();
+        String title = init.getTitle();
         // 路径在这里检测
         if (StrUtil.isBlank(path)) {
             throw new BaseRuntimeException("init.path路径不能为空");
@@ -209,10 +209,8 @@ public class InitServiceImpl implements InitService {
         }
 
 
+        // 2021-09-23 地址需要更新
         init.setUpdateTime(LocalDateTime.now());
-        init.setTitle(title);
-        // 2021-09-23 旧场景地址需要更新
-        init.setPath(param.getPath());
         Integer recount = init.getRecount();
         recount = recount == null ? 1 : recount + 1;
         init.setRecount(recount);
@@ -355,6 +353,7 @@ public class InitServiceImpl implements InitService {
         InitDto initDto = new InitDto();
         initDto.setSceneCode(sceneCode);
         initDto.setFrom("recount");
+
         this.initData(initDto);
 
 

+ 7 - 71
laser/src/main/java/com/fdkankan/indoor/core/service/impl/MergeSceneServiceImpl.java

@@ -74,75 +74,7 @@ public class MergeSceneServiceImpl extends IBaseServiceImpl implements MergeScen
     @Autowired
     ControlPointCalculateService controlPointCalculateService;
 
-    /**
-     * 目前只支持没有合并过的场景
-     * @param sceneCode
-     * @param mergeCode
-     * @return
-     */
-//    @Override
-//    public Result merge(String sceneCode, String mergeCode) {
-//
-//        List<MergeInfoEntity> mergeList =  mergeInfoService.findByMergeCode(mergeCode);
-//        if (mergeList.size() > 0) {
-//            Result.failure("此场景已合并:" + mergeCode);
-//        }
-//
-//
-//        ControlPointCalculateEntity controlPoint = controlPointCalculateService.findById(sceneCode);
-//
-//        if (controlPoint == null) {
-//            String msg = "控制点计算表结果不存在,尝试重算解决";
-//            log.error(msg);
-//            return Result.failure(msg);
-//        }
-//
-//        InitEntity initEntity = initService.findById(mergeCode);
-//
-//        String mergePath = "";
-//
-//        if ("dev".equals(configConstant.active)) {
-//            mergePath = configConstant.serverBasePath  + "/" + mergeCode + "/results/laserData";
-//        } else {
-//            mergePath = redisPath(mergeCode) + "/laserData";
-//        }
-//        log.info("合并场景路径:{}", mergePath);
-//
-//        // siteMode要优先处理;
-//        Map<Object, Object> resMap = mergeSiteModelFloor(sceneCode, mergeCode, mergePath, controlPoint);
-//
-//        Integer siteModelId = (Integer)resMap.get("maxId");
-//
-//        // dateSet.siteModelId是数组, 如果siteModel的模板id改了,这里要重新设置
-//        List<Integer> siteModeIds = Arrays.asList(10, siteModelId);
-//        Integer dataSetId = mergeDateSet(sceneCode, mergeCode, siteModeIds, mergePath, controlPoint.getRotation2());
-//
-//
-//        mergeFilter(sceneCode, mergeCode, controlPoint, mergePath, siteModelId, dataSetId);
-//
-//        // 合并平面图
-//        mergeTileMap(sceneCode, mergeCode, siteModelId, mergePath);
-//
-//        // 上传数据到oss:目录pano、pano_depth、webcloud上传oss 外层目录以场景码命名
-//        // todo 本地测试,注释上传oss
-//        if (!"dev".equals(configConstant.active)) {
-//            initService.ossUploadDirByLaserData(sceneCode, mergePath, mergeCode);
-//        }
-//        log.info("文件上传oss完成, 合并数据完成");
-//
-//        // 保存合并信息
-//        MergeInfoEntity entity = new MergeInfoEntity();
-//        entity.setDataSetId(dataSetId);
-//        entity.setMergeCode(mergeCode);
-//        entity.setSiteModelId(siteModelId);
-//        entity.setTitle(initEntity.getTitle());
-//        entity.setPath(mergePath);
-//        entity.setSceneCode(sceneCode);
-//        saveMergeInfo(entity);
-//
-//
-//        return Result.success();
-//    }
+
 
     /**
      *
@@ -300,10 +232,15 @@ public class MergeSceneServiceImpl extends IBaseServiceImpl implements MergeScen
         dataSetService.save(dataSetentity);
         log.info("dataSet数据删除完成, dataSetId:{}", dataSetId);
 
+
         // 删除合并信息
         mergeInfoService.removeSceneCodeAndMergeCode(sceneCode, mergeCode);
         log.info("mergeInfo数据删除完成, mergeCode:{}", mergeCode);
 
+        // 2021-09-24 删除合并的tiledMap平面图数据
+        tiledMapService.removeMerge(sceneCode, mergeCode);
+
+
         return Result.success();
     }
 
@@ -818,9 +755,7 @@ public class MergeSceneServiceImpl extends IBaseServiceImpl implements MergeScen
     private SiteDto initSiteModelFloor(String sceneCode){
         SiteDto dto = new SiteDto();
         dto.setType("FLOOR");
-//        dto.setName("合并FLOOR_" + sceneCode);
         dto.setName(sceneCode);
-//        dto.setArea(2503.30551910935);
         dto.setVolume(295513.21880627);
         dto.setGeometry_hash(-200081285L);
         return dto;
@@ -878,6 +813,7 @@ public class MergeSceneServiceImpl extends IBaseServiceImpl implements MergeScen
             maxTiledMapId ++;
             mapDto.setId(maxTiledMapId);
             mapDto.setFloor_id(modelSiteId);
+            mapDto.setSceneCode(mergeCode);
             // 使用被合并的场景码做目录
             mapDto.setFile_path("data/bundle_" + mergeCode +"/building_1/map_tiles/" + mapDto.getFloor_id());
 

+ 6 - 1
laser/src/main/java/com/fdkankan/indoor/core/service/impl/PoiServiceImpl.java

@@ -228,6 +228,11 @@ public class PoiServiceImpl extends IBaseServiceImpl implements PoiService {
     public Result filter(String sceneCode, PoiQueryDto param) {
         List<PoiHotDto> data = findDataBySceneCode(sceneCode);
 
+        if (data.size() == 0){
+            log.info("热点为空");
+            return Result.success();
+        }
+
         // 返回dataset对应的热点
         if (param.getDataset() != null) {
             List<Integer> dataset = param.getDataset();
@@ -242,8 +247,8 @@ public class PoiServiceImpl extends IBaseServiceImpl implements PoiService {
 
 
         List<Integer> siteModelIds = param.getSite_model_entity();
-        List<Integer> poiTypeIds = param.getPoi_type();
 
+        List<Integer> poiTypeIds = param.getPoi_type();
         if (siteModelIds.size() == 0 || poiTypeIds.size() == 0) {
             return  Result.success();
         }

+ 143 - 7
laser/src/main/java/com/fdkankan/indoor/core/service/impl/TiledMapServiceImpl.java

@@ -1,6 +1,8 @@
 package com.fdkankan.indoor.core.service.impl;
 
+import cn.hutool.core.img.ImgUtil;
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.ZipUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -23,12 +25,14 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
 /**
  * Created by owen on 2021/7/28 0028 20:05
@@ -61,6 +65,13 @@ public class TiledMapServiceImpl extends IBaseServiceImpl implements TiledMapSer
         return null;
     }
 
+    /**
+     * 平面图初始化
+     * 初始化是使用平面图是: /laserData/cover
+     * 修改上传使用的工作目录是:/results/laserData/cover
+     * @param sceneCode
+     * @param from
+     */
     @Override
     public void init(String sceneCode, String from) {
         TiledMapEntity entity = findById(sceneCode);
@@ -168,11 +179,119 @@ public class TiledMapServiceImpl extends IBaseServiceImpl implements TiledMapSer
      */
     @Override
     public Result download(String sceneCode) {
-        String basePath =  "data/" + sceneCode + "/upload_cover/cover.zip";
+        String basePath =  "data/" + sceneCode + "/download/final_freespace.png";
         return Result.success(basePath);
     }
 
     @Override
+    public Result upload2(String sceneCode, MultipartFile file) {
+
+        // 只接受png格式
+        String originalFilename = file.getOriginalFilename();
+        originalFilename = originalFilename.toLowerCase();
+        if (!originalFilename.endsWith(".png")){
+            return Result.failure("文件格式有误, 只接收png图片");
+        }
+
+        // 只接受info.json里的图片大小尺寸
+        String basePath = redisPath(sceneCode);
+
+        // 全景图工作目录
+        String tiledBasePath = StrUtil.subBefore(basePath, "/laserData", true);
+
+        String infoPath = tiledBasePath +  "/extras/info.json";
+        if (!FileUtil.exist(infoPath)){
+            String msg = "info.json文件不存在, 请检查";
+            log.error(msg + ": " +infoPath);
+            return Result.failure(msg);
+        }
+
+        String info = FileUtil.readUtf8String(infoPath);
+        JSONObject infoJ = JSONObject.parseObject(info);
+        JSONObject resolution = infoJ.getJSONObject("resolution");
+        Integer width = resolution.getInteger("width");
+        Integer height = resolution.getInteger("height");
+
+        BufferedImage read = null;
+        String tiledMapPath = tiledBasePath + "/extras/final_freespace.png";
+        try {
+
+            FileUtil.writeFromStream(file.getInputStream(), tiledMapPath);
+
+            read = ImgUtil.read(tiledMapPath);
+            int widthImg = read.getWidth();
+            int heightImg = read.getHeight();
+            if (width != widthImg || height != heightImg) {
+                String msg = "上传图片尺寸跟原图不一致";
+                log.error(msg + ", width:{}, height:{}, widthImg:{}, heightImg:{}" , width, height,widthImg, heightImg);
+                return Result.failure(msg);
+            }
+
+            // 调用算法切图
+            cmdTiledMap(tiledBasePath);
+
+            // 上传平面图到download目录
+            uplodaOss(tiledBasePath, sceneCode);
+            return Result.success();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    /**
+     * 2021-09-24
+     * 这里使用路径判断场景码删除
+     * 删除合并的平面图信息
+     * @param sceneCode
+     * @param mergeCode
+     */
+    @Override
+    public void removeMerge(String sceneCode, String mergeCode) {
+        TiledMapEntity mapEntity = findById(sceneCode);
+        List<TiledMapDto> data = mapEntity.getData();
+        data = data.stream().filter(p -> !p.getFile_path().contains(mergeCode)).collect(Collectors.toList());
+
+        mapEntity.setData(data);
+        this.save(mapEntity);
+
+    }
+
+    /**
+     * 切图上传oss
+     * @param tiledBasePath
+     * @param sceneCode
+     */
+    private void uplodaOss(String tiledBasePath, String sceneCode){
+        String tiledMapPath = tiledBasePath + "/results/laserData/cover/final_freespace.png";
+//        String tiledMaptInfoPath = tiledBasePath + "/results/laserData/cover/info.json";
+
+        // 提供前端下载使用
+        String ossTiledMap = "data/" + sceneCode + "/download/final_freespace.png";
+        aliYunOssUtil.upload(tiledMapPath, ossTiledMap);
+
+        // 上传切片后的平面图
+        String uploadDir = tiledBasePath + "/results/laserData/cover";
+        uploadDiyCover(sceneCode, uploadDir );
+        log.info("切图上传oss完成");
+
+    }
+
+    /**
+     * 平面图算法调用
+     * @param inPath 工作目录
+     */
+    private void cmdTiledMap(String inPath){
+        String cmd = CmdConstant.TILED_MAP;
+        cmd = cmd.replace("@inPath", inPath);
+        CmdUtils.callLineSh(cmd, 50);
+        log.info("平面图算法调用完成");
+    }
+
+
+
+    @Override
     public void remove(String sceneCode) {
         entityMapper.deleteById(sceneCode);
     }
@@ -338,6 +457,7 @@ public class TiledMapServiceImpl extends IBaseServiceImpl implements TiledMapSer
         dto.setQuadtree(quadTree);
         dto.setType("TILED_PYRAMID");
         dto.setTile_size_px(256);
+        dto.setSceneCode(sceneCode);
 
         dto.setMap_size_m(mapSize_m);
         // 使用dataSet.location
@@ -356,11 +476,24 @@ public class TiledMapServiceImpl extends IBaseServiceImpl implements TiledMapSer
         String ossTarget = "data/" + sceneCode + "/" + dto.getFile_path();
         String uploadDir = path + "/cover";
         ossUploadDir(ossTarget, uploadDir);
-        // 压缩并上传oss
-        zipAndUploadOss(path, uploadDir, sceneCode);
+        // 压缩并上传oss提供下载
+//        zipAndUploadOss(path, uploadDir, sceneCode);
+        tiledMapUploadOss(path, sceneCode);
 
         return list;
+    }
 
+    /**
+     * 长传平面图提供下载
+     * @param basePath
+     * @param sceneCode
+     */
+    private void tiledMapUploadOss(String basePath, String sceneCode){
+        String tiledMapPath = basePath + "/cover/final_freespace.png";
+        // 提供前端下载使用
+        String ossTiledMap = "data/" + sceneCode + "/download/final_freespace.png";
+        aliYunOssUtil.upload(tiledMapPath, ossTiledMap);
+        log.info("平面图上传完成");
     }
 
 
@@ -387,7 +520,6 @@ public class TiledMapServiceImpl extends IBaseServiceImpl implements TiledMapSer
 
     // 将cover上传oss
     private void uploadCover(String sceneCode){
-//        String path = redisPath(sceneCode) + "/laserData";
         String path = redisPath(sceneCode) ;
         // 11=floor_id值:site_model.type:floor的id
         String bundlePath = "data/bundle_" + sceneCode +"/building_1/map_tiles/11";
@@ -396,7 +528,8 @@ public class TiledMapServiceImpl extends IBaseServiceImpl implements TiledMapSer
         ossUploadDir(ossTarget, uploadDir);
 
         // 压缩并上传oss
-        zipAndUploadOss(path, uploadDir, sceneCode);
+//        zipAndUploadOss(path, uploadDir, sceneCode);
+        tiledMapUploadOss(path, sceneCode);
 
     }
 
@@ -451,7 +584,10 @@ public class TiledMapServiceImpl extends IBaseServiceImpl implements TiledMapSer
 //        String out = "F:\\test\\ngin\\age_laser_data\\w-60\\results\\laserData\\1\\cover.zip";
         // 有个bug, 如果路径中是以压缩包前缀命名包含在路径斜杠后面中会出错
         String out = "F:\\test\\ngin\\age_laser_data\\w-60\\results\\laserData\\upload_cover\\cover.zip";
-        ZipUtil.zip(new File(out), false, new File(filePath));
-    }
+//        ZipUtil.zip(new File(out), false, new File(filePath));
+
+        System.out.println(out.contains("w-60"));
+        System.out.println("w-60".contains(out));
+}
 
 }