SLAM 中地理计算库 GeographicLib 极简入门 (Ubuntu 18.04 c++例子)

  • Post author:
  • Post category:其他


地理计算库 GeographicLib 极简入门

  • 时间:

    20210412



1. 文档


2. 安装
  • 克隆源码并编译安装 GeographicLib 。 (

    码云

    镜像更快,已有较多人转储,不用自己导入,如需自己导入,参考

    gitee文档

    )。

    git clone https://gitee.com/masonqin/geographiclib.git
    cd geographiclib
    mkdir build && cd build
    cmake .. #无报错
    make #无报错
    sudo make install #无报错
    


3. 项目集成
  • 编写


    CMakeLists.txt


    ,非常简单的老三句。

    find_package (GeographicLib REQUIRED)
    include_directories(${GeographicLib_INCLUDE_DIRS})
    target_link_libraries(<可执行程序> ${GeographicLib_LIBRARIES})
    
  • 代码集成,

    最常用的功能

    ,使用局部坐标系转换,从

    经纬高



    ENU

    #include <GeographicLib/LocalCartesian.hpp> //包含头文件
    //经纬度原点初始化
    GeographicLib::LocalCartesian geo_converter;
    geo_converter.Reset(latitude, longitude, altitude);
    //经纬度转ENU
    geo_converter.Forward(latitude, longitude, altitude, local_E, local_N, local_U);
    

  • 初始化原点

    用了

    Reset

    函数,

    Forward

    用于将

    经纬高转换成米制坐标[E,N,U]

    。俩函数都是调用 geo_converter 对象的成员函数,geo_converter 就是

    GeographicLib::LocalCartesian

    的实例。


    • GeographicLib::LocalCartesian

      简介,

      官方文档

      • 功能就是把椭球体下的地理坐标系坐标转为ENU局部系下的坐标。
      • Reset 函数的作用是重置原点,LocalCartesian构造函数是默认在(0,0,0)也就是地心。
      • Forward (lat, lon, alt, x, y, z)函数就是把经纬高转换为ENU,前三个

        传入

        ,后三个

        传出



4. 极简的例子
  • 新建

    geographiclib_demo

    文件夹,在里面新建

    CMakeLists.txt



    main.cpp


  • main.cpp

    ,经纬度数据转ENU米制坐标,数据文件为

    lonlat.csv

    ,格式为**[纬度,经度,高度]**。

    #include <iostream>
    #include <vector>
    #include <string>
    #include <fstream>
    #include <sstream>
    #include <GeographicLib/LocalCartesian.hpp> //header file
    
    typedef std::vector<std::vector<double>> dataMat_NxN;
    
    void ReadCSV(std::string str_csv_file, dataMat_NxN &data_NxN)
    {
        std::ifstream in_file(str_csv_file, std::ios::in);
        std::string std_line;
        while (getline(in_file, std_line))
        {
            std::stringstream ss(std_line);
            std::string data_each;
            std::vector<double> data_array;
            while (getline(ss, data_each, ','))
            {
                data_array.push_back(atof(data_each.c_str()));
            }
            data_NxN.push_back(data_array);
        }
    }
    
    void WriteDat(std::string str_dat_file, dataMat_NxN &data_NxN)
    {
        std::ofstream out_file(str_dat_file, std::ios::out);
        for (int i = 0; i < data_NxN.size(); ++i)
        {
            for (int j = 0; j < data_NxN[i].size(); ++j)
            {
                out_file << data_NxN[i][j]<<" ";
            }
            out_file << "\n";
        }
    }
    
    int main()
    {
        std::cout << "Demo program of GeographicLib." << std::endl;
        // geo origin init
        GeographicLib::LocalCartesian geo_converter;
        // data structure define
        dataMat_NxN geo_data;
        dataMat_NxN ENU_data;
        // read data from file
        std::string str_geo_data = "../lonlat.csv";//lat,lon,h
        ReadCSV(str_geo_data, geo_data);
        if (geo_data.size() > 0)
        {
            if (geo_data[0].size() == 3)
            {
                geo_converter.Reset(geo_data[0][0], geo_data[0][1], geo_data[0][2]);
                for (int i = 0; i < geo_data.size(); ++i)
                {
                    double local_E, local_N, local_U;
                    // convert[lat,lon,hgt] to ENU
                    geo_converter.Forward(geo_data[i][0], geo_data[i][1], geo_data[i][2], local_E, local_N, local_U);
                    std::vector<double> data_each;
                    data_each.emplace_back(local_E);
                    data_each.emplace_back(local_N);
                    data_each.emplace_back(local_U);
                    ENU_data.emplace_back(data_each);
                    std::cout << "i=" << i << std::endl;
                }
            }
        }
        std::string str_ENU_data = "../enu.dat";//e,n,u
        WriteDat(str_ENU_data, ENU_data);
        return 0;
    }
    


  • CMakeLists.txt


    文件

    cmake_minimum_required(VERSION 3.10)
    project(geographiclib_demo)
    
    set(CMAKE_CXX_STANDARD 14)
    
    find_package (GeographicLib REQUIRED)
    include_directories(${GeographicLib_INCLUDE_DIRS})
    
    add_executable(geographiclib_demo main.cpp)
    target_link_libraries(geographiclib_demo ${GeographicLib_LIBRARIES})
    
  • 编译 & 执行

    git clone https://gitee.com/jqf64078/geographiclib_demo.git
    cd geographiclib_demo
    mkdir build && cd build
    cmake ..
    make
    ./geographiclib_demo
    
  • 转换ENU米制坐标结果绘制,matlab 绘制。

    enu_data = load('enu.dat');
    plot(enu_data(:,1),enu_data(:,2));grid on;xlabel('East'),ylabel('North');
    
  • csv 文件格式,程序只是简单地定义 [纬度,经度,高度] 如下所示的格式进行读取。

    lat, lon, h,

    lat, lon, h,

    lat, lon, h,



版权声明:本文为sinat_25923849原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。