Quellcode durchsuchen

route合并完成

wuweihao vor 4 Jahren
Ursprung
Commit
9abb17a25b
25 geänderte Dateien mit 1031 neuen und 133 gelöschten Zeilen
  1. 78 0
      laser/src/main/java/com/fdkankan/indoor/base/convert/FixRouteMap.java
  2. 47 0
      laser/src/main/java/com/fdkankan/indoor/base/convert/GisCoordinateUtil.java
  3. 143 15
      laser/src/main/java/com/fdkankan/indoor/base/convert/MergeRouteMap.java
  4. 4 2
      laser/src/main/java/com/fdkankan/indoor/base/convert/ModifyDataSets.java
  5. 148 0
      laser/src/main/java/com/fdkankan/indoor/base/convert/PlanGraph.java
  6. 6 3
      laser/src/main/java/com/fdkankan/indoor/base/convert/TransformGPS.java
  7. 24 0
      laser/src/main/java/com/fdkankan/indoor/base/convert/quadTree/Node.java
  8. 203 0
      laser/src/main/java/com/fdkankan/indoor/base/convert/quadTree/Solution.java
  9. 5 4
      laser/src/main/java/com/fdkankan/indoor/core/controller/ControlPointController.java
  10. 18 4
      laser/src/main/java/com/fdkankan/indoor/core/controller/DateSetController.java
  11. 37 37
      laser/src/main/java/com/fdkankan/indoor/core/controller/PoseController.java
  12. 6 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/ControlPointEntity.java
  13. 31 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/dto/ControlPointDto.java
  14. 6 0
      laser/src/main/java/com/fdkankan/indoor/core/entity/merge/MergeDateSetDto.java
  15. 2 0
      laser/src/main/java/com/fdkankan/indoor/core/mapper/MergeInfoMapper.java
  16. 4 1
      laser/src/main/java/com/fdkankan/indoor/core/service/ControlPointService.java
  17. 2 0
      laser/src/main/java/com/fdkankan/indoor/core/service/DataSetService.java
  18. 2 0
      laser/src/main/java/com/fdkankan/indoor/core/service/MergeInfoService.java
  19. 41 14
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/ControlPointServiceImpl.java
  20. 138 43
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/DataSetServiceImpl.java
  21. 29 5
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/InitServiceImpl.java
  22. 5 0
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/MergeInfoServiceImpl.java
  23. 19 2
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/MergeSceneServiceImpl.java
  24. 21 3
      laser/src/main/java/com/fdkankan/indoor/core/service/impl/TiledMapServiceImpl.java
  25. 12 0
      laser/src/main/java/com/fdkankan/indoor/test/Demo.java

+ 78 - 0
laser/src/main/java/com/fdkankan/indoor/base/convert/FixRouteMap.java

@@ -109,6 +109,84 @@ public class FixRouteMap {
     }
 
     /**
+     * 旋转平移
+     * @param orientation
+     * @param gpsLocation
+     * @param controlPoint
+     * @param path
+     * @return
+     * @throws Exception
+     */
+    public static  List<JSONObject> getRotate(double orientation, double[] gpsLocation, ControlPointEntity controlPoint, String path)  {
+
+        // dataSet.location的gps坐标转本地坐标
+        double[] ageLocation = GisCoordinateUtil.convertGpsToLocation(gpsLocation, controlPoint);
+
+        // 新的本地坐标, 转出来应该是原点, 很接近0
+        JSONObject newLocation = new JSONObject();
+        newLocation.put("x", ageLocation[0]);
+        newLocation.put("y", ageLocation[1]);
+        newLocation.put("z", gpsLocation[2]);
+        log.info("newLocation: {}", newLocation );
+
+
+        double[] newMatrix = getTransfromMatrix(orientation, newLocation);
+
+
+        // 读取棋盘的坐标,读文件final_freespace.csv,不要读数据库,最初的坐标
+        String routePath = path + "/final_freespace.csv";
+        log.info("routePath: {}", routePath);
+        if (!cn.hutool.core.io.FileUtil.isFile(routePath)){
+            log.info("输入路径有误, path: {}", routePath);
+            throw new BaseRuntimeException(MsgCode.e3001, "final_freespace.csv路径有误,文件不存在");
+        }
+        List<String> list = null;
+        try {
+            list = FileUtil.readFileByLines2(routePath);
+            log.info("数据读取成功");
+
+            // 修改棋盘每个顶点坐标,然后再入库
+            List<JSONObject> newRoute = new ArrayList<>();
+            for (String line : list) {
+                // 将每一行的坐标值获取处理进行修改
+                String[] split = line.split(" ");
+
+                double[] oldPoint = {Double.valueOf(split[0]), Double.valueOf(split[1]), Double.valueOf(split[2])};
+                double[] newPoint =  applyMatrix4(oldPoint,newMatrix);
+
+                StringBuilder lineBuffer = new StringBuilder();
+
+                for (int i = 0; i < split.length; i++) {
+                    if (i>3) {
+                        lineBuffer.append(split[i]);
+                        if (i != split.length-1){
+                            lineBuffer.append(" ");
+                        }
+                    }
+
+                }
+                JSONObject linkedIds = new JSONObject();
+                linkedIds.put("linkedIds", lineBuffer.toString());
+
+                linkedIds.put("x", newPoint[0]);
+                linkedIds.put("y", newPoint[1]);
+                linkedIds.put("z", newPoint[2]);
+                linkedIds.put("k", split[3]);
+                newRoute.add(linkedIds);
+
+
+            }
+            log.info("数据解析成功");
+            return newRoute;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return null;
+
+    }
+
+    /**
      * 本地测试 修改 Route数据
      * @param args
      * @throws Exception

+ 47 - 0
laser/src/main/java/com/fdkankan/indoor/base/convert/GisCoordinateUtil.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.indoor.base.convert.GisCoordinateTransform;
 import com.fdkankan.indoor.core.entity.ControlPointEntity;
+import org.junit.Test;
 
 import java.io.*;
 
@@ -178,4 +179,50 @@ public class GisCoordinateUtil {
         return d;
     }
 
+
+    /**
+     *  两个控制点的纠偏,已知两个控制点的未纠偏前的经纬度和控制点的真实经纬度,求真实位置相对于未纠偏之前的旋转 角度
+     * @param relativePoint1     【经度,纬度】   [113,22]  ,相对坐标用算法生成的控制点
+     * @param absolutelyPoint1   【经度,纬度】   [113,22]  绝对坐标:用页面输入的坐标
+     * @param relativePoint2        【经度,纬度】   [113,22] ,相对坐标用算法生成的控制点
+     * @param absolutelyPoint2      【经度,纬度】   [113,22] 绝对坐标:用页面输入的坐标
+     * @return  弧度 设置到dataSet.orientation
+     */
+    private static double getAngle(double[] relativePoint1,double[] absolutelyPoint1,double[] relativePoint2,double[] absolutelyPoint2){
+        double[]  relativeVector=new double[2];
+        double[]  absolutelyVector=new double[2];
+        relativeVector[0]=relativePoint2[0]-relativePoint1[0];
+        relativeVector[1]=relativePoint2[1]-relativePoint1[1];
+        absolutelyVector[0]=absolutelyPoint2[0]-absolutelyPoint1[0];
+        absolutelyVector[1]=absolutelyPoint2[1]-absolutelyPoint1[1];
+        double a1=Math.atan2(relativeVector[1], relativeVector[0]);
+        double a2=Math.atan2(absolutelyVector[1], absolutelyVector[0]);
+        return  a1-a2;
+    }
+
+    /**
+     * 获取弧度
+     * @param dto
+     * @return
+     */
+    public static double getAngle(ControlPointEntity dto){
+
+        double[] relativePoint1 = dto.getRelativePoint1();
+        double[] absolutelyPoint1 = dto.getGpsControlCoordinate1();
+        double[] relativePoint2 = dto.getRelativePoint2();
+        double[] absolutelyPoint2 = dto.getGpsControlCoordinate2();
+        return getAngle(relativePoint1, absolutelyPoint1, relativePoint2, absolutelyPoint2);
+
+    }
+
+    @Test
+    public void testGetAngle(){
+        double[] relativePoint1 = { 113.595725873337, 22.366579193007};
+        double[] absolutelyPoint1 = {113.595725873337, 22.366579193007};
+        double[] relativePoint2 = {113.595754224886, 22.3665878935361};
+        double[] absolutelyPoint2 = {113.595754224886, 22.3665878935361};
+        double angle = getAngle(relativePoint1, absolutelyPoint1, relativePoint2, absolutelyPoint2);
+        System.out.println(angle);
+    }
+
 }

