wuweihao 4 rokov pred
rodič
commit
e3c67ec4ea

+ 5 - 1
README.md

@@ -119,4 +119,8 @@ t-p307mDm
 # 登录体系
    共用四维看看登录体系
  
-             
+# 流程
+  
+  2021-8-24
+  前端上传点云数据 -> 调用算法 -> 按顺序生成chunk1、chunk2目录 -> 将chunk1目录上传oss -> 修改dateSet、siteModel表, 跟cloud.js相关的数据都修改一遍
+  -> siteModel 加一个房间  -> dataSet加一条数据           

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

@@ -33,8 +33,14 @@ public class CmdConstant {
     /**
      * 2021-08-17
      * 剪切模型命令, 这个需要在nas共享目录, 测试服务器,跟算法服务器是分开的
-     * bash /home/ubuntu/bin/PotreeConverter.sh /mnt/data/00001002/872819408496492544/74ee2a39e656_202108051135248650/results/laserData/laser.las /mnt/data/owen_test/indoor_cut.las /mnt/data/owen_test/cut_param.json
+     * bash /home/ubuntu/bin/PotreeConverter.sh /mnt/data/00001002/872819408496492544/74ee2a39e656_202108051135248650/results/laserData/laser.las /mnt/data/00001002/872819408496492544/74ee2a39e656_202108051135248650/results/laserData/indoor_cut.las /mnt/data/00001002/872819408496492544/74ee2a39e656_202108051135248650/results/laserData/cut_param.json
      * bash /home/ubuntu/bin/PotreeConverter.sh inPath outPath inCutParam;
      */
     public final static String CUT_MODEL = "bash /home/ubuntu/bin/PotreeConverter.sh @inPath @outPath @cutParam";
+
+    /**
+     * las to bin
+     * bash /home/ubuntu/bin/PotreeConverter.sh /mnt/data/00001002/872819408496492544/74ee2a39e656_202108051135248650/results/laserData/laser.las /mnt/data/00001002/872819408496492544/74ee2a39e656_202108051135248650/results/laserData
+     */
+    public final static String LAS_TO_BIN = "bash /home/ubuntu/bin/PotreeConverter.sh @inPath @outPath";
 }

+ 15 - 6
laser/src/main/java/com/fdkankan/indoor/base/convert/GetRoute.java

