地理计算库 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,
…