| 1 | // %pacpus:license{
 | 
|---|
| 2 | // This file is part of the PACPUS framework distributed under the
 | 
|---|
| 3 | // CECILL-C License, Version 1.0.
 | 
|---|
| 4 | /// @author  Marek Kurdej <firstname.surname@utc.fr>
 | 
|---|
| 5 | /// @author  Jean Laneurit <firstname.surname@utc.fr>
 | 
|---|
| 6 | /// @date    April, 2010
 | 
|---|
| 7 | // %pacpus:license}
 | 
|---|
| 8 | 
 | 
|---|
| 9 | #include <Pacpus/PacpusTools/geodesie.h>
 | 
|---|
| 10 | 
 | 
|---|
| 11 | #include <fstream>
 | 
|---|
| 12 | #include <QMatrix4x4>
 | 
|---|
| 13 | #include <QVector3D>
 | 
|---|
| 14 | 
 | 
|---|
| 15 | using ::boost::math::constants::pi;
 | 
|---|
| 16 | using ::boost::math::constants::half_pi;
 | 
|---|
| 17 | using ::std::abs;
 | 
|---|
| 18 | using ::std::atan;
 | 
|---|
| 19 | using ::std::exp;
 | 
|---|
| 20 | using ::std::ifstream;
 | 
|---|
| 21 | using ::std::ostream;
 | 
|---|
| 22 | using ::std::log;
 | 
|---|
| 23 | using ::std::sin;
 | 
|---|
| 24 | using ::std::string;
 | 
|---|
| 25 | 
 | 
|---|
| 26 | #ifdef _MSC_VER
 | 
|---|
| 27 | #pragma warning(disable : 4244)
 | 
|---|
| 28 | #endif //_MSC_VER
 | 
|---|
| 29 | 
 | 
|---|
| 30 | namespace Geodesy
 | 