@@ -209,9 +209,15 @@ public class GetRoute {
 //			path.add(node);
 //		}
 
+		// 点的距离
 		for(int i = mappath.size()-1;i>-1;) {
 			Node node = mappath.get(i);
-			i -= 3;
+			if(mappath.size()>4){
+				i -= 3;
+			}
+			else{
+				--i;
+			}
 			path.add(node);
 		}
 
@@ -264,6 +270,10 @@ public class GetRoute {
 
 			JSONObject instruction = null;
 
+			virtualEndPosition[0] = node.coord.x;
+			virtualEndPosition[1] = node.coord.y;
+			virtualEndPosition[2] = node.coord.z;
+
 			if(i == 0) {
 				item.put("distance", g_AStar.calcH(node.coord,new Coord(startX,startY,startZ)));
 				item.put("distance_to_previous", g_AStar.calcH(node.coord,new Coord(startX,startY,startZ)));
@@ -272,8 +282,7 @@ public class GetRoute {
 				instruction = new JSONObject();
 				instruction.put("type", "source_projection_to_navgraph");
 				item.put("instruction", instruction);
-			}
-			else {
+			} else {
 				Node prenode = path.get(i-1);
 				JSONObject preitem = route.getJSONObject(i);
 				Double distance_to_previous = g_AStar.calcH(node.coord,prenode.coord);
@@ -285,9 +294,9 @@ public class GetRoute {
 					instruction.put("type", "destination_projection_to_navgraph");
 					item.put("instruction", instruction);
 
-					virtualEndPosition[0] = node.coord.x;
-					virtualEndPosition[1] = node.coord.y;
-					virtualEndPosition[2] = node.coord.z;
+//					virtualEndPosition[0] = node.coord.x;
+//					virtualEndPosition[1] = node.coord.y;
+//					virtualEndPosition[2] = node.coord.z;
 
 				}
 				else {

+ 32 - 0
laser/src/main/java/com/fdkankan/indoor/core/controller/CloudController.java

@@ -0,0 +1,32 @@
+package com.fdkankan.indoor.core.controller;
+
+import com.fdkankan.indoor.base.aop.WebControllerLog;
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.core.service.CloudService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * Created by owen on 2021/8/24 0024 18:23
+ */
+@Api(tags = "cloud-点云")
+@RestController
+public class CloudController {
+
+    @Autowired
+    CloudService entityService;
+
+    @WebControllerLog(description = "cloud点云-上传点云")
+    @ApiOperation(value = "上传图标")
+    @PostMapping("indoor/{sceneCode}/cloud/upload")
+    public Object upload(@PathVariable String sceneCode, MultipartFile file){
+        Result result = entityService.upload(sceneCode, file);
+        return result.getData();
+    }
+
+}

+ 12 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/CloudService.java

@@ -0,0 +1,12 @@
+package com.fdkankan.indoor.core.service;
+
+import com.fdkankan.indoor.base.util.Result;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * Created by owen on 2021/8/24 0024 18:26
+ */
+public interface CloudService {
+
+    Result upload(String sceneCode, MultipartFile file);
+}

+ 253 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/impl/CloudServiceImpl.java

@@ -0,0 +1,253 @@
+package com.fdkankan.indoor.core.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.fdkankan.indoor.base.constant.TypeConstant;
+import com.fdkankan.indoor.base.convert.ModifyCloud;
+import com.fdkankan.indoor.base.util.Result;
+import com.fdkankan.indoor.base.util.SnowFlakeUUidUtils;
+import com.fdkankan.indoor.core.entity.ControlPointEntity;
+import com.fdkankan.indoor.core.entity.SiteModelEntity;
+import com.fdkankan.indoor.core.entity.SpecialPointEntity;
+import com.fdkankan.indoor.core.entity.dto.SiteDto;
+import com.fdkankan.indoor.core.entity.dto.SitePolygon;
+import com.fdkankan.indoor.core.service.CloudService;
+import com.fdkankan.indoor.core.service.SiteService;
+import com.fdkankan.indoor.core.service.SpecialPointService;
+import lombok.extern.slf4j.Slf4j;
+import net.sf.json.JSONArray;
+import net.sf.json.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * Created by owen on 2021/8/24 0024 18:26
+ */
+@Service
+@Slf4j
+public class CloudServiceImpl extends IBaseServiceImpl implements CloudService {
+
+    @Autowired
+    SpecialPointService specialPointService;
+
+    @Autowired
+    SiteService siteService;
+
+
+    @Override
+    public Result upload(String sceneCode, MultipartFile file) {
+
+        // step1: 长传点云到nas目录
+        if (file == null) {
+            throw new RuntimeException("文件为空");
+        }
+        String originalFilename = file.getOriginalFilename();
+        String suffix = StrUtil.subAfter(originalFilename, ".", true);
+
+//        String newName = DateUtil.format(LocalDateTime.now(), "yyyyMMdd_HHmmssSSS");
+        UUID uuid = UUID.randomUUID();
+        String newName = "poi-" + uuid + "." + suffix;
+
+        String urlPath = "/" + sceneCode + "/poi/image/" + newName;
+        String savePath = configConstant.serverBasePath + urlPath;
+        log.info("保存图片路径:{}", savePath);
+        try {
+            FileUtil.writeFromStream(file.getInputStream(), savePath);
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        // step2: 调用算法,生成网络点云数据。目录是根目录/chunk1 数字递增
+
+        // step3: 上传网络点云到oss
+
+
+
+        return Result.success();
+    }
+
+    /**
+     * 处理上传的点云数据:siteModel -> 原点、中心点、最大点、最小点
+     * @param sceneCode 场景码
+     * @param laserDataPath 基础路径
+     * @param controlPoint 控制点
+     */
+    private void processCoule(String sceneCode, String laserDataPath, ControlPointEntity controlPoint){
+       String path = laserDataPath + "/webcloud/cloud.js";
+        // 处理原点,将原点坐标转为坐标, 转换后的原点只有经纬度,没有高度, 高度现在默认是0
+        double[] doubles = ModifyCloud.convertFromOrigin(controlPoint);
+        // 2021-08-4 原点默认 z:0
+        Double[] gpsOrigin = {doubles[0] ,doubles[1], 0.0};
+        // 将数据保存到db, dateSet数据location使用
+        saveSpecialPoint(sceneCode, TypeConstant.POI_ORIGIN, null, gpsOrigin);
+        log.info("原点保存成功");
+
+        try {
+            // 修改cloud.js文件
+            JSONObject info = ModifyCloud.fixCloud(path);
+
+            cn.hutool.core.io.FileUtil.writeUtf8String(info.toString(), path);
+            log.info("新的cloud.js写入服务器完成:{}", path);
+
+            /**
+             * 将boundingBox坐标转换成gis坐标, site_model需要
+             * boundingBox:虚拟点坐标,存特殊点, dataSet数据要使用
+             */
+            JSONObject boundingBox = ModifyCloud.getBoundingBox(info);
+            Double maxX = boundingBox.getDouble("maxX");
+            Double maxY = boundingBox.getDouble("maxY");
+            Double maxZ = boundingBox.getDouble("maxZ");
+
+            Double minX = boundingBox.getDouble("minX");
+            Double minY = boundingBox.getDouble("minY");
+            Double minZ = boundingBox.getDouble("minZ");
+
+            Double centreX = boundingBox.getDouble("centreX");
+            Double centreY = boundingBox.getDouble("centreY");
+            Double centreZ = boundingBox.getDouble("centreZ");
+
+
+            // 虚拟点坐标(四维看看坐标)
+            Double[] ageMax = {maxX,maxY,maxZ};
+            Double[] ageMin = {minX,minY,minZ};
+            Double[] ageCentre = {centreX,centreY,centreZ};
+
+            JSONObject resJson = ModifyCloud.convertFromBoundingBox(boundingBox, controlPoint);
+
+            Double[] gpsMax = getKey(resJson, "max");
+            Double[] gpsMin = getKey(resJson, "min");
+            Double[] gpsCentre = getKeyZ(resJson, "centre");
+
+            // 将数据保存到db
+            saveSpecialPoint(sceneCode, TypeConstant.POI_BOUNDINGBOX_MAX, ageMax, gpsMax);
+            saveSpecialPoint(sceneCode, TypeConstant.POI_BOUNDINGBOX_MIN, ageMin, gpsMin);
+            saveSpecialPoint(sceneCode, TypeConstant.POI_CENTRE, ageCentre, gpsCentre);
+            log.info("max、min、中心点保存成功");
+
+
+            // 创建sitModel
+            createSiteModel(sceneCode, gpsMax, gpsMin, gpsCentre, maxZ, minZ);
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    /**
+     * 获取两个值的
+     * json数组转 double[]
+     * @param resJson
+     * @param key
+     * @return
+     */
+    private Double[] getKey(JSONObject resJson , String key){
+        JSONArray array = resJson.getJSONArray(key);
+        Double[] res = {array.getDouble(0), array.getDouble(1)};
+        return res;
+    }
+
+    /**
+     * 获取三个值的
+     * @param resJson
+     * @param key
+     * @return
+     */
+    private Double[] getKeyZ(JSONObject resJson , String key){
+        JSONArray array = resJson.getJSONArray(key);
+        Double[] res = {array.getDouble(0), array.getDouble(1), array.getDouble(2)};
+        return res;
+    }
+
+
+
+    /***
+     * 保存特质点
+     * @param sceneCode 场景码
+     * @param poiKey key
+     * @param agePoi 虚拟点坐标(四维看看坐标)
+     */
+    private void saveSpecialPoint(String sceneCode, String poiKey, Double[] agePoi, Double[] gpsPoi){
+        SpecialPointEntity entity = new SpecialPointEntity();
+        entity.setId(SnowFlakeUUidUtils.getUuid("SP"));
+        entity.setUpdateTime(LocalDateTime.now());
+        entity.setSceneCode(sceneCode);
+        entity.setPoiKey(poiKey);
+        entity.setPoi(agePoi);
+        entity.setGpsPoi(gpsPoi);
+        specialPointService.save(entity);
+    }
+
+    private void createSiteModel(String sceneCode,  Double[] max,  Double[] min,  Double[] centre, Double maxZ, Double minZ){
+        //读取初始文件
+        String content = cn.hutool.core.io.FileUtil.readUtf8String(configConstant.templatePath + "/site_model.json");
+        List<SiteDto> siteModels = JSON.parseArray(content, SiteDto.class);
+        // z_max、z_min 替换site_model的Floor、root类型
+        // max、min四个顶点替换BUILDING、FLOOR 的coordinates,
+        // 顺时针,(x_max,y_max),(x_max,y_min),(x_min,y_min),(x_min,y_max)
+        // 一般参数1:x, 参数2:Y
+        Double[] peak_1 = {max[0],max[1]};
+        Double[] peak_2 = {max[0],min[1]};
+        Double[] peak_3 = {min[0],min[1]};
+        Double[] peak_4 = {min[0],max[1]};
+        List<List<Double[]>> doubles = Arrays.asList(Arrays.asList(peak_1, peak_2, peak_3, peak_4));
+
+        // centre 替换BUILDING、FLOOR、ROOM 的center
+        log.info("中心点:{}, {}, {}", centre[0], centre[1], centre[2]);
+        siteModels.forEach(p -> {
+            // 第一层:BUILDING,处理centre、coordinates
+            p.setCenter(centre);
+            SitePolygon polygon = p.getPolygon();
+
+            //  BUILDING. coordinates, max、min四个顶点替换
+            polygon.setCoordinates(doubles);
+
+            // 第二层:FLOOR 层
+            List<SiteDto> children = p.getChildren();
+            if (children.size() > 0) {
+                children.forEach(c ->{
+                    c.setCenter(centre);
+                    c.setZ_max(maxZ);
+                    c.setZ_min(minZ);
+
+                    // 第三层: ROOM层
+                    List<SiteDto> roomChildren = c.getChildren();
+                    if (roomChildren.size() > 0) {
+                        roomChildren.forEach(r -> {
+                            r.setCenter(centre);
+                            r.setZ_max(maxZ);
+                            r.setZ_min(minZ);
+                            SitePolygon rPolygon = r.getPolygon();
+                            rPolygon.setCoordinates(doubles);
+                        });
+                    }
+                });
+            }
+
+        });
+
+        log.info("siteMode数据解析完成");
+        SiteModelEntity modelEntity = siteService.findById(sceneCode);
+        if (modelEntity != null) {
+            siteService.remove(sceneCode);
+            log.info("删除旧siteModel数据完成");
+        }
+        SiteModelEntity entity = new SiteModelEntity();
+        entity.setId(sceneCode);
+        entity.setCreateTime(LocalDateTime.now());
+        // 默认热点为空
+        entity.setData(siteModels);
+        siteService.save(entity);
+        log.info("siteModel数据初始化创建完成");
+    }
+}

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

@@ -1,5 +1,6 @@
 package com.fdkankan.indoor.core.service.impl;
 
+import com.fdkankan.indoor.base.exception.BaseRuntimeException;
 import com.fdkankan.indoor.base.util.Result;
 import com.fdkankan.indoor.core.entity.ConfigEntity;
 import com.fdkankan.indoor.core.entity.dto.ConfigDto;
@@ -36,6 +37,9 @@ public class ConfigServiceImpl extends IBaseServiceImpl implements ConfigService
     @Override
     public Result getById(String sceneCode) {
         ConfigEntity entity = findById(sceneCode);
+        if (entity == null) {
+            throw new BaseRuntimeException("config表数据不存在: " + sceneCode);
+        }
         List<ConfigDto> data = entity.getData();
 
         List<ConfigDto> result = new ArrayList<>();

+ 9 - 2
laser/src/main/java/com/fdkankan/indoor/core/service/impl/PoiServiceImpl.java

@@ -267,10 +267,17 @@ public class PoiServiceImpl extends IBaseServiceImpl implements PoiService {
             return result;
     }
 
-
+    /**
+     * 匹配查询
+     * @param p
+     * @param searchKey
+     * @return
+     */
     private Boolean getContent(PoiHotDto p, String searchKey){
         String titles = p.getTitles().getZh();
-//        log.info("titles: {}, 配备结果:{}", titles, titles.contains(searchKey));
+        if (titles == null) {
+            return false;
+        }
         return titles.contains(searchKey);
     }
 

+ 1 - 1
laser/src/main/resources/application.properties

@@ -10,7 +10,7 @@ logging.level.com.fdkankan=info
 
 # \uFFFD\uFFFD\u013F\uFFFD\uFFFD\uFFFD\uFFFD
 project.en=age_camera_germany
-project.sc=\u5FB7\u56FD\u6FC0\u5149\u76F8\u673A
+project.sc=\u6FC0\u5149\u76F8\u673A
 
 #\u4E0A\u4F20\u6587\u4EF6\u5927\u5C0F
 spring.servlet.multipart.enabled=true