+ 143 - 15
laser/src/main/java/com/fdkankan/indoor/base/convert/MergeRouteMap.java

@@ -3,37 +3,63 @@ package com.fdkankan.indoor.base.convert;
 import java.util.ArrayList;
 import java.util.List;
 
+import lombok.extern.slf4j.Slf4j;
 import net.sf.json.JSONObject;
 
 /**
  * 合并Route表
  */
+@Slf4j
 public class MergeRouteMap {
-    private String path1 = "";
-    private String pate2 = "";
+//  private String path1 = "";
+//  private String pate2 = "";
+
     private static final float cell = 0.36f;
+    //第一张表的行数
     private static final int lineNum = 100;
 
     //FixRouteMap之后
-    public static List<Integer> getEdge(List<JSONObject> list) {
+    //linkedIds表示相连的8个邻居点的id,是字符串
+    private static List<Integer> getEdge(List<JSONObject> list,int addLineNum) {
         List<Integer> edges = new ArrayList<Integer>();
         for (int i = 0; i < list.size(); ++i) {
             JSONObject item = (JSONObject) list.get(i);
             String linkedIds = item.getString("linkedIds");
-            if (linkedIds.indexOf("-1") > -1) {
-                edges.add(i);
+            String[] linked = linkedIds.split(" ");
+            for(int j=0;j<linked.length;++j) {
+                if(linked[j].equals("-1")) {
+                    edges.add(i);
+                }
+                else {
+                    linked[j] = String.valueOf(Integer.valueOf(linked[j])+addLineNum);
+                }
             }
+            linkedIds = convertArrayToString(linked);
+            item.put("linkedIds", linkedIds);
         }
         return edges;
     }
 
-    public static double getDis(double x, double y, double z, double _x, double _y, double _z) {
+    public static String convertArrayToString(String[] strArr) {
+        String res = "";
+        for (int i = 0, len = strArr.length; i < len; i++) {
+            res += strArr[i];
+            if (i < len - 1) {
+                res += " ";
+            }
+        }
+        return res;
+    }
+
+    // 算距离
+    private static double getDis(double x, double y, double z, double _x, double _y, double _z) {
         double distance = Math.pow((x - _x), 2) + Math.pow((y - _y), 2) + Math.pow((z - _z), 2);
         distance = Math.sqrt(distance);
         return distance;
     }
 
-    public static int getMini(JSONObject item, List<JSONObject> list) {
+    //item是边缘
+    private static int getMini(JSONObject item, List<JSONObject> list) {
         double minDistance = 10000;
         int linked = -1;
 
@@ -43,9 +69,9 @@ public class MergeRouteMap {
 
         for (int i = 0; i < list.size(); ++i) {
             JSONObject _item = list.get(i);
-            double _x = item.getDouble("_x");
-            double _y = item.getDouble("_y");
-            double _z = item.getDouble("_z");
+            double _x = _item.getDouble("x");
+            double _y = _item.getDouble("y");
+            double _z = _item.getDouble("z");
 
             if (Math.abs(x - _x) < cell && Math.abs(y - _y) < cell && Math.abs(z - _z) < cell) {
                 continue;
@@ -60,14 +86,73 @@ public class MergeRouteMap {
         return linked;
     }
 
+
+    public static List<JSONObject> mergeRoute(List<JSONObject> list1, List<JSONObject> list2){
+        log.info("list1数量:{}", list1.size());
+        log.info("list2数量:{}", list2.size());
+        try {
+            List<Integer> edges1 = getEdge(list1,0);
+            List<Integer> edges2 = getEdge(list2,list1.size());
+
+            List<JSONObject> result = new ArrayList<>();
+
+
+
+            //第一个表里找边缘点与第二个表比较
+            for (int i = 0; i < edges1.size(); ++i) {
+                int index = edges1.get(i);
+                JSONObject item1 = list1.get(index);
+                int linked = getMini(item1, list2);
+                if (linked != -1) {
+                    String linkedIds = item1.getString("linkedIds").replaceFirst("-1", String.valueOf(linked+1+list1.size()));
+                    item1.put("linkedIds", linkedIds);
+                }
+            }
+
+            //第二个表里找边缘点与第一个表比较
+            for (int i = 0; i < edges2.size(); ++i) {
+                int index = edges2.get(i);
+                JSONObject item2 = list2.get(index);
+                int linked = getMini(item2, list1);
+                if (linked != -1) {
+                    String linkedIds = item2.getString("linkedIds").replaceFirst("-1", String.valueOf(linked+1));
+                    item2.put("linkedIds", linkedIds);
+                }
+            }
+
+            for(int i=0;i<list1.size();++i) {
+                JSONObject item = list1.get(i);
+                result.add(item);
+            }
+
+            for(int i=0;i<list2.size();++i) {
+                JSONObject item = list2.get(i);
+                result.add(item);
+            }
+
+            log.info("合并后数量:{}", result.size());
+            return result;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+
     public static void main(String args[]) {
+        String path1 = "F:\\test\\ngin\\age_laser_data\\t-30\\results\\laserData\\final_freespace.csv";
+        String pate2 = "F:\\test\\ngin\\age_laser_data\\t-40\\results\\laserData\\final_freespace.csv";
+
 
         try {
-            List<JSONObject> list1 = new ArrayList<JSONObject>();
-            List<JSONObject> list2 = new ArrayList<JSONObject>();
+            List<JSONObject> list1 = getLinkedIds(path1);
+            List<JSONObject> list2 = getLinkedIds(pate2);
+
+            List<Integer> edges1 = getEdge(list1, 0);
+            List<Integer> edges2 = getEdge(list2, list1.size());
 
-            List<Integer> edges1 = getEdge(list1);
-            List<Integer> edges2 = getEdge(list2);
+            List<JSONObject> result = new ArrayList<>();
 
             //第一个表里找边缘点与第二个表比较
             for (int i = 0; i < edges1.size(); ++i) {
@@ -77,11 +162,12 @@ public class MergeRouteMap {
                 if (linked != -1) {
                     String linkedIds = item1.getString("linkedIds").replaceFirst("-1", String.valueOf(linked));
                     item1.put("linkedIds", linkedIds);
+                    result.add(item1);
                 }
             }
 
             //第二个表里找边缘点与第一个表比较
-            edges2 = getEdge(list2);
+//          edges2 = getEdge(list2);
             for (int i = 0; i < edges2.size(); ++i) {
                 int index = edges2.get(i);
                 JSONObject item2 = list2.get(index);
@@ -89,13 +175,55 @@ public class MergeRouteMap {
                 if (linked != -1) {
                     String linkedIds = item2.getString("linkedIds").replaceFirst("-1", String.valueOf(linked));
                     item2.put("linkedIds", linkedIds);
+                    result.add(item2);
                 }
             }
 
+            //最后再合并list1和list2,入库
             System.out.println("ok");
         } catch (Exception e) {
             e.printStackTrace();
         }
 
     }
+
+    /**
+     * 解析csv数据
+     * String path1 = "F:\\test\\ngin\\age_laser_data\\t-40\\results\\laserData\\final_freespace.csv";
+     * @param path
+     * @return
+     * @throws Exception
+     */
+    private static List<JSONObject> getLinkedIds(String path) throws Exception {
+        List<String> list = FileUtil.readFileByLines2(path);
+        List<JSONObject> newRoute = new ArrayList<>();
+        for (String line : list) {
+            // 将每一行的坐标值获取处理进行修改
+            String[] split = line.split(" ");
+
+            StringBuilder lineBuffer = new StringBuilder();
+
+            for (int i = 0; i < split.length; i++) {
+                if (i>3) {
+                    lineBuffer.append(split[i]);
+                    if (i != split.length-1){
+                        lineBuffer.append(" ");
+                    }
+                }
+
+            }
+            JSONObject linkedIds = new JSONObject();
+            linkedIds.put("linkedIds", lineBuffer.toString());
+
+            linkedIds.put("x", split[0]);
+            linkedIds.put("y", split[1]);
+            linkedIds.put("z", split[2]);
+            linkedIds.put("k", split[3]);
+            newRoute.add(linkedIds);
+        }
+
+
+        return newRoute;
+
+    }
 }

+ 4 - 2
laser/src/main/java/com/fdkankan/indoor/base/convert/ModifyDataSets.java

@@ -83,7 +83,8 @@ public class ModifyDataSets {
 		po.setType("4dage");
 		po.setName(mergeDto.getName());
 		po.setTitle(mergeDto.getTitle());
-		po.setColor("pink");
+		String color = mergeDto.getColor() == null? "pink" : mergeDto.getColor();
+		po.setColor(color);
 		po.setVisible(false);
 
 		//double[] location = {0,0,0};
@@ -91,7 +92,8 @@ public class ModifyDataSets {
 		//原点 ,获取特征点的原点
 //		Double[] doubles = param.get(TypeConstant.POI_ORIGIN);
 		po.setLocation(param.get(TypeConstant.POI_ORIGIN));
-		po.setOrientation(0.0);
+//		po.setOrientation(0.0);
+		po.setOrientation(mergeDto.getOrientation());
 		// 2021.08.26
 //		Double[] doubles = {0.0};
 //		po.setOrientation(doubles);

+ 148 - 0
laser/src/main/java/com/fdkankan/indoor/base/convert/PlanGraph.java

@@ -0,0 +1,148 @@
+package com.fdkankan.indoor.base.convert;
+
+import net.sf.json.JSONObject;
+
+/**
+ * Created by owen on 2021/9/1 0001 18:06
+ * 平面图
+ */
+
+public class PlanGraph {
+
+    //THREE.Math.degToRad(-90)
+    public double degToRad(double angle) {
+        double DEG2RAD = Math.PI/180;
+        return angle * DEG2RAD;
+    }
+
+    public JSONObject setFromAxisAngle(JSONObject axis, double angle) {
+        // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
+        // assumes axis is normalized
+
+        double halfAngle = angle / 2;
+        double s = Math.sin( halfAngle );
+
+        double _x = axis.getDouble("x") * s;
+        double _y = axis.getDouble("y") * s;
+        double _z = axis.getDouble("z") * s;
+        double _w = Math.cos( halfAngle );
+
+        //this._onChangeCallback();
+        JSONObject quaternion = new JSONObject();
+        quaternion.put("x", _x);
+        quaternion.put("y", _y);
+        quaternion.put("z", _z);
+        quaternion.put("w", _w);
+        return quaternion;
+    }
+
+    public JSONObject inverse(JSONObject quaternion) {
+        double _x = -1*quaternion.getDouble("x");
+        double _y = -1*quaternion.getDouble("y");
+        double _z = -1*quaternion.getDouble("z");
+        JSONObject _quaternion = new JSONObject();
+        _quaternion.put("x", _x);
+        _quaternion.put("y", _y);
+        _quaternion.put("z", _z);
+        _quaternion.put("w", quaternion.getDouble("w"));
+        return _quaternion;
+    }
+
+    public JSONObject multiply(JSONObject q, JSONObject p ) {
+
+        return multiplyQuaternions( q, p );
+
+    }
+
+    public JSONObject multiplyQuaternions(JSONObject a,JSONObject b ) {
+
+        // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
+
+        //const qax = a._x, qay = a._y, qaz = a._z, qaw = a._w;
+        //const qbx = b._x, qby = b._y, qbz = b._z, qbw = b._w;
+
+        double _x = a.getDouble("x") * b.getDouble("w") + a.getDouble("w") * b.getDouble("x") + a.getDouble("y") * b.getDouble("z") - a.getDouble("z") * b.getDouble("y");
+        double _y = a.getDouble("y") * b.getDouble("w") + a.getDouble("w") * b.getDouble("y") + a.getDouble("z") * b.getDouble("x") - a.getDouble("x") * b.getDouble("z");
+        double _z = a.getDouble("z") * b.getDouble("w") + a.getDouble("w") * b.getDouble("z") + a.getDouble("x") * b.getDouble("y") - a.getDouble("y") * b.getDouble("x");
+        double _w = a.getDouble("w") * b.getDouble("w") - a.getDouble("x") * b.getDouble("x") - a.getDouble("y") * b.getDouble("y") - a.getDouble("z") * b.getDouble("z");
+
+        JSONObject quaternion = new JSONObject();
+        quaternion.put("x", _x);
+        quaternion.put("y", _y);
+        quaternion.put("z", _z);
+        quaternion.put("w", _w);
+        return quaternion;
+
+    }
+
+    public double[] toArray(JSONObject quaternion) {
+
+        //new THREE.Quaternion
+		/*
+		 * 	_w: 1
+			_x: 0
+			_y: 0
+			_z: 0
+		 * */
+        //double[] Quaternion = {1,0,0,0};
+        JSONObject axis = new JSONObject();
+        axis.put("x", 0);
+        axis.put("y", 0);
+        axis.put("z", 1);
+        JSONObject rot90 =  setFromAxisAngle(axis, degToRad(-90)); //add 转入时旋转90度
+        JSONObject rot90Invert = inverse(rot90);//add 转出时旋回90度
+        JSONObject t1 = multiply(quaternion,rot90Invert);
+
+        double[] e = {t1.getDouble("w"),t1.getDouble("x"),t1.getDouble("y"),t1.getDouble("z")};
+        return e;
+        //JSONObject e = t1.toArray();
+        //return [e[3], e[0], e[1], e[2]]
+    }
+
+    public JSONObject setFromEuler(double x,double y,double z) {
+
+        double c1 = Math.cos( x / 2 );
+        double c2 = Math.cos( y / 2 );
+        double c3 = Math.cos( z / 2 );
+
+        double s1 = Math.sin( x / 2 );
+        double s2 = Math.sin( y / 2 );
+        double s3 = Math.sin( z / 2 );
+
+        JSONObject quaternion = new JSONObject();
+        double _x = s1 * c2 * c3 + c1 * s2 * s3;
+        double _y = c1 * s2 * c3 - s1 * c2 * s3;
+        double _z = c1 * c2 * s3 + s1 * s2 * c3;
+        double _w = c1 * c2 * c3 - s1 * s2 * s3;
+
+        quaternion.put("x", _x);
+        quaternion.put("y", _y);
+        quaternion.put("z", _z);
+        quaternion.put("w", _w);
+
+        return quaternion;
+    }
+
+    public double[] getQuaternion(double angle) {
+        JSONObject quaternion = setFromEuler(0,0,degToRad(-angle));
+        return toArray(quaternion);
+    }
+
+    public double getSize(int imgWidth, int scale) {
+        double level = imgWidth / 1024;  //以1024为基准
+        return 95.54628610610962 * level * scale; // 95.54628610610962 = 38.21851444244385 * (2+0.5), 其中38.21851444244385 = mapSizeM / Math.pow(2,maxDepth) = 40075017 / Math.pow(2,20) 可能表示地图在缩放zoom为20时的单块宽度
+        //0.5是试出来的,因为图片层的bias=0.5, 暂不知道其用处,所以试用了下……
+        //另:可能不是*2.5,  也许是*256/100 ?  不知道如何精确测试下
+        //有出现过一次错误是2048时的图但是大了一倍,发现是传图的那个网页在缩放值为0.1(即图为1:1显示,函数canvasFunction(extent, scale )时只有1024大小,后来刷新重新操作就是2048然后就正确。所以可能是这个网页出错。
+    }
+
+    public static void main(String[] args) {
+        PlanGraph _testMap = new PlanGraph();
+        double angle = 0;
+        // 获取laserData/cover/info.json -> resolution.width/height的最大值
+        int imgWidth = 2048;
+        // tiledMap 使用的值
+        double[] orientation = _testMap.getQuaternion(angle);
+        double map_size_m = _testMap.getSize(imgWidth,1);
+    }
+}

+ 6 - 3
laser/src/main/java/com/fdkankan/indoor/base/convert/TransformGPS.java

@@ -17,6 +17,7 @@ public class TransformGPS {
 //	public static double[] controlLocation2 = {6.059886f,-12.197689f}; // 四维看看坐标
 //	public static double[] controlCoordinate2 = {113.59571900944f,22.366554639591f};  //gps坐标
 
+	// 控制点
 	public static double[] controlLocation1 = {-1.803582f,-1.927333f};  // 四维看看坐标
 	public static double[] controlCoordinate1 = {113.60044921875,22.364469401041667}; //gps坐标
 
@@ -94,10 +95,12 @@ public class TransformGPS {
 	   	
         return result;
 	}
-	
+
+	/**
+	 * 四维坐标转gis坐标
+	 * @param args
+	 */
     public static void main(String[] args) {
-        //String url = "src/main/resources/demo.cp";
-        //GisCoordinateUtil.parseControlPointsFile(url);
     	GisCoordinateUtil.calculateVariable (
     			controlCoordinate1[0],controlCoordinate1[1],controlLocation1[0],controlLocation1[1],
 				controlCoordinate2[0],controlCoordinate2[1],controlLocation2[0],controlLocation2[1]);

+ 24 - 0
laser/src/main/java/com/fdkankan/indoor/base/convert/quadTree/Node.java

@@ -0,0 +1,24 @@
+package com.fdkankan.indoor.base.convert.quadTree;
+
+public class Node {
+	public boolean val;
+    public boolean isLeaf;
+    public Node topLeft;
+    public Node topRight;
+    public Node bottomLeft;
+    public Node bottomRight;
+    
+    public String row;
+    public String col;
+ 
+    public Node() {}
+ 
+    public Node(boolean _val,boolean _isLeaf,Node _topLeft,Node _topRight,Node _bottomLeft,Node _bottomRight) {
+        val = _val;
+        isLeaf = _isLeaf;
+        topLeft = _topLeft;
+        topRight = _topRight;
+        bottomLeft = _bottomLeft;
+        bottomRight = _bottomRight;
+    }
+}

+ 203 - 0
laser/src/main/java/com/fdkankan/indoor/base/convert/quadTree/Solution.java

@@ -0,0 +1,203 @@
+package com.fdkankan.indoor.base.convert.quadTree;
+
+import java.io.File;
+
+//import com.tree.my.Node;
+//import com.tree.my.Solution;
+
+//com.quadTree.
+
+/**
+ * 四叉树算法
+ */
+public class Solution {
+
+	///阿里云-四维时代-官网测试服务器-120.25.146.52/mnt/data/00001001/882599154956632064/7ca7b00be91d_202109011208264440/results/laserData/cover/3
+//	public static final String path = "F:\\2021\\navvis\\���Ի���\\laserData\\building_1\\map_tiles\\2\\3";
+//	public static String QUADTREE = "";
+	//public static int MaxDepth = 0;
+	
+	private static String quadTree = "";
+
+
+	//val      当前点是否有值
+	//isLeaf   是否是叶子节点,即:是否有儿子
+	public static Node construct(int[][] grid) {
+        return find(grid,0,grid.length-1,0,grid.length-1);
+    }
+    
+    private static Node find(int[][] grid,int startrow,int endrow,int startcol,int endcol) {
+    	boolean val = grid[startrow][startcol] == 0?false:true;
+    	Node root=null;
+    	
+    	if(startrow == 0&&endrow == 1&&startcol == 2&&endcol == 3) {
+    		System.out.println();
+    	}
+
+    	if(isLeaf(grid,startrow,endrow,startcol,endcol))
+    	{
+    		root=new Node(val,true,null,null,null,null);
+    	}
+    	else {
+    		root=new Node(val,false,null,null,null,null);
+    		root.topLeft=find(grid,startrow,startrow+(endrow-startrow)/2,startcol,startcol+(endcol-startcol)/2);
+    		root.bottomLeft=find(grid,startrow+(endrow-startrow)/2+1,endrow,startcol,startcol+(endcol-startcol)/2);
+    		root.topRight=find(grid,startrow,startrow+(endrow-startrow)/2,startcol+(endcol-startcol)/2+1,endcol);
+    		root.bottomRight=find(grid,startrow+(endrow-startrow)/2+1,endrow,startcol+(endcol-startcol)/2+1,endcol);
+    	}
+    	root.row = String.valueOf(startrow)+'-'+String.valueOf(endrow);
+    	root.col = String.valueOf(startcol)+'-'+String.valueOf(endcol);
+    	return root;
+    }
+    
+    private static boolean isLeaf(int[][] grid,int startrow,int endrow,int startcol,int endcol) {
+    	//int now=grid[startrow][startcol];
+    	if(startrow == endrow && startcol == endcol) {
+			//叶子节点
+    		return true;
+    	}
+    	
+    	for(int i=startrow;i<=endrow;i++)
+    	{
+    		for(int j=startcol;j<=endcol;j++)
+    		{
+    			if(grid[i][j] == 1)
+    			{
+					//非叶子节点
+    				return false;
+    			}
+    		}
+    	}
+		//叶子节点
+    	return true;
+    }
+    
+    private static File readFiles(String inPath) {
+		try {
+			File f = new File(inPath);
+			if(f.isDirectory()) {
+				//MaxDepth = f.list().length;
+				return f;
+			}
+			else {
+				return null;
+			}
+		}
+		catch(Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+	}
+
+	private static String getXYTiles(File f){
+		File[] files = f.listFiles();
+		String tiles = "";
+
+		int maxX = files.length;
+		int maxY = 0;
+		for(int i=0;i<files.length;++i) {
+			String[] fileNames = files[i].list();
+			if(fileNames.length>maxY) {
+				maxY = fileNames.length;
+			}
+			for(int j=0;j<fileNames.length;++j) {
+				tiles += files[i].getName()+"-"+fileNames[j].replace(".png", "")+",";
+			}
+		}
+		
+		int max = Math.max(maxX, maxY);
+		int[][] numthree = new int[max][max];
+		
+		for(int i=0;i<max;++i) {
+			for(int j=0;j<max;++j) {
+				if(tiles.indexOf(String.valueOf(i)+"-"+String.valueOf(j))>-1) {
+					numthree[i][j] = 1;
+				}
+				else {
+					numthree[i][j] = 0;
+				}
+			}
+		}
+		
+		Node node = construct(numthree);
+		String singleScore = getSingleScore(node);
+		System.out.println("singleScore: " + singleScore);
+		ouput(node);
+		// tiledMap.Quadtree("fccf7fffcff3bf7f") 的值;
+		System.out.println(quadTree);
+		return quadTree;
+	}
+	
+	private static void ouput(Node node) {
+		if(node.isLeaf) {
+			return;
+		}
+
+		getSingleScore(node.topLeft);
+		getSingleScore(node.bottomLeft);
+		getSingleScore(node.topRight);
+		getSingleScore(node.bottomRight);
+		
+		if(node.topLeft!=null) {
+			ouput(node.topLeft);
+		}
+		if(node.bottomLeft!=null) {
+			ouput(node.bottomLeft);
+		}
+		if(node.topRight!=null) {
+			ouput(node.topRight);
+		}
+		if(node.bottomRight!=null) {
+			ouput(node.bottomRight);
+		}
+	}
+	
+	private static String getSingleScore(Node node) {
+		int score = 0;
+		
+		if(node.topLeft!=null&&!node.topLeft.isLeaf) {
+			score +=1;
+		}
+		else if(node.topLeft!=null&&node.topLeft.val) {
+			score +=1;
+		}
+		
+		if(node.topRight!=null&&!node.topRight.isLeaf) {
+			score +=4;
+		}
+		else if(node.topRight!=null&&node.topRight.val) {
+			score +=4;
+		}
+		
+		if(node.bottomLeft!=null&&!node.bottomLeft.isLeaf) {
+			score +=2;
+		}
+		else if(node.bottomLeft!=null&&node.bottomLeft.val) {
+			score +=2;
+		}
+		
+		if(node.bottomRight!=null&&!node.bottomRight.isLeaf) {
+			score +=8;
+		}
+		else if(node.bottomRight!=null&&node.bottomRight.val) {
+			score +=8;
+		}
+		if(score>0) {
+			String str = Integer.toHexString(score);
+			quadTree += str;
+			return str;
+		}
+		else {
+			return "0";
+		}
+	}
+
+	public static void main(String args[]) {
+		String path = "F:\\test\\ngin\\age_laser_data\\w-60\\results\\laserData\\cover\\0";
+		File file = readFiles(path);
+		if(file!=null) {
+			String xyTiles = getXYTiles(file);
+			System.out.println("quadTree:" + xyTiles);
+		}
+	}
+}

+ 5 - 4
laser/src/main/java/com/fdkankan/indoor/core/controller/ControlPointController.java

@@ -3,6 +3,7 @@ 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.entity.ControlPointEntity;
+import com.fdkankan.indoor.core.entity.dto.ControlPointDto;
 import com.fdkankan.indoor.core.service.ControlPointService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -34,10 +35,10 @@ public class ControlPointController {
     @WebControllerLog(description = "控制点管理-新增/修改控制点")
     @ApiOperation(value = "新增/修改控制点")
     @PostMapping("indoor/{sceneCode}/api/controlPoint/save")
-    public Result save(@PathVariable String sceneCode,  @RequestBody ControlPointEntity param) {
-        param.setId(sceneCode);
-        String from = "web";
-        return entityService.save(param, from);
+    public Result save(@PathVariable String sceneCode,  @RequestBody ControlPointDto param) {
+//        param.setId(sceneCode);
+//        String from = "web";
+        return entityService.save(param, sceneCode);
     }
 
 

+ 18 - 4
laser/src/main/java/com/fdkankan/indoor/core/controller/DateSetController.java

@@ -31,7 +31,7 @@ public class DateSetController {
      * @param sceneCode
      * @return
      */
-    @WebControllerLog(description = "场景信息接口-获取数据")
+    @WebControllerLog(description = "数据集-获取数据")
     @ApiOperation(value = "获取数据")
     @GetMapping("indoor/{sceneCode}/api/datasets")
     public Object getDataSet(@PathVariable String sceneCode) {
@@ -41,12 +41,12 @@ public class DateSetController {
 
 
     /**
-     * FixRouteMap
+     * 2021.8.31 不处理旋转平移 FixRouteMap
      * @param sceneCode
      * @param param
      * @return
      */
-    @WebControllerLog(description = "场景信息接口-修改")
+    @WebControllerLog(description = "数据集-修改(不添加)")
     @ApiOperation(value = "修改数据", notes = "会修改route数据")
     @PutMapping("indoor/{sceneCode}/api/datasets")
     public Object update(@PathVariable String sceneCode, @RequestBody List<DataSetPo> param) {
@@ -61,11 +61,25 @@ public class DateSetController {
      * @param dataSetId
      * @return
      */
-    @WebControllerLog(description = "场景信息接口-根据id查询")
+    @WebControllerLog(description = "数据集-根据id查询")
     @ApiOperation(value = "根据id查询")
     @GetMapping("indoor/{sceneCode}/api/datasets/{dataSetId}")
     public Object findByDataSetId(@PathVariable String sceneCode, @PathVariable Integer dataSetId) {
         Result result = entityService.findByDataSetId(sceneCode, dataSetId);
         return result.getData();
     }
+
+
+    /**
+     * 合并route, 2个数据集以上才执行
+     * @param sceneCode
+     * @return
+     */
+    @WebControllerLog(description = "数据集-合并route")
+    @ApiOperation(value = "合并route")
+    @GetMapping("indoor/{sceneCode}/api/reposes")
+    public Object reposes(@PathVariable String sceneCode) throws Exception {
+        Result result = entityService.reposes(sceneCode);
+        return result;
+    }
 }

+ 37 - 37
laser/src/main/java/com/fdkankan/indoor/core/controller/PoseController.java

@@ -1,37 +1,37 @@
-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.ConfigService;
-import com.fdkankan.indoor.core.service.PoseService;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * Created by owen on 2021/8/5 0005 20:56
- * 生成pose.json 给算法部用
- */
-@Api(tags = "pose")
-@RestController
-public class PoseController {
-
-    @Autowired
-    PoseService poseService;
-
-    /**
-     * 2021-08-31 可能废弃
-     * @param sceneCode
-     * @return
-     */
-    @WebControllerLog(description = "生成pose.json")
-    @ApiOperation(value = "生成pose.json")
-    @GetMapping("indoor/{sceneCode}/api/reposes")
-    public Object reposes(@PathVariable String sceneCode){
-        Result result = poseService.reposes(sceneCode);
-        return result;
-    }
-}
+//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.ConfigService;
+//import com.fdkankan.indoor.core.service.PoseService;
+//import io.swagger.annotations.Api;
+//import io.swagger.annotations.ApiOperation;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.web.bind.annotation.GetMapping;
+//import org.springframework.web.bind.annotation.PathVariable;
+//import org.springframework.web.bind.annotation.RestController;
+//
+///**
+// * Created by owen on 2021/8/5 0005 20:56
+// * 生成pose.json 给算法部用
+// */
+//@Api(tags = "pose")
+//@RestController
+//public class PoseController {
+//
+//    @Autowired
+//    PoseService poseService;
+//
+//    /**
+//     * 2021-08-31 可能废弃
+//     * @param sceneCode
+//     * @return
+//     */
+//    @WebControllerLog(description = "生成pose.json")
+//    @ApiOperation(value = "生成pose.json")
+//    @GetMapping("indoor/{sceneCode}/api/reposes")
+//    public Object reposes(@PathVariable String sceneCode){
+//        Result result = poseService.reposes(sceneCode);
+//        return result;
+//    }
+//}

+ 6 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/ControlPointEntity.java

@@ -33,6 +33,12 @@ public class ControlPointEntity {
     private double[] gpsControlCoordinate2;
 
 
+    @ApiModelProperty(value = "算法部生成gis坐标1, 【经度,纬度】   [113,22]")
+    private double[] relativePoint1;
+
+    @ApiModelProperty(value = "算法部生成gis坐标2, 【经度,纬度】   [113,22]")
+    private double[] relativePoint2;
+
     private LocalDateTime createTime;
 
     private LocalDateTime updateTime;

+ 31 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/dto/ControlPointDto.java

@@ -0,0 +1,31 @@
+package com.fdkankan.indoor.core.entity.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * Created by owen on 2021/8/31 0031 16:13
+ */
+@Data
+public class ControlPointDto {
+
+    // 四维看看控制点
+    @ApiModelProperty(value = "四维看看控制点1",required = true)
+    private double[] ageControlLocation1;
+
+    @ApiModelProperty(value = "四维看看控制点2" , required = true)
+    private double[] ageControlLocation2;
+
+    // gps坐标
+    @ApiModelProperty(value = "GPS坐标1, 参数[0]:lat, [1]:lon" , required = true)
+    private double[] gpsControlCoordinate1;
+
+    @ApiModelProperty(value = "GPS坐标2", required = true )
+    private double[] gpsControlCoordinate2;
+
+//    @ApiModelProperty(value = "算法部生成gis坐标1, 【经度,纬度】   [113,22]")
+//    private double[] relativePoint1;
+//
+//    @ApiModelProperty(value = "算法部生成gis坐标2, 【经度,纬度】   [113,22]")
+//    private double[] relativePoint2;
+}

+ 6 - 0
laser/src/main/java/com/fdkankan/indoor/core/entity/merge/MergeDateSetDto.java

@@ -24,4 +24,10 @@ public class MergeDateSetDto {
 
     @ApiModelProperty(value = "nas场景文件地址")
     private String path;
+
+    @ApiModelProperty(value = "弧度")
+    private Double orientation;
+
+    @ApiModelProperty(value = "颜色")
+    private String color;
 }

+ 2 - 0
laser/src/main/java/com/fdkankan/indoor/core/mapper/MergeInfoMapper.java

@@ -24,4 +24,6 @@ public interface MergeInfoMapper extends MongoRepository<MergeInfoEntity, String
     void deleteBySceneCodeAndMergeCode(String sceneCode, String mergeCode);
 
     void deleteBySceneCode(String sceneCode);
+
+    MergeInfoEntity findBySceneCodeAndDataSetId(String sceneCode, Integer dataSetId);
 }

+ 4 - 1
laser/src/main/java/com/fdkankan/indoor/core/service/ControlPointService.java

@@ -3,13 +3,14 @@ package com.fdkankan.indoor.core.service;
 
 import com.fdkankan.indoor.base.util.Result;
 import com.fdkankan.indoor.core.entity.ControlPointEntity;
+import com.fdkankan.indoor.core.entity.dto.ControlPointDto;
 
 /**
  * Created by owen on 2021/7/28 0028 20:05
  */
 public interface ControlPointService {
 
-    Result save(ControlPointEntity param, String from);
+    Result save(ControlPointDto param, String sceneCode);
 
     ControlPointEntity findById(String id);
 
@@ -18,4 +19,6 @@ public interface ControlPointService {
     void remove(String sceneCode);
 
     Result testControlPoint(ControlPointEntity param);
+
+    void saveEntity(ControlPointEntity param);
 }

+ 2 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/DataSetService.java

@@ -23,4 +23,6 @@ public interface DataSetService {
     List<DataSetPo> getDataBySceneCode(String sceneCode);
 
     DataSetEntity findById(String sceneCode);
+
+    Result reposes(String sceneCode) throws Exception;
 }

+ 2 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/MergeInfoService.java

@@ -22,4 +22,6 @@ public interface MergeInfoService {
     void removeSceneCodeAndMergeCode(String sceneCode, String mergeCode);
 
     void removeBySceneCode(String sceneCode);
+
+    MergeInfoEntity findBySceneCodeAndDataSetId(String sceneCode, Integer dataSetId);
 }

+ 41 - 14
laser/src/main/java/com/fdkankan/indoor/core/service/impl/ControlPointServiceImpl.java

@@ -6,10 +6,13 @@ import com.fdkankan.indoor.base.exception.BaseRuntimeException;
 import com.fdkankan.indoor.base.util.Result;
 import com.fdkankan.indoor.core.entity.ControlPointEntity;
 import com.fdkankan.indoor.core.entity.InitEntity;
+import com.fdkankan.indoor.core.entity.dto.ControlPointDto;
 import com.fdkankan.indoor.core.mapper.ControlPointMapper;
 import com.fdkankan.indoor.core.service.ControlPointService;
 import com.fdkankan.indoor.core.service.InitService;
 import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -32,33 +35,38 @@ public class ControlPointServiceImpl implements ControlPointService {
 
 
     @Override
-    public Result save(ControlPointEntity param, String from) {
-        String id = param.getId();
-        if (StrUtil.isAllEmpty(id)){
-            return Result.failure("场景码不能为空");
+    public Result save(ControlPointDto param, String sceneCode) {
+
+
+        ControlPointEntity pointEntity = this.findById(sceneCode);
+        if (pointEntity == null) {
+            pointEntity = new ControlPointEntity();
         }
 
-        param.setUpdateTime(LocalDateTime.now());
+        BeanUtils.copyProperties(param, pointEntity);
+
+        pointEntity.setUpdateTime(LocalDateTime.now());
         // 用户手动输入控制点
-        if ("web".equals(from)) {
-            param.setStatus(1);
-        }
-        entityMapper.save(param);
+       pointEntity.setStatus(1);
+        entityMapper.save(pointEntity);
         log.info("控制点保存完成");
 
         // 初始化step2 数据
-        initService.initDataStep2(id);
+        initService.initDataStep2(sceneCode);
         log.info("初始化step2 完成");
         return Result.success();
     }
 
     @Override
+    public void saveEntity(ControlPointEntity param){
+        entityMapper.save(param);
+    }
+
+
+    @Override
     public ControlPointEntity findById(String id) {
         Optional<ControlPointEntity> optional = entityMapper.findById(id);
-        if (!optional.isPresent()) {
-            throw new BaseRuntimeException(MsgCode.e3001, "控制点对象不存在");
-        }
-        return optional.get();
+        return optional.orElse(null);
     }
 
     @Override
@@ -87,4 +95,23 @@ public class ControlPointServiceImpl implements ControlPointService {
         log.info("初始化step2 完成");
         return Result.success();
     }
+
+
+    @Test
+    public void test(){
+        ControlPointEntity in = new ControlPointEntity();
+        double[] a = {1.0, 1.0};
+        double[] b = {2.0, 2.0};
+        double[] c = {3.0, 3.0};
+        in.setAgeControlLocation2(a);
+        in.setGpsControlCoordinate2(b);
+
+        ControlPointEntity out = new ControlPointEntity();
+        out.setRelativePoint2(c);
+
+        BeanUtils.copyProperties(in, out);
+        System.out.println();
+
+
+    }
 }

+ 138 - 43
laser/src/main/java/com/fdkankan/indoor/core/service/impl/DataSetServiceImpl.java

@@ -3,30 +3,23 @@ package com.fdkankan.indoor.core.service.impl;
 import com.fdkankan.indoor.base.constant.MsgCode;
 import com.fdkankan.indoor.base.constant.TypeConstant;
 import com.fdkankan.indoor.base.convert.FixRouteMap;
+import com.fdkankan.indoor.base.convert.MergeRouteMap;
 import com.fdkankan.indoor.base.exception.BaseRuntimeException;
 import com.fdkankan.indoor.base.util.Result;
-import com.fdkankan.indoor.core.entity.ControlPointEntity;
-import com.fdkankan.indoor.core.entity.DataSetEntity;
-import com.fdkankan.indoor.core.entity.InitEntity;
-import com.fdkankan.indoor.core.entity.RouteEntity;
+import com.fdkankan.indoor.core.entity.*;
 import com.fdkankan.indoor.core.entity.dto.FilterHotDto;
 import com.fdkankan.indoor.core.entity.dto.PoiHotDto;
 import com.fdkankan.indoor.core.entity.dto.SecurityDto;
 import com.fdkankan.indoor.core.entity.po.DataSetPo;
 import com.fdkankan.indoor.core.mapper.DataSetMapper;
-import com.fdkankan.indoor.core.service.ControlPointService;
-import com.fdkankan.indoor.core.service.DataSetService;
-import com.fdkankan.indoor.core.service.InitService;
-import com.fdkankan.indoor.core.service.RouteService;
+import com.fdkankan.indoor.core.service.*;
 import lombok.extern.slf4j.Slf4j;
+import net.sf.json.JSONObject;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
@@ -49,6 +42,8 @@ public class DataSetServiceImpl extends IBaseServiceImpl implements DataSetServi
     @Autowired
     RouteService routeService;
 
+    @Autowired
+    MergeInfoService mergeInfoService;
 
 
     @Override
@@ -119,17 +114,19 @@ public class DataSetServiceImpl extends IBaseServiceImpl implements DataSetServi
         dataSetMapper.save(entity);
         log.info("更新dataSet数据完成");
 
-        // 更新RouteMap并存入数据库
-        try {
-            fixRouteMap(location, orientation, sceneCode);
-//            return Result.success(auth(sceneCode).getData());
-            // 返回修改的数组
-            return Result.success(getDataBySceneCodeAndDataSetId(sceneCode, newIds));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+        return Result.success(getDataBySceneCodeAndDataSetId(sceneCode, newIds));
 
-        return null;
+        // 2021-08-31 不需处理更新RouteMap并存入数据库
+//        try {
+//            fixRouteMap(location, orientation, sceneCode);
+////            return Result.success(auth(sceneCode).getData());
+//            // 返回修改的数组
+//            return Result.success(getDataBySceneCodeAndDataSetId(sceneCode, newIds));
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//
+//        return null;
     }
 
 
@@ -140,39 +137,136 @@ public class DataSetServiceImpl extends IBaseServiceImpl implements DataSetServi
      * @param sceneCode
      * @throws Exception
      */
-    private void fixRouteMap(Double[] location, Double orientation, String sceneCode) throws Exception {
-        String initKey = TypeConstant.REDIS_INIT_PATH + sceneCode;
-        log.info("initKey: {}", initKey);
-//        String initPath = redisTemplate.opsForValue().get(initKey);
-//        if (initPath == null) {
-//            InitEntity initEntity = initService.findById(sceneCode);
-//            if (initEntity == null) {
-//                throw new BaseRuntimeException("init初始化数据不存: {}" +sceneCode);
-//            }
-//            initPath = initEntity.getPath();
-//            redisTemplate.opsForValue().set(initKey, initPath, 24, TimeUnit.HOURS);
+//    private void fixRouteMap(Double[] location, Double orientation, String sceneCode) throws Exception {
+//        String initKey = TypeConstant.REDIS_INIT_PATH + sceneCode;
+//        log.info("initKey: {}", initKey);
+//        String initPath = redisPath(sceneCode);
+//
+//        initPath = initPath + "/laserData";
+//        log.info("initPath: {}", initPath);
+//
+//        ControlPointEntity controlPointEntity = controlPointService.findById(sceneCode);
+//        if (controlPointEntity == null) {
+//            throw new BaseRuntimeException("控制点数据不存: {}" +sceneCode);
 //        }
-        String initPath = redisPath(sceneCode);
+//        log.info("有控制点");
+//        double[] gpsLocation = {location[0], location[1], location[2]};
+//        List<String> routeMap = FixRouteMap.updateRouteMap(orientation, gpsLocation, controlPointEntity, initPath);
+//
+//        RouteEntity routeEntity = routeService.findBySceneCode(sceneCode);
+//        routeEntity.setData(routeMap);
+//        routeEntity.setUpdateTime(LocalDateTime.now());
+//        routeService.save(routeEntity);
+//        log.info("更新Route数据完成");
+//
+//    }
+
+
+    /**
+     * 本地测试:需要把t_merge_info的合并路径改为本地路径(windows)
+     * F:\\test\\ngin\\age_laser_data\\w-50\\results\\laserData
+     * @param sceneCode
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public Result reposes(String sceneCode)  {
 
-        initPath = initPath + "/laserData";
-        log.info("initPath: {}", initPath);
+        List<DataSetPo> data = getDataBySceneCode(sceneCode);
+        // 1个数据集, 不需要处理, 两个或以上需要处理
+        if (data.size() <= 1) {
+            log.info("数据集数量为1,不需要合并");
+            return Result.success();
+        }
 
-        ControlPointEntity controlPointEntity = controlPointService.findById(sceneCode);
-        if (controlPointEntity == null) {
-            throw new BaseRuntimeException("控制点数据不存: {}" +sceneCode);
+
+        // 获取控制点
+        ControlPointEntity controlPoint = controlPointService.findById(sceneCode);
+        // 原场景码地址
+        String sceneCodePath = redisPath(sceneCode) + "/laserData";
+        if ("dev".equals(configConstant.active)) {
+            sceneCodePath = "F:\\test\\ngin\\age_laser_data\\" + sceneCode + "\\results\\laserData";
+        }
+
+
+        List<List<JSONObject>> routeList= new ArrayList<>();
+        for (DataSetPo po : data) {
+            Double orientation = po.getOrientation();
+            if (orientation == null) {
+                throw new BaseRuntimeException("dataSet.orientation不能为空");
+            }
+            Double[] location = po.getLocation();
+            Integer dataSetId = po.getId();
+            double[] gpsLocation = {location[0], location[1], location[2]};
+            List<JSONObject> route ;
+            // 原数据集
+            if (dataSetId == 1) {
+                route = FixRouteMap.getRotate(orientation, gpsLocation, controlPoint, sceneCodePath);
+            } else {
+                // 合并数据集
+                MergeInfoEntity mergeInfoEntity = mergeInfoService.findBySceneCodeAndDataSetId(sceneCode, dataSetId);
+                if (mergeInfoEntity == null) {
+                    throw new BaseRuntimeException("合并信息数据不存在");
+                }
+                route = FixRouteMap.getRotate(orientation, gpsLocation, controlPoint, mergeInfoEntity.getPath());
+            }
+            routeList.add(route);
         }
-        log.info("有控制点");
-        double[] gpsLocation = {location[0], location[1], location[2]};
-        List<String> routeMap = FixRouteMap.updateRouteMap(orientation, gpsLocation, controlPointEntity, initPath);
+
+        // 合并
+        recursion(routeList);
+        log.info("route递归合并完成");
+
+        // 合并结果
+        List<JSONObject> mergeRoute = routeList.get(0);
+        // 信息写入数据库
+        List<String> resultStr = convertToString(mergeRoute);
 
         RouteEntity routeEntity = routeService.findBySceneCode(sceneCode);
-        routeEntity.setData(routeMap);
+        routeEntity.setData(resultStr);
         routeEntity.setUpdateTime(LocalDateTime.now());
         routeService.save(routeEntity);
         log.info("更新Route数据完成");
 
+
+
+        return Result.success();
     }
 
+    private static List<String> convertToString(List<JSONObject> param){
+        List<String> mergeResult =  new ArrayList<>();
+            for (JSONObject jon : param) {
+                StringBuilder strBuilder = new StringBuilder();
+                strBuilder.append(jon.getString("x")).append(" ");
+                strBuilder.append(jon.getString("y")).append(" ");
+                strBuilder.append(jon.getString("z")).append(" ");
+                strBuilder.append(jon.getString("k")).append(" ");
+                strBuilder.append(jon.getString("linkedIds"));
+
+                mergeResult.add(strBuilder.toString());
+        }
+            log.info("json数据转换String完成");
+            return mergeResult;
+    }
+
+    /**
+     * 递归合并
+     */
+    private void recursion(List<List<JSONObject>> param){
+        log.info("需要合并的数据量:{}", param.size());
+        if (param.size() >= 2) {
+            List<JSONObject> mergeRoute = MergeRouteMap.mergeRoute(param.get(0), param.get(1));
+            param.set(0, mergeRoute);
+            param.remove(1);
+
+            // 递归调用
+            recursion(param);
+        }
+    }
+
+
+
+
     @Override
     public void remove(String sceneCode) {
         dataSetMapper.deleteById(sceneCode);
@@ -235,6 +329,7 @@ public class DataSetServiceImpl extends IBaseServiceImpl implements DataSetServi
     }
 
 
+
     private List<DataSetPo> changeSecurityUnLoginList(List<DataSetPo> param){
         List<DataSetPo> result = new ArrayList<>();
         for (DataSetPo dto : param) {

+ 29 - 5
laser/src/main/java/com/fdkankan/indoor/core/service/impl/InitServiceImpl.java

@@ -146,7 +146,7 @@ public class InitServiceImpl implements InitService {
 
         // 路径在这里检测
         if (StrUtil.isBlank(path)) {
-            throw new BaseRuntimeException("路径不能为空");
+            throw new BaseRuntimeException("init.path路径不能为空");
         }
 
         if (StrUtil.isBlank(title)) {
@@ -261,7 +261,7 @@ public class InitServiceImpl implements InitService {
         createConfig(sceneCode);
 
         // step7 创建t_datasets表, 使用的是代码, 需要处理原点之后执行
-        createDataSet(sceneCode, laserDataPath);
+        createDataSet(sceneCode, laserDataPath, controlPoint);
 
 
         // step8 目录pano、pano_depth、webcloud上传oss, 初始化合并场景码跟原来的一样
@@ -413,11 +413,21 @@ public class InitServiceImpl implements InitService {
         entity.setAgeControlLocation1(ageLocation1);
         entity.setAgeControlLocation2(ageLocation2);
 
+        // 2021-08-31
+        entity.setRelativePoint1(gpsCoord1);
+        entity.setRelativePoint2(gpsCoord2);
+
         entity.setId(sceneCode);
         entity.setCreateTime(LocalDateTime.now());
         entity.setStatus(0);
         // 控制点保存方法有很多处理逻辑
-        controlPointService.save(entity, null);
+//        controlPointService.save(entity, null);
+        controlPointService.saveEntity(entity);
+        log.info("算法控制点保存完成");
+
+        // 执行initData2 初始化
+        this.initDataStep2(sceneCode);
+
         log.info("controlPoint控制点初始化完成");
     }
 
@@ -523,7 +533,7 @@ public class InitServiceImpl implements InitService {
         createConfig(sceneCode);
 
         // step7 创建t_datasets表, 使用的是代码, 需要处理原点之后执行
-        createDataSet(sceneCode, laserDataPath);
+        createDataSet(sceneCode, laserDataPath, controlPoint);
 
 
         // step8 目录pano、pano_depth、webcloud上传oss,
@@ -783,7 +793,7 @@ public class InitServiceImpl implements InitService {
      * bounding_box_min:(特殊点表)
      * @param sceneCode
      */
-    private void createDataSet(String sceneCode, String laserDataPath){
+    private void createDataSet(String sceneCode, String laserDataPath, ControlPointEntity controlPoint){
         DataSetEntity entity = new DataSetEntity();
         entity.setId(sceneCode);
         entity.setUpdateTime(LocalDateTime.now());
@@ -820,12 +830,26 @@ public class InitServiceImpl implements InitService {
 
         mergeDto.setPath(laserDataPath);
 
+        // 处理弧度
+        mergeDto.setOrientation(getOrientation(controlPoint));
+
         DataSetPo po = ModifyDataSets.mergeDataSetPo(map, mergeDto);
         entity.setData(Arrays.asList(po));
         dataSetService.save(entity);
         log.info("DataSet数据初始化创建完成");
     }
 
+    /**
+     * 处理弧度
+     * @param controlPoint
+     * @return
+     */
+    private Double getOrientation(ControlPointEntity controlPoint){
+        double angle = GisCoordinateUtil.getAngle(controlPoint);
+        log.info("Orientation弧度:{}", angle);
+        return angle;
+    }
+
     private void createConfig(String sceneCode){
 
         // 根据场景码查询特殊点

+ 5 - 0
laser/src/main/java/com/fdkankan/indoor/core/service/impl/MergeInfoServiceImpl.java

@@ -60,4 +60,9 @@ public class MergeInfoServiceImpl extends IBaseServiceImpl implements MergeInfoS
         entityMapper.deleteBySceneCode(sceneCode);
     }
 
+    @Override
+    public MergeInfoEntity findBySceneCodeAndDataSetId(String sceneCode, Integer dataSetId) {
+        return entityMapper.findBySceneCodeAndDataSetId(sceneCode,dataSetId);
+    }
+
 }

+ 19 - 2
laser/src/main/java/com/fdkankan/indoor/core/service/impl/MergeSceneServiceImpl.java

@@ -1,10 +1,12 @@
 package com.fdkankan.indoor.core.service.impl;
 
+import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
 import com.fdkankan.indoor.base.constant.ConfigConstant;
 import com.fdkankan.indoor.base.constant.MsgCode;
 import com.fdkankan.indoor.base.constant.TypeConstant;
 import com.fdkankan.indoor.base.convert.ConvertToVision;
+import com.fdkankan.indoor.base.convert.GisCoordinateUtil;
 import com.fdkankan.indoor.base.convert.ModifyCloud;
 import com.fdkankan.indoor.base.convert.ModifyDataSets;
 import com.fdkankan.indoor.base.exception.BaseRuntimeException;
@@ -101,7 +103,7 @@ public class MergeSceneServiceImpl extends IBaseServiceImpl implements MergeScen
 
         // dateSet.siteModelId是数组, 如果siteModel的模板id改了,这里要重新设置
         List<Integer> siteModeIds = Arrays.asList(10,11, siteModelId);
-        Integer dataSetId = mergeDateSet(sceneCode, mergeCode, siteModeIds, mergePath);
+        Integer dataSetId = mergeDateSet(sceneCode, mergeCode, siteModeIds, mergePath, controlPoint);
 
 
         mergeFilter(sceneCode, mergeCode, controlPoint, mergePath, siteModelId, dataSetId);
@@ -219,7 +221,7 @@ public class MergeSceneServiceImpl extends IBaseServiceImpl implements MergeScen
 
 
 
-    private Integer  mergeDateSet(String sceneCode, String mergeCode, List<Integer> siteModeIds, String mergePath){
+    private Integer  mergeDateSet(String sceneCode, String mergeCode, List<Integer> siteModeIds, String mergePath, ControlPointEntity controlPoint){
 
         // 获取原场景数据
         DataSetEntity entity = dataSetService.findById(sceneCode);
@@ -251,6 +253,13 @@ public class MergeSceneServiceImpl extends IBaseServiceImpl implements MergeScen
         mergePath = StrUtil.subBefore(mergePath, "/results", true);
 
         mergeDto.setPath(mergePath);
+        // 处理弧度
+        double angle = GisCoordinateUtil.getAngle(controlPoint);
+        log.info("Orientation弧度:{}", angle);
+        mergeDto.setOrientation(angle);
+
+
+        mergeDto.setColor(getColor());
 
 
 
@@ -311,6 +320,14 @@ public class MergeSceneServiceImpl extends IBaseServiceImpl implements MergeScen
 
     }
 
+    // 获取随机色
+    private String getColor(){
+        String[] a = {"red", "blue", "green", "yellow", "purple", "orange", "gold", "gray", "olive"};
+        List<String> strings = Arrays.asList(a);
+        int i = RandomUtil.randomInt(a.length);
+
+        return strings.get(i);
+    }
 
     private Map<Object, Object>  mergeSiteModel(String sceneCode, String mergeCode, String mergePath, ControlPointEntity controlPoint){
 

+ 21 - 3
laser/src/main/java/com/fdkankan/indoor/core/service/impl/TiledMapServiceImpl.java

@@ -79,19 +79,37 @@ public class TiledMapServiceImpl extends IBaseServiceImpl implements TiledMapSer
      */
     private List<TiledMapDto> editData(TiledEditDto param){
         TiledMapDto dto = new TiledMapDto();
-        dto.setId(5);
-        dto.setBundle_id(3);
+        dto.setId(1);
+        // 默认1
+        dto.setBundle_id(1);
         // 小地图oss路径
-
+        /**
+         * data/bundle/building_1/map_tiles/11
+         * building_1: bundle_id值
+         * 11:floor_id值
+         */
         dto.setFile_path("data/building_1/map");
         dto.setFile_name("$DEPTH/$X/$Y.png");
         dto.setFloor_id(11);
+        /**
+         * /阿里云-四维时代-官网测试服务器-120.25.146.52
+         * /mnt/data/00001001/882599154956632064/7ca7b00be91d_202109011208264440/results/laserData/cover
+         * 根据目录的大小填写,0-5 取最大值
+         * 0:256*256
+         * 1:512*512
+         * 2:1024*1024
+         * 3:2048*2048
+         * 4:4096*4096
+         */
         dto.setMax_depth(3);
         dto.setQuadtree("fccf7fffcff3bf7f");
         dto.setType("TILED_PYRAMID");
         dto.setTile_size_px(256);
+        // 前端提供
         dto.setMap_size_m(param.getMap_size_m());
+        // 使用dataSet.location
         dto.setLocation(param.getLocation());
+        // 前端提供
         dto.setOrientation(param.getOrientation());
         List<TiledMapDto> list = new ArrayList<>();
         list.add(dto);

+ 12 - 0
laser/src/main/java/com/fdkankan/indoor/test/Demo.java

@@ -1,11 +1,14 @@
 package com.fdkankan.indoor.test;
 
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.RandomUtil;
 import com.alibaba.fastjson.JSONArray;
 import org.junit.Test;
 import org.springframework.util.ResourceUtils;
 
 import java.io.FileNotFoundException;
+import java.util.Arrays;
+import java.util.List;
 
 /**
  * Created by owen on 2021/7/15 0015 15:50
@@ -33,4 +36,13 @@ public class Demo {
         System.out.println(path);
 
     }
+
+    @Test
+    public void testColor(){
+        String[] a = {"red", "blue", "green", "yellow", "purple", "orange", "white", "black"};
+        List<String> strings = Arrays.asList(a);
+        int i = RandomUtil.randomInt(a.length);
+
+        System.out.println(strings.get(i));
+    }
 }