|---|
| 31 | {
 | 
|---|
| 32 | 
 | 
|---|
| 33 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 34 | Matrice::Matrice(const Matrice& A)
 | 
|---|
| 35 | {
 | 
|---|
| 36 |     c0_l0 = A.c0_l0;
 | 
|---|
| 37 |     c1_l0 = A.c1_l0;
 | 
|---|
| 38 |     c2_l0 = A.c2_l0;
 | 
|---|
| 39 |     c0_l1 = A.c0_l1;
 | 
|---|
| 40 |     c1_l1 = A.c1_l1;
 | 
|---|
| 41 |     c2_l1 = A.c2_l1;
 | 
|---|
| 42 |     c0_l2 = A.c0_l2;
 | 
|---|
| 43 |     c1_l2 = A.c1_l2;
 | 
|---|
| 44 |     c2_l2 = A.c2_l2;
 | 
|---|
| 45 | }
 | 
|---|
| 46 | 
 | 
|---|
| 47 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 48 | Matrice::Matrice()
 | 
|---|
| 49 | {
 | 
|---|
| 50 |     c0_l0 = 0.0;
 | 
|---|
| 51 |     c1_l0 = 0.0;
 | 
|---|
| 52 |     c2_l0 = 0.0;
 | 
|---|
| 53 |     c0_l1 = 0.0;
 | 
|---|
| 54 |     c1_l1 = 0.0;
 | 
|---|
| 55 |     c2_l1 = 0.0;
 | 
|---|
| 56 |     c0_l2 = 0.0;
 | 
|---|
| 57 |     c1_l2 = 0.0;
 | 
|---|
| 58 |     c2_l2 = 0.0;
 | 
|---|
| 59 | }
 | 
|---|
| 60 | 
 | 
|---|
| 61 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 62 | void Matrice::Apply(double v0, double v1, double v2, double& Mv0, double& Mv1, double& Mv2)
 | 
|---|
| 63 | {
 | 
|---|
| 64 |     Mv0 = c0_l0 * v0 + c1_l0 * v1 + c2_l0 * v2;
 | 
|---|
| 65 |     Mv1 = c0_l1 * v0 + c1_l1 * v1 + c2_l1 * v2;
 | 
|---|
| 66 |     Mv2 = c0_l2 * v0 + c1_l2 * v1 + c2_l2 * v2;
 | 
|---|
| 67 | }
 | 
|---|
| 68 | 
 | 
|---|
| 69 | Matrice& Matrice::operator*=(Matrice const& other)
 | 
|---|
| 70 | {
 | 
|---|
| 71 |     // TODO: optimize
 | 
|---|
| 72 |     *this = ProdMat(*this, other);
 | 
|---|
| 73 |     return *this;
 | 
|---|
| 74 | }
 | 
|---|
| 75 | 
 | 
|---|
| 76 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 77 | Matrice ProdMat(Matrice const& A, Matrice const& B)
 | 
|---|
| 78 | {
 | 
|---|
| 79 |     Matrice out;
 | 
|---|
| 80 | 
 | 
|---|
| 81 |     out.c0_l0 = A.c0_l0 * B.c0_l0 + A.c1_l0 * B.c0_l1 + A.c2_l0 * B.c0_l2;
 | 
|---|
| 82 |     out.c1_l0 = A.c0_l0 * B.c1_l0 + A.c1_l0 * B.c1_l1 + A.c2_l0 * B.c1_l2;
 | 
|---|
| 83 |     out.c2_l0 = A.c0_l0 * B.c2_l0 + A.c1_l0 * B.c2_l1 + A.c2_l0 * B.c2_l2;
 | 
|---|
| 84 | 
 | 
|---|
| 85 |     out.c0_l1 = A.c0_l1 * B.c0_l0 + A.c1_l1 * B.c0_l1 + A.c2_l1 * B.c0_l2;
 | 
|---|
| 86 |     out.c1_l1 = A.c0_l1 * B.c1_l0 + A.c1_l1 * B.c1_l1 + A.c2_l1 * B.c1_l2;
 | 
|---|
| 87 |     out.c2_l1 = A.c0_l1 * B.c2_l0 + A.c1_l1 * B.c2_l1 + A.c2_l1 * B.c2_l2;
 | 
|---|
| 88 | 
 | 
|---|
| 89 |     out.c0_l2 = A.c0_l2 * B.c0_l0 + A.c1_l2 * B.c0_l1 + A.c2_l2 * B.c0_l2;
 | 
|---|
| 90 |     out.c1_l2 = A.c0_l2 * B.c1_l0 + A.c1_l2 * B.c1_l1 + A.c2_l2 * B.c1_l2;
 | 
|---|
| 91 |     out.c2_l2 = A.c0_l2 * B.c2_l0 + A.c1_l2 * B.c2_l1 + A.c2_l2 * B.c2_l2;
 | 
|---|
| 92 |     return out;
 | 
|---|
| 93 | }
 | 
|---|
| 94 | 
 | 
|---|
| 95 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 96 | Matrice TransMat(Matrice const& A)
 | 
|---|
| 97 | {
 | 
|---|
| 98 |     Matrice out;
 | 
|---|
| 99 |     out.c0_l0 = A.c0_l0;
 | 
|---|
| 100 |     out.c1_l0 = A.c0_l1;
 | 
|---|
| 101 |     out.c2_l0 = A.c0_l2;
 | 
|---|
| 102 |     out.c0_l1 = A.c1_l0;
 | 
|---|
| 103 |     out.c1_l1 = A.c1_l1;
 | 
|---|
| 104 |     out.c2_l1 = A.c1_l2;
 | 
|---|
| 105 |     out.c0_l2 = A.c2_l0;
 | 
|---|
| 106 |     out.c1_l2 = A.c2_l1;
 | 
|---|
| 107 |     out.c2_l2 = A.c2_l2;
 | 
|---|
| 108 |     return out;
 | 
|---|
| 109 | }
 | 
|---|
| 110 | 
 | 
|---|
| 111 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 112 | ostream& operator<<(ostream& os, Matrice const& A)
 | 
|---|
| 113 | {
 | 
|---|
| 114 |     os << A.c0_l0 << "\t" << A.c1_l0 << "\t" << A.c2_l0 << "\n";
 | 
|---|
| 115 |     os << A.c0_l1 << "\t" << A.c1_l1 << "\t" << A.c2_l1 << "\n";
 | 
|---|
| 116 |     os << A.c0_l2 << "\t" << A.c1_l2 << "\t" << A.c2_l2 << "\n";
 | 
|---|
| 117 |     return os;
 | 
|---|
| 118 | }
 | 
|---|
| 119 | 
 | 
|---|
| 120 | void Write(Matrice const& A, ostream& out)
 | 
|---|
| 121 | {
 | 
|---|
| 122 |     out << A;
 | 
|---|
| 123 | }
 | 
|---|
| 124 | 
 | 
|---|
| 125 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 126 | Raf98::Raf98()
 | 
|---|
| 127 | {
 | 
|---|
| 128 | }
 | 
|---|
| 129 | 
 | 
|---|
| 130 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 131 | Raf98::~Raf98()
 | 
|---|
| 132 | {
 | 
|---|
| 133 |     m_dvalues.clear();
 | 
|---|
| 134 | }
 | 
|---|
| 135 | 
 | 
|---|
| 136 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 137 | bool Raf98::Interpol(double longitude, double latitude, double* Hwgs84) const
 | 
|---|
| 138 | {
 | 
|---|
| 139 |     *Hwgs84 = 0.0;
 | 
|---|
| 140 |     if (m_dvalues.size() == 0) {
 | 
|---|
| 141 |         return false;
 | 
|---|
| 142 |     }
 | 
|---|
| 143 |     const double longitude_min = -5.5;
 | 
|---|
| 144 |     const double longitude_max = 8.5;
 | 
|---|
| 145 |     if (longitude < longitude_min) {
 | 
|---|
| 146 |         return false;
 | 
|---|
| 147 |     }
 | 
|---|
| 148 |     if (longitude > longitude_max) {
 | 
|---|
| 149 |         return false;
 | 
|---|
| 150 |     }
 | 
|---|
| 151 |     const double latitude_min = 42;
 | 
|---|
| 152 |     const double latitude_max = 51.5;
 | 
|---|
| 153 |     if (latitude < latitude_min) {
 | 
|---|
| 154 |         return false;
 | 
|---|
| 155 |     }
 | 
|---|
| 156 |     if (latitude > latitude_max) {
 | 
|---|
| 157 |         return false;
 | 
|---|
| 158 |     }
 | 
|---|
| 159 |     //conversion en position
 | 
|---|
| 160 |     double longPix = (longitude - longitude_min) * 30.;
 | 
|---|
| 161 |     double latPix = (latitude_max - latitude) * 40.;
 | 
|---|
| 162 | 
 | 
|---|
| 163 |     double RestCol, RestLig;
 | 
|---|
| 164 |     double ColIni, LigIni;
 | 
|---|
| 165 |     RestCol = modf(longPix, &ColIni);
 | 
|---|
| 166 |     RestLig = modf(latPix, &LigIni);
 | 
|---|
| 167 | 
 | 
|---|
| 168 |     double Zbd = (1.0 - RestCol) * (1.0 - RestLig) * LitGrille(ColIni, LigIni);
 | 
|---|
| 169 |     Zbd += RestCol * (1.0 - RestLig) * LitGrille(ColIni + 1, LigIni);
 | 
|---|
| 170 |     Zbd += (1.0 - RestCol) * RestLig * LitGrille(ColIni, LigIni + 1);
 | 
|---|
| 171 |     Zbd += RestCol * RestLig * LitGrille(ColIni + 1, LigIni + 1);
 | 
|---|
| 172 |     *Hwgs84 = Zbd;
 | 
|---|
| 173 | 
 | 
|---|
| 174 |     return true;
 | 
|---|
| 175 | }
 | 
|---|
| 176 | 
 | 
|---|
| 177 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 178 | double Raf98::LitGrille(unsigned int c, unsigned int l) const
 | 
|---|
| 179 | {
 | 
|---|
| 180 |     const unsigned int w = 421;
 | 
|---|
| 181 |     //    const unsigned int h=381;
 | 
|---|
| 182 |     return m_dvalues.at(c + l * w);
 | 
|---|
| 183 | }
 | 
|---|
| 184 | 
 | 
|---|
| 185 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 186 | bool Raf98::Load(const string& s)
 | 
|---|
| 187 | {
 | 
|---|
| 188 |     ifstream in(s.c_str());
 | 
|---|
| 189 |     unsigned int w = 421;
 | 
|---|
| 190 |     unsigned int h = 381;
 | 
|---|
| 191 | 
 | 
|---|
| 192 |     m_dvalues.reserve(w * h);
 | 
|---|
| 193 | 
 | 
|---|
| 194 |     char entete[1024]; //sur 3 lignes
 | 
|---|
| 195 |     in.getline(entete, 1023);
 | 
|---|
| 196 |     in.getline(entete, 1023);
 | 
|---|
| 197 |     in.getline(entete, 1023);
 | 
|---|
| 198 | 
 | 
|---|
| 199 |     char bidon[1024];
 | 
|---|
| 200 |     double val;
 | 
|---|
| 201 |     for (unsigned int i = 0; i < h; ++i) {
 | 
|---|
| 202 |         for (unsigned int j = 0; j < 52; ++j) {
 | 
|---|
| 203 |             for (unsigned int k = 0; k < 8; ++k) {
 | 
|---|
| 204 |                 in >> val;
 | 
|---|
| 205 |                 m_dvalues.push_back(val);
 | 
|---|
| 206 |             }
 | 
|---|
| 207 |             in.getline(bidon, 1023);
 | 
|---|
| 208 |         }
 | 
|---|
| 209 |         for (unsigned int k = 0; k < 5; ++k) {
 | 
|---|
| 210 |             in >> val;
 | 
|---|
| 211 |             m_dvalues.push_back(val);
 | 
|---|
| 212 |         }
 | 
|---|
| 213 |         in.getline(bidon, 1023);
 | 
|---|
| 214 |         if (!in.good()) {
 | 
|---|
| 215 |             m_dvalues.clear();
 | 
|---|
| 216 |             return false;
 | 
|---|
| 217 |         }
 | 
|---|
| 218 |     }
 | 
|---|
| 219 |     return in.good();
 | 
|---|
| 220 | }
 | 
|---|
| 221 | 
 | 
|---|
| 222 | } // namespace Geodesy
 | 
