Browse Source

add pcd2geojson project

lijinliang 3 years ago
parent
commit
ed8386c3d2

+ 2 - 1
src/tool/opendriveParser/convert_opendrive.py

@@ -835,7 +835,8 @@ class ConvertOpenDrive:
             
 if __name__ == "__main__":
 
-    xodr_file = r'map_xiali.xodr'
+    # xodr_file = r'map_xiali.xodr'
+    xodr_file = r'meta8.xodr'
     opendrive = opendrive_parser.parse(xodr_file, silence=True)
 
     convert = ConvertOpenDrive(opendrive, 0.5)

+ 1 - 0
src/tool/opendriveParser/readme.md

@@ -20,4 +20,5 @@ convert = ConvertOpenDrive(opendrive, 0.5)
 
 convert.json_all_baseroad(r'./tmp/all_baseroad_new.json')
 ```
+> convert_opendrive.py
 

+ 165 - 0
src/tool/tool_pcd2Geojson/main.cpp

@@ -0,0 +1,165 @@
+#include <pcl/visualization/cloud_viewer.h>
+#include <iostream>
+#include <pcl/io/io.h>
+#include <pcl/io/pcd_io.h>
+#include <QCoreApplication>
+#include <QVector>
+#include <thread>
+#include <chrono>
+#include <qjsondocument.h>
+#include <qjsonobject.h>
+#include <QJsonArray>
+#include <QDebug>
+#include <QFile>
+//#include "modulecomm.h"
+#include "mathlocation.h"
+#include <getopt.h>
+
+char gstr_mapname[256];
+char gstr_xmlpath[256];
+char gstr_logpath[256];
+
+void print_useage()
+{
+    std::cout<<" -p --pcd $pcdpath : map path. eq.  -p /home/nvidia/map/gpu.pcd"<<std::endl;
+    std::cout<<" -h --help print help"<<std::endl;
+}
+
+int  GetOptLong(int argc, char *argv[]) {
+    int nRtn = 0;
+    int opt; // getopt_long() 的返回值
+    int digit_optind = 0; // 设置短参数类型及是否需要参数
+
+    // 如果option_index非空,它指向的变量将记录当前找到参数符合long_opts里的
+    // 第几个元素的描述,即是long_opts的下标值
+    int option_index = 0;
+    // 设置短参数类型及是否需要参数
+    const char *optstring = "p:h";
+
+    // 设置长参数类型及其简写,比如 --reqarg <==>-r
+    /*
+    struct option {
+             const char * name;  // 参数的名称
+             int has_arg; // 是否带参数值,有三种:no_argument, required_argument,optional_argument
+             int * flag; // 为空时,函数直接将 val 的数值从getopt_long的返回值返回出去,
+                     // 当非空时,val的值会被赋到 flag 指向的整型数中,而函数返回值为0
+             int val; // 用于指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值
+        };
+    其中:
+        no_argument(即0),表明这个长参数不带参数(即不带数值,如:--name)
+            required_argument(即1),表明这个长参数必须带参数(即必须带数值,如:--name Bob)
+            optional_argument(即2),表明这个长参数后面带的参数是可选的,(即--name和--name Bob均可)
+     */
+    static struct option long_options[] = {
+        {"pcdpath", required_argument, NULL, 'p'},
+        {"help",  no_argument,       NULL, 'h'},
+ //       {"optarg", optional_argument, NULL, 'o'},
+        {0, 0, 0, 0}  // 添加 {0, 0, 0, 0} 是为了防止输入空值
+    };
+    strncpy(gstr_mapname,"/home/nvidia/BorregasAve.pcd",255);
+    while ( (opt = getopt_long(argc,
+                               argv,
+                               optstring,
+                               long_options,
+                               &option_index)) != -1) {
+//        printf("opt = %c\n", opt); // 命令参数,亦即 -a -b -n -r
+//        printf("optarg = %s\n", optarg); // 参数内容
+//        printf("optind = %d\n", optind); // 下一个被处理的下标值
+//        printf("argv[optind - 1] = %s\n",  argv[optind - 1]); // 参数内容
+//        printf("option_index = %d\n", option_index);  // 当前打印参数的下标值
+//        printf("\n");
+        switch(opt)
+        {
+        case 'p':
+            strncpy(gstr_mapname,optarg,255);
+            break;
+        case 'h':
+            print_useage();
+            nRtn = 1; //because use -h
+            break;
+        default:
+            break;
+        }
+
+    }
+
+    return nRtn;
+}
+int writeFile(QJsonObject obj)
+{
+    QByteArray baframe;
+    QString filename = "/home/nvidia/pointCloud.json";
+    QFile xFile(filename);
+    if(!xFile.open(QIODevice::QIODevice::WriteOnly))
+    {
+        std::cout<<" File Fail."<<std::endl;
+        return -1;
+    }
+
+    baframe = QJsonDocument(obj).toJson();
+    int result = xFile.write(baframe);
+    xFile.close();
+    return result;
+}
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication a(argc, argv);
+
+    snprintf(gstr_mapname,255,"");
+
+    int nRtn = GetOptLong(argc,argv);
+    if(nRtn == 1)  //show help,so exit.
+    {
+        return 0;
+    }
+
+
+    pcl::PointCloud<pcl::PointXYZI>::Ptr point_cloud(
+                new pcl::PointCloud<pcl::PointXYZI>());
+    std::string path = gstr_mapname;
+
+    if(path.length() < 1)
+    {
+        std::cout<<"Please use -p set pcd path."<<std::endl;
+        return 0;
+    }
+
+    pcl::io::loadPCDFile<pcl::PointXYZI>(path,*point_cloud);
+
+
+    double lat = 39.12072740;
+    double lon= 117.02800329;
+    double latx,lonx;
+    double x,y;
+    GaussProjCal(lon, lat, &x, &y);
+
+    QJsonArray dataArray,featureArry;
+    QJsonObject dataObj,properObj,geoObj,obj;
+    dataObj.insert("type",QJsonValue("Feature"));
+    properObj.insert("color",QJsonValue("#111111"));
+    dataObj.insert("properties",QJsonValue(properObj));
+    geoObj.insert("type",QJsonValue("MultiPoint"));
+
+    int size = point_cloud->size();
+    for(int i = 0; i < size; i++)
+    {
+        QJsonArray arr;
+        GaussProjInvCal(point_cloud->points[i].x+x, point_cloud->points[i].y+y, &lon, &lat);
+        arr.append(QJsonValue(lon));
+        arr.append(QJsonValue(lat));
+        arr.append(QJsonValue(point_cloud->points[i].z));
+        dataArray.append(QJsonValue(arr));
+        qDebug()<<arr;
+    }
+    geoObj.insert("coordinates",QJsonValue(dataArray));
+    dataObj.insert("geometry",geoObj);
+    featureArry.append(QJsonValue(dataObj));
+    obj.insert("type",QJsonValue("FeatureCollection"));
+    obj.insert("features",QJsonValue(featureArry));
+    int result = writeFile(obj);
+    qDebug("Convert compless, %d point has been writed",result);
+
+    return a.exec();
+}
+

+ 76 - 0
src/tool/tool_pcd2Geojson/mathlocation.cpp

@@ -0,0 +1,76 @@
+#include "mathlocation.h"
+
+//高斯投影由经纬度(Unit:DD)反算大地坐标(含带号,Unit:Metres)
+void GaussProjCal(double longitude, double latitude, double *X, double *Y)
+{
+    int ProjNo = 0; int ZoneWide; ////带宽
+    double longitude1, latitude1, longitude0, latitude0, X0, Y0, xval, yval;
+    double a, f, e2, ee, NN, T, C, A, M, iPI;
+    iPI = 0.0174532925199433; ////3.1415926535898/180.0;
+    ZoneWide = 6; ////6度带宽
+    a = 6378245.0; f = 1.0 / 298.3; //54年北京坐标系参数
+                                    ////a=6378140.0; f=1/298.257; //80年西安坐标系参数
+    ProjNo = (int)(longitude / ZoneWide);
+    longitude0 = ProjNo * ZoneWide + ZoneWide / 2;
+    longitude0 = longitude0 * iPI;
+    latitude0 = 0;
+    longitude1 = longitude * iPI; //经度转换为弧度
+    latitude1 = latitude * iPI; //纬度转换为弧度
+    e2 = 2 * f - f * f;
+    ee = e2 * (1.0 - e2);
+    NN = a / sqrt(1.0 - e2 * sin(latitude1)*sin(latitude1));
+    T = tan(latitude1)*tan(latitude1);
+    C = ee * cos(latitude1)*cos(latitude1);
+    A = (longitude1 - longitude0)*cos(latitude1);
+    M = a * ((1 - e2 / 4 - 3 * e2*e2 / 64 - 5 * e2*e2*e2 / 256)*latitude1 - (3 * e2 / 8 + 3 * e2*e2 / 32 + 45 * e2*e2
+        *e2 / 1024)*sin(2 * latitude1)
+        + (15 * e2*e2 / 256 + 45 * e2*e2*e2 / 1024)*sin(4 * latitude1) - (35 * e2*e2*e2 / 3072)*sin(6 * latitude1));
+    xval = NN * (A + (1 - T + C)*A*A*A / 6 + (5 - 18 * T + T * T + 72 * C - 58 * ee)*A*A*A*A*A / 120);
+    yval = M + NN * tan(latitude1)*(A*A / 2 + (5 - T + 9 * C + 4 * C*C)*A*A*A*A / 24
+        + (61 - 58 * T + T * T + 600 * C - 330 * ee)*A*A*A*A*A*A / 720);
+    X0 = 1000000L * (ProjNo + 1) + 500000L;
+    Y0 = 0;
+    xval = xval + X0; yval = yval + Y0;
+    *X = xval;
+    *Y = yval;
+}
+
+//高斯投影由大地坐标(Unit:Metres)反算经纬度(Unit:DD)
+void GaussProjInvCal(double X, double Y, double *longitude, double *latitude)
+{
+    int ProjNo; int ZoneWide; ////带宽
+    double longitude1, latitude1, longitude0, latitude0, X0, Y0, xval, yval;
+    double e1, e2, f, a, ee, NN, T, C, M, D, R, u, fai, iPI;
+    iPI = 0.0174532925199433; ////3.1415926535898/180.0;
+    a = 6378245.0; f = 1.0 / 298.3; //54年北京坐标系参数
+    ////a=6378140.0; f=1/298.257; //80年西安坐标系参数
+    ZoneWide = 6; ////6度带宽
+    ProjNo = (int)(X / 1000000L); //查找带号
+    longitude0 = (ProjNo - 1) * ZoneWide + ZoneWide / 2;
+    longitude0 = longitude0 * iPI; //中央经线
+    X0 = ProjNo * 1000000L + 500000L;
+    Y0 = 0;
+    xval = X - X0; yval = Y - Y0; //带内大地坐标
+    e2 = 2 * f - f * f;
+    e1 = (1.0 - sqrt(1 - e2)) / (1.0 + sqrt(1 - e2));
+    ee = e2 / (1 - e2);
+    M = yval;
+    u = M / (a*(1 - e2 / 4 - 3 * e2*e2 / 64 - 5 * e2*e2*e2 / 256));
+    fai = u + (3 * e1 / 2 - 27 * e1*e1*e1 / 32)*sin(2 * u) + (21 * e1*e1 / 16 - 55 * e1*e1*e1*e1 / 32)*sin(
+                4 * u)
+            + (151 * e1*e1*e1 / 96)*sin(6 * u) + (1097 * e1*e1*e1*e1 / 512)*sin(8 * u);
+    C = ee * cos(fai)*cos(fai);
+    T = tan(fai)*tan(fai);
+    NN = a / sqrt(1.0 - e2 * sin(fai)*sin(fai));
+    R = a * (1 - e2) / sqrt((1 - e2 * sin(fai)*sin(fai))*(1 - e2 * sin(fai)*sin(fai))*(1 - e2 * sin
+                                                                                       (fai)*sin(fai)));
+    D = xval / NN;
+    //计算经度(Longitude) 纬度(Latitude)
+    longitude1 = longitude0 + (D - (1 + 2 * T + C)*D*D*D / 6 + (5 - 2 * C + 28 * T - 3 * C*C + 8 * ee + 24 * T*T)*D
+                               *D*D*D*D / 120) / cos(fai);
+    latitude1 = fai - (NN*tan(fai) / R)*(D*D / 2 - (5 + 3 * T + 10 * C - 4 * C*C - 9 * ee)*D*D*D*D / 24
+                                         + (61 + 90 * T + 298 * C + 45 * T*T - 256 * ee - 3 * C*C)*D*D*D*D*D*D / 720);
+    //转换为度 DD
+    *longitude = longitude1 / iPI;
+    *latitude = latitude1 / iPI;
+}

+ 11 - 0
src/tool/tool_pcd2Geojson/mathlocation.h

@@ -0,0 +1,11 @@
+#ifndef MATHLOCATION_H
+#define MATHLOCATION_H
+#include <math.h>
+
+//高斯投影由经纬度(Unit:DD)反算大地坐标(含带号,Unit:Metres)
+void GaussProjCal(double longitude, double latitude, double *X, double *Y);
+
+//高斯投影由大地坐标(Unit:Metres)反算经纬度(Unit:DD)
+void GaussProjInvCal(double X, double Y, double *longitude, double *latitude);
+
+#endif // MATHLOCATION_H

+ 58 - 0
src/tool/tool_pcd2Geojson/tool_pcd2Geojson.pro

@@ -0,0 +1,58 @@
+QT -= gui
+
+CONFIG += c++11 console
+CONFIG -= app_bundle
+
+QMAKE_LFLAGS += -no-pie
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+QMAKE_LFLAGS += -no-pie
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += main.cpp \
+    mathlocation.cpp
+
+INCLUDEPATH += /opt/ros/kinetic/include
+INCLUDEPATH += /usr/include/pcl-1.8
+INCLUDEPATH += /usr/include/pcl-1.7
+INCLUDEPATH += /usr/include/eigen3
+INCLUDEPATH += /usr/include/vtk-6.3
+INCLUDEPATH += /usr/include/vtk-6.2
+
+unix:LIBS +=  -lpcl_common\
+        -lpcl_features\
+        -lpcl_filters\
+        -lpcl_io\
+        -lpcl_io_ply\
+        -lpcl_kdtree\
+        -lpcl_keypoints\
+        -lpcl_octree\
+        -lpcl_outofcore\
+        -lpcl_people\
+        -lpcl_recognition\
+        -lpcl_registration\
+        -lpcl_sample_consensus\
+        -lpcl_search\
+        -lpcl_segmentation\
+        -lpcl_surface\
+        -lpcl_tracking\
+        -lpcl_visualization
+
+#INCLUDEPATH += $$PWD/../../../include/
+#LIBS += -L$$PWD/../../../bin/ -lxmlparam -lmodulecomm -livlog -livfault
+
+LIBS += -lboost_system
+#LIBS += -lvtkCommonExecutionModel-6.3 -lvtkCommonCore-6.3 -lvtkRenderingLOD-6.3 -lvtkRenderingCore-6.3 \
+#        -lvtkFiltersSources-6.3
+
+HEADERS += \
+    mathlocation.h

+ 1 - 0
src/tool/view_pcdmap/main.cpp

@@ -26,6 +26,7 @@ int  GetOptLong(int argc, char *argv[]) {
     int opt; // getopt_long() 的返回值
     int digit_optind = 0; // 设置短参数类型及是否需要参数
 
+    strncpy(gstr_mapname,"/home/nvidia/BorregasAve.pcd",255);
     // 如果option_index非空,它指向的变量将记录当前找到参数符合long_opts里的
     // 第几个元素的描述,即是long_opts的下标值
     int option_index = 0;