1.采用geodesy库
geographic_msgs::GeoPoint gp;
gp.latitude = gpchc_msg_ptr->Lattitude;
gp.longitude = gpchc_msg_ptr->Longitude;
gp.altitude = gpchc_msg_ptr->Altitude;
geodesy::UTMPoint pt(gp);
utm_msg.pose.pose.position.x=pt.easting-317085.167245;
utm_msg.pose.pose.position.y=pt.northing-3817156.83425;
std::cout<<"enu1:"<<std::setprecision(16)<<utm_msg.pose.pose.position.x<<","<<utm_msg.pose.pose.position.y <<std::endl;
2.采用GeographicLib
double RefLat = 34.47979222;
double RefLon = 109.00815992;
double projection_y0_ = 0;
const GeographicLib::TransverseMercator projection_;
double x0;
projection_.Forward(RefLon, RefLat,RefLon, x0, projection_y0_);
double x, y, gamma, k;
projection_.Forward(RefLon, gpchc_msg_ptr->Lattitude, gpchc_msg_ptr->Longitude, x, y,gamma, k);
std::cout<<"enu2:"<<std::setprecision(16)<<x <<","<<y - projection_y0_ <<std::endl;
3.采用GeographicLib
头文件:
#ifndef WGS2UTM_H
#define WGS2UTM_H
#include <iostream>
#include <fstream>
#include <vector>
#include <Eigen/Geometry>
#include <GeographicLib/UTMUPS.hpp>
#include <geographic_msgs/GeoPointStamped.h>
#include <geodesy/utm.h>
#include <ros/ros.h>
using namespace std;
class WGS2UTM
{
public:
/**
* @brief 构造函数
*/
WGS2UTM(){}
/**
* @brief 获取选取原点的经纬度lla坐标
* @return 所选取原点的经纬度lla坐标
*/
inline Eigen::Vector3d get_origin_lla()
{
return origin_LLA_;
}
/**
* @brief 获取选取原点的经纬度utm坐标
* @return 所选取原点的经纬度utm坐标
*/
inline Eigen::Vector3d get_origin_tum()
{
return origin_UTM_;
}
/***********************************************************/
/***********************************************************/
/**利用GeographicLib功能包实现WGS84经纬度坐标转化成UTM坐标**/
/***********************************************************/
/***********************************************************/
/**
* @brief 把选取的原点的经纬度lla坐标转化为东北天utm坐标
* @param origin_LLA 输入--原点经纬度lla坐标
*/
void set_origin_2(Eigen::Vector3d origin_LLA);
/**
* @brief 把经纬度lla坐标转化为东北天utm坐标
* @param LLA 输入--lla坐标
* @param UTM 输出--utm坐标
*/
void LLA2UTM_2(const Eigen::Vector3d& LLA, Eigen::Vector3d& UTM);
/**
* @brief 把经纬度lla坐标转化为相对于所选取原点的东北天utm坐标
* @param LLA 输入--lla坐标
* @param UTM 输出--utm坐标
*/
void LLA2UTM_origin_2(const Eigen::Vector3d& LLA, Eigen::Vector3d& UTM_origin);
private:
Eigen::Vector3d origin_LLA_;
Eigen::Vector3d origin_UTM_;
double torad = M_PI / 180;
};
#endif //WGS2UTM_H
源文件:
void WGS2UTM::set_origin_2(Eigen::Vector3d origin_LLA)
{
origin_LLA_ = origin_LLA;
LLA2UTM_2(origin_LLA_, origin_UTM_);
}
void WGS2UTM::LLA2UTM_2(const Eigen::Vector3d& LLA, Eigen::Vector3d& UTM)
{
GeographicLib::Math::real lat = LLA[0];
GeographicLib::Math::real lon = LLA[1];
GeographicLib::Math::real alt = LLA[2];
int UTMZone;
bool isNorth;
GeographicLib::UTMUPS::Forward(lat, lon, UTMZone, isNorth, UTM[0], UTM[1]);
UTM[2] = LLA[2];
}
void WGS2UTM::LLA2UTM_origin_2(const Eigen::Vector3d& LLA, Eigen::Vector3d& UTM_origin)
{
//经纬度转换为UTM投影
Eigen::Vector3d UTM;
LLA2UTM_2(LLA, UTM);
//UTM2ENU, UTM投影平移至东北天坐标系, 东北天坐标系原点为第一个采样点
UTM_origin = UTM - origin_UTM_;
}
WGS2UTM wgs2utm;
Eigen::Vector3d origin_LLA;
Eigen::Vector3d origin_UTM;
origin_LLA[0] = 34.47979222;
origin_LLA[1] = 109.00815992;
origin_LLA[2] = 345.700012207;
wgs2utm.set_origin_2(origin_LLA);
origin_UTM = wgs2utm.get_origin_tum();
std::cout<<"xy0:"<<std::setprecision(16)<< origin_UTM[0] <<","<<origin_UTM[1] <<std::endl;
Eigen::Vector3d P_LLA; // 任意一点的经纬度坐标
Eigen::Vector3d P_UTM; // 该点相对于所选取原点的utm坐标
P_LLA[0] = gpchc_msg_ptr->Lattitude;
P_LLA[1] = gpchc_msg_ptr->Longitude;
P_LLA[2] = gpchc_msg_ptr->Altitude;
wgs2utm.LLA2UTM_origin_2(P_LLA, P_UTM);
std::cout<<"enu3:"<<std::setprecision(16)<<P_UTM[0]<<","<<P_UTM[1] <<std::endl;
测试结果:
enu2:-21.55637298376162,-1.775981625076383
enu3:-21.58742491883459,-1.351323097478598
enu1:-21.61596268927678,-1.354094658978283
enu2:-34.56130186195978,-2.79318039258942
enu3:-34.61002051952528,-2.112335940822959
enu1:-34.64409087330569,-2.11610805336386
enu2:-86.73813263529708,-7.122480107471347
enu3:-86.86262539529707,-5.41375290369615
enu1:-86.89391857566079,-5.416469991672784
可以发现,方式1和方式3的处理结果基本相同,但是对比方式2,y值会有较大偏差,大概在2~3米。