|---|
| 223 | 
 | 
|---|
| 224 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 225 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 226 | 
 | 
|---|
| 227 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 228 | //ALGO0001
 | 
|---|
| 229 | double Geodesy::LatitueIsometrique(double latitude, double e)
 | 
|---|
| 230 | {
 | 
|---|
| 231 |     double li = log(tan(pi<double>() / 4. + latitude / 2.)) + e * log((1 - e * sin(latitude)) / (1 + e * sin(latitude))) / 2;
 | 
|---|
| 232 |     return li;
 | 
|---|
| 233 | }
 | 
|---|
| 234 | 
 | 
|---|
| 235 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 236 | //ALGO0002
 | 
|---|
| 237 | double Geodesy::LatitueIsometrique2Lat(double latitude_iso, double e, double epsilon)
 | 
|---|
| 238 | {
 | 
|---|
| 239 |     double latitude_i = 2 * atan(exp(latitude_iso)) - half_pi<double>();
 | 
|---|
| 240 |     double latitude_ip1 = latitude_i + epsilon * 2;
 | 
|---|
| 241 |     while (abs(latitude_i - latitude_ip1) > epsilon) {
 | 
|---|
| 242 |         latitude_i = latitude_ip1;
 | 
|---|
| 243 |         latitude_ip1 = 2 * atan(
 | 
|---|
| 244 |                                exp(e * 0.5 * log(
 | 
|---|
| 245 |                                                  (1 + e * sin(latitude_i)) / (1 - e * sin(latitude_i))))
 | 
|---|
| 246 |                                * exp(latitude_iso)) - half_pi<double>();
 | 
|---|
| 247 |     }
 | 
|---|
| 248 |     return latitude_ip1;
 | 
|---|
| 249 | }
 | 
