GeoUtilities.hpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2010, LABUST, UNIZG-FER
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of the LABUST nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  *********************************************************************/
00034 #ifndef GEOUTILITIES_HPP_
00035 #define GEOUTILITIES_HPP_
00036 #define _USE_MATH_DEFINES
00037 #include <utility>
00038 #include <math.h>
00039 #include <Eigen/Dense>
00040 
00041 namespace labust
00042 {
00046         namespace tools
00047         {
00049                 static const double deg2rad = M_PI/180;
00050                 static const double rad2deg = 180/M_PI;
00051                 static const double radius = 6378137;
00052                 static const double ratio = 0.99664719;
00053 
00059                 inline double mpdlat(double lat)
00060                 {
00061                         return (111132.954 - 559.822*cos(2*lat*deg2rad) + 1.175*cos(4*lat*deg2rad));
00062                 };
00068                 inline double mpdlon(double lat)
00069                 {
00070                         return (radius*cos(atan(ratio*tan(lat*deg2rad)))*deg2rad);
00071                 };
00081                 inline std::pair<double,double> deg2meter(double difflat, double difflon, double lat)
00082                                 {
00083                         return std::pair<double,double>(difflat*mpdlat(lat),difflon*mpdlon(lat));
00084                                 }
00094                 inline std::pair<double,double> meter2deg(double x, double y, double lat)
00095                                 {
00096                         return std::pair<double,double>(x/mpdlat(lat),y/mpdlon(lat));
00097                                 };
00098 
00099 
00100 
00111 
00112                 static const double a = 6378137;
00114                 static const double f = 1/298.257223563;
00116                 static const double b = a*(1-f);
00118                 static const double esq = 2*f-f*f;
00120                 static const double ecsq = (a*a - b*b)/(b*b);
00121 
00122 
00129                 inline Eigen::Vector3d geodetic2ecef(const Eigen::Vector3d& geo)
00130                 {
00131                         enum {lon=0, lat, alt};
00132                         double rlat(geo(lat)*M_PI/180);
00133                         double rlon(geo(lon)*M_PI/180);
00134                         double R = a/sqrt(1-esq*sin(rlat)*sin(rlat));
00135 
00136                         return Eigen::Vector3d(
00137                                         (R+geo(alt))*cos(rlat)*cos(rlon),
00138                                         (R+geo(alt))*cos(rlat)*sin(rlon),
00139                                         (R+geo(alt) - esq*R)*sin(rlat));
00140                 }
00141 
00149                 inline Eigen::Vector3d ecef2geodetic(const Eigen::Vector3d& xyz)
00150                 {
00151                         double x(xyz(0)), y(xyz(1)), z(xyz(2));
00152 
00153                         double r = sqrt(x*x + y*y);
00154                         double F = 54*(b*b)*(z*z);
00155                         double G = r*r + (1-esq)*z*z - esq*(a*a - b*b);
00156                         double c = esq*esq*F*r*r/(G*G*G);
00157                         double s = cbrt(1+c+sqrt(c*c+2*c));
00158                         double P = F/(3*(s+1/s+1)*(s+1/s+1)*G*G);
00159                         double Q = sqrt(1+2*esq*esq*P);
00160                         double r0 = -P*esq*r/(1+Q) + sqrt(0.5*a*a*(1+1/Q)
00161                                         - P*(1-esq)*z*z/(Q*(1+Q)) - 0.5*P*r*r);
00162                         double re = r-esq*r0;
00163                         double U = sqrt(re*re + z*z);
00164                         double V = sqrt(re*re + (1-esq)*z*z);
00165                         double z0 = b*b*z/(a*V);
00166 
00167                         return Eigen::Vector3d(
00168                                         atan2(y,x)*180/M_PI,
00169                                         atan((z+ecsq*z0)/r)*180/M_PI,
00170                                         U*(1-b*b/(a*V)));
00171                 }
00172 
00174                 inline Eigen::Matrix3d nedrot(const Eigen::Vector3d& geo)
00175                 {
00176                         enum {lon=0, lat, alt};
00177                         double rlat(geo(lat)*M_PI/180);
00178                         double rlon(geo(lon)*M_PI/180);
00179 
00180 //                      Eigen::Matrix3d rot;
00181 //                      rot<<-sin(rlat)*cos(rlon), -sin(rlon), -cos(rlon)*cos(rlat),
00182 //                                      -sin(rlon)*sin(rlat),   -cos(rlon), -sin(rlon)*cos(rlat),
00183 //                                      cos(rlat),0,-sin(rlat);
00184 
00185                         double pitch = M_PI/2 + rlat;
00186                         double yaw = -rlon;
00187 
00188                         Eigen::Matrix3d rz, ry;
00189                         rz << cos(yaw), sin(yaw),0,
00190                                         -sin(yaw), cos(yaw), 0,
00191                                         0, 0, 1;
00192                         ry << cos(pitch), 0, -sin(pitch),
00193                                         0,1,0,
00194                                         sin(pitch), 0, cos(pitch);
00195 
00196 //                      return rot;
00197                         return rz*ry;
00198                 }
00199 
00201                 inline Eigen::Matrix3d nwurot(const Eigen::Vector3d& geo)
00202                 {
00203                         enum {lon=0, lat, alt};
00204                         double rlat(geo(lat)*M_PI/180);
00205                         double rlon(geo(lon)*M_PI/180);
00206 
00207 //                      Eigen::Matrix3d rot;
00208 //                      rot<<-sin(rlat)*cos(rlon), -sin(rlon), -cos(rlon)*cos(rlat),
00209 //                                      -sin(rlon)*sin(rlat),   -cos(rlon), -sin(rlon)*cos(rlat),
00210 //                                      cos(rlat),0,-sin(rlat);
00211 
00212                         double roll = M_PI/2 - rlat;
00213                         double yaw = M_PI+rlon;
00214 
00215                         Eigen::Matrix3d rz, rx;
00216                         rz << cos(yaw), sin(yaw),0,
00217                                         -sin(yaw), cos(yaw), 0,
00218                                         0, 0, 1;
00219                         rx << 1, 0 ,0,
00220                                   0, cos(roll), sin(roll),
00221                                   0, -sin(roll),cos(roll);
00222 
00223 //                      return rot;
00224                         return rz*rx;
00225                 }
00226 
00230                 inline Eigen::Vector3d ecef2ned(const Eigen::Vector3d& xyz, const Eigen::Vector3d& geo)
00231                 {
00232                         Eigen::Vector3d xyz0 = geodetic2ecef(geo);
00233                         Eigen::Matrix3d mrot = nedrot(geo);
00234                         return mrot.transpose() * (xyz - xyz0);
00235                 }
00236 
00240                 inline Eigen::Vector3d ned2ecef(const Eigen::Vector3d& ned, const Eigen::Vector3d& geo)
00241                 {
00242                         Eigen::Vector3d xyz0 = geodetic2ecef(geo);
00243                         Eigen::Matrix3d mrot = nedrot(geo);
00244                         return mrot * ned + xyz0;
00245                 }
00246         }
00247 }
00248 /* GEOUTILITIES_HPP_ */
00249 #endif


snippets
Author(s): Gyula Nagy
autogenerated on Fri Aug 28 2015 11:22:33