关于WGS80经纬度坐标选定原点转UTM平面坐标的几种测试

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米。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值