|---|
| 250 | 
 | 
|---|
| 251 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 252 | void Geodesy::Geo2ProjLambert(
 | 
|---|
| 253 |     double lambda, double phi,
 | 
|---|
| 254 |     double n, double c, double e,
 | 
|---|
| 255 |     double lambdac, double xs, double ys,
 | 
|---|
| 256 |     double& X, double& Y)
 | 
|---|
| 257 | {
 | 
|---|
| 258 |     double lat_iso = LatitueIsometrique(phi, e);
 | 
|---|
| 259 |     X = xs + c * exp(-n * lat_iso) * sin(n * (lambda - lambdac));
 | 
|---|
| 260 |     Y = ys - c * exp(-n * lat_iso) * cos(n * (lambda - lambdac));
 | 
|---|
| 261 | }
 | 
|---|
| 262 | 
 | 
|---|
| 263 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 264 | //ALGO0004
 | 
|---|
| 265 | void Geodesy::Proj2GeoLambert(
 | 
|---|
| 266 |     double X, double Y,
 | 
|---|
| 267 |     double n, double c, double e,
 | 
|---|
| 268 |     double lambdac, double xs, double ys,
 | 
|---|
| 269 |     double epsilon,
 | 
|---|
| 270 |     double& lambda, double& phi)
 | 
|---|
| 271 | {
 | 
|---|
| 272 |     double X_xs = X - xs;
 | 
|---|
| 273 |     double ys_Y = ys - Y;
 | 
|---|
| 274 |     double R = sqrt(X_xs * X_xs + ys_Y * ys_Y);
 | 
|---|
| 275 |     double gamma = atan(X_xs / ys_Y);
 | 
|---|
| 276 |     lambda = lambdac + gamma / n;
 | 
|---|
| 277 |     double lat_iso = -1 / n * log(fabs(R / c));
 | 
|---|
| 278 |     phi = LatitueIsometrique2Lat(lat_iso, e, epsilon);
 | 
|---|
| 279 | }
 | 
|---|
| 280 | 
 | 
|---|
| 281 | ////////////////////////////////////////////////////////////////////////////////
 | 
|---|
| 282 | double Geodesy::ConvMerApp(double longitude)
 | 
|---|
| 283 | {
 | 
|---|
| 284 |     double phi0_Lambert93 = Deg2Rad(46.5);
 | 
|---|
| 285 |     double lambda0_Lambert93 = Deg2Rad(3.0);
 | 
|---|
| 286 |     double conv = -sin(phi0_Lambert93) * (longitude - lambda0_Lambert93);
 | 
|---|
| 287 |     return conv;
 | 
|---|
| 288 | }
 | 
|---|
| 289 | 
 | 
|---|
| 290 | ////////////////////////////////////////////////////////////////////
 | 
|---|
| 291 | void Geodesy::Geographique_2_Lambert93(const Raf98& raf98, double lambda, double phi, double he, Matrice in, double& E, double& N, double& h, Matrice& out)
 | 
|---|
| 292 | {
 | 
|---|
| 293 |     Matrice passage;
 | 
|---|
| 294 |     double conv = Geodesy::ConvMerApp(lambda);
 | 
|---|
| 295 |     double c_ = cos(conv);
 | 
|---|
| 296 |     double s_ = sin(conv);
 | 
|---|
| 297 | 
 | 
|---|
| 298 |     passage.c0_l0 = c_;
 | 
|---|
| 299 |     passage.c0_l1 = s_;
 | 
|---|
| 300 |     passage.c0_l2 = 0.0;
 | 
|---|
| 301 | 
 | 
|---|
| 302 |     passage.c1_l0 = -s_;
 | 
|---|
| 303 |     passage.c1_l1 = c_;
 | 
|---|
| 304 |     passage.c1_l2 = 0.0;
 | 
|---|
| 305 | 
 | 
|---|
| 306 |     passage.c2_l0 = 0.0;
 | 
|---|
| 307 |     passage.c2_l1 = 0.0;
 | 
|---|
| 308 |     passage.c2_l2 = 1.0;
 | 
|---|
| 309 | 
 | 
|---|
| 310 |     out = passage * in;
 | 
|---|
| 311 |     double diff_h;
 | 
|---|
| 312 |     raf98.Interpol(Rad2Deg(lambda), Rad2Deg(phi), &diff_h);
 | 
|---|
| 313 |     h = he - diff_h;
 | 
|---|
| 314 | 
 | 
|---|
| 315 |     Geodesy::Geo2ProjLambert(
 | 
|---|
| 316 |         lambda, phi,
 | 
|---|
| 317 |         n_Lambert93, c_Lambert93, e_Lambert93,
 | 
|---|
| 318 |         lambda0_Lambert93, xs_Lambert93, ys_Lambert93,
 | 
|---|
| 319 |         E, N);
 | 
|---|
| 320 | }
 | 
|---|
| 321 | 
 | 
|---|
| 322 | ////////////////////////////////////////////////////////////////////////
 | 
|---|
| 323 | void Geodesy::Geographique_2_Lambert93(const Raf98& raf98, double lambda, double phi, double he, double& E, double& N, double& h)
 | 
|---|
| 324 | {
 | 
|---|
| 325 |     Geodesy::Geo2ProjLambert(
 | 
|---|
| 326 |         lambda, phi,
 | 
|---|
| 327 |         n_Lambert93, c_Lambert93, e_Lambert93,
 | 
|---|
| 328 |         lambda0_Lambert93, xs_Lambert93, ys_Lambert93,
 | 
|---|
| 329 |         E, N);
 | 
|---|
| 330 | 
 | 
|---|
| 331 |     double diff_h;
 | 
|---|
| 332 |     raf98.Interpol(Rad2Deg(lambda), Rad2Deg(phi), &diff_h);
 | 
|---|
| 333 |     h = he - diff_h;
 | 
|---|
| 334 | }
 | 
|---|
| 335 | 
 | 
|---|
| 336 | /// Converts Lambert93 coordinates (East, North, Height) into geographical coordinates in radians (Longitude = Rad2Deg(lambda), Latitude = Rad2Deg(phi), Height)
 | 
|---|
| 337 | void Geodesy::Lambert93_2_Geographique(const Raf98& raf98, double E, double N, double h, double& lambda, double& phi, double& he)
 | 
|---|
| 338 | {
 | 
|---|
| 339 |     Geodesy::Proj2GeoLambert(
 | 
|---|
| 340 |         E, N,
 | 
|---|
| 341 |         n_Lambert93, c_Lambert93, e_Lambert93,
 | 
|---|
| 342 |         lambda0_Lambert93, xs_Lambert93, ys_Lambert93,
 | 
|---|
| 343 |         0.0000000000000001,
 | 
|---|
| 344 |         lambda, phi);
 | 
|---|
| 345 | 
 | 
|---|
| 346 |     double diff_h;
 | 
|---|
| 347 |     raf98.Interpol(Rad2Deg(lambda), Rad2Deg(phi), &diff_h);
 | 
|---|
| 348 |     he = h + diff_h;
 | 
|---|
| 349 | }
 | 
|---|
| 350 | 
 | 
|---|
| 351 | ////////////////////////////////////////////////////////////////////////
 | 
|---|
| 352 | void Geodesy::Lambert93_2_Geographique(const Raf98& raf98, double E, double N, double h, Matrice in, double& lambda, double& phi, double& he, Matrice& out)
 | 
|---|
| 353 | {
 | 
|---|
| 354 |     Geodesy::Proj2GeoLambert(
 | 
|---|
| 355 |         E, N,
 | 
|---|
| 356 |         n_Lambert93, c_Lambert93, e_Lambert93,
 | 
|---|
| 357 |         lambda0_Lambert93, xs_Lambert93, ys_Lambert93,
 | 
|---|
| 358 |         0.0000000000000001,
 | 
|---|
| 359 |         lambda, phi);
 | 
|---|
| 360 | 
 | 
|---|
| 361 |     Matrice passage;
 | 
|---|
| 362 |     double conv = Geodesy::ConvMerApp(lambda);
 | 
|---|
| 363 |     double c_ = cos(conv);
 | 
|---|
| 364 |     double s_ = sin(conv);
 | 
|---|
| 365 | 
 | 
|---|
| 366 |     passage.c0_l0 = c_;
 | 
|---|
| 367 |     passage.c0_l1 = -s_;
 | 
|---|
| 368 |     passage.c0_l2 = 0.0;
 | 
|---|
| 369 | 
 | 
|---|
| 370 |     passage.c1_l0 = s_;
 | 
|---|
| 371 |     passage.c1_l1 = c_;
 | 
|---|
| 372 |     passage.c1_l2 = 0.0;
 | 
|---|
| 373 | 
 | 
|---|
| 374 |     passage.c2_l0 = 0.0;
 | 
|---|
| 375 |     passage.c2_l1 = 0.0;
 | 
|---|
| 376 |     passage.c2_l2 = 1.0;
 | 
|---|
| 377 | 
 | 
|---|
| 378 |     out = passage * in;
 | 
|---|
| 379 | 
 | 
|---|
| 380 |     double diff_h;
 | 
|---|
| 381 |     raf98.Interpol(Rad2Deg(lambda), Rad2Deg(phi), &diff_h);
 | 
|---|
| 382 |     he = h + diff_h;
 | 
|---|
| 383 | }
 | 
|---|
| 384 | 
 | 
|---|
| 385 | ////////////////////////////////////////////////////////////////////////
 | 
|---|
| 386 | void Geodesy::Geographique_2_ECEF(double longitude, double latitude, double he, double& x, double& y, double& z)
 | 
|---|
| 387 | {
 | 
|---|
| 388 |     const double n = GRS_a / sqrt(1.0 - pow(GRS_e, 2) * pow(sin(latitude), 2));
 | 
|---|
| 389 |     x = (n + he) * cos(latitude) * cos(longitude);
 | 
|---|
| 390 |     y = (n + he) * cos(latitude) * sin(longitude);
 | 
|---|
| 391 |     z = (n * (1.0 - pow(GRS_e, 2)) + he) * sin(latitude);
 | 
|---|
| 392 | }
 | 
|---|
| 393 | 
 | 
|---|
| 394 | ////////////////////////////////////////////////////////////////////////
 | 
|---|
| 395 | void Geodesy::ECEF_2_ENU(double x, double y, double z, double& e, double& n, double& u, double lon0, double lat0, double he0)
 | 
|---|
| 396 | {
 | 
|---|
| 397 |     double slat = sin(lat0);
 | 
|---|
| 398 |     double clat = cos(lat0);
 | 
|---|
| 399 |     double slon = sin(lon0);
 | 
|---|
| 400 |     double clon = cos(lon0);
 | 
|---|
| 401 | 
 | 
|---|
| 402 |     Matrice C;
 | 
|---|
| 403 |     C.c0_l0 = -slon;
 | 
|---|
| 404 |     C.c1_l0 = clon;
 | 
|---|
| 405 | 
 | 
|---|
| 406 |     C.c0_l1 = -clon * slat;
 | 
|---|
| 407 |     C.c1_l1 = -slon * slat;
 | 
|---|
| 408 |     C.c2_l1 = clat;
 | 
|---|
| 409 | 
 | 
|---|
| 410 |     C.c0_l2 = clon * clat;
 | 
|---|
| 411 |     C.c1_l2 = slon * clat;
 | 
|---|
| 412 |     C.c2_l2 = slat;
 | 
|---|
| 413 | 
 | 
|---|
| 414 |     double x0, y0, z0;
 | 
|---|
| 415 |     Geographique_2_ECEF(lon0, lat0, he0, x0, y0, z0);
 | 
|---|
| 416 | 
 | 
|---|
| 417 |     x -= x0;
 | 
|---|
| 418 |     y -= y0;
 | 
|---|
| 419 |     z -= z0;
 | 
|---|
| 420 | 
 | 
|---|
| 421 |     C.Apply(x, y, z, e, n, u);
 | 
|---|
| 422 | }
 | 
|---|
| 423 | 
 | 
|---|
| 424 | QMatrix4x4 Geodesy::yprenuToMatrix(QVector3D angle, QVector3D position)
 | 
|---|
| 425 | {
 | 
|---|
| 426 |     float c1 = cos(angle.x());
 | 
|---|
| 427 |     float c2 = cos(angle.y());
 | 
|---|
| 428 |     float c3 = cos(angle.z());
 | 
|---|
| 429 | 
 | 
|---|
| 430 |     float s1 = sin(angle.x());
 | 
|---|
| 431 |     float s2 = sin(angle.y());
 | 
|---|
| 432 |     float s3 = sin(angle.z());
 | 
|---|
| 433 | 
 | 
|---|
| 434 |     // Source : https://en.wikipedia.org/wiki/Euler_angles
 | 
|---|
| 435 |     return QMatrix4x4(c1 * c2, c1 * s2 * s3 - c3 * s1, s1 * s3 + c1 * c3 * s2, position.x(),
 | 
|---|
| 436 |                       c2 * s1, c1 * c3 + s1 * s2 * s3, c3 * s1 * s2 - c1 * s3, position.y(),
 | 
|---|
| 437 |                       -s2, c2 * s3, c2 * c3, position.z(),
 | 
|---|
| 438 |                       0, 0, 0, 1);
 | 
|---|
| 439 | }
 | 
|---|