/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2024, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */

#include <mrpt/math/CMatrixD.h>
#include <mrpt/system/os.h>
#include <mrpt/topography.h>

#include <iomanip>
#include <iostream>

using namespace mrpt::math;
using namespace mrpt::topography;
using namespace mrpt::system;
using namespace std;

#include <mrpt/examples_config.h>

std::vector<string> names;
std::vector<CMatrixD> results;
const double TH = 0.02;

using mrpt::system::consoleColorAndStyle;
using mrpt::system::ConsoleForegroundColor;

void exampleResults()
{
  names.resize(6);
  names[0] = "MAND";
  names[1] = "OROZ";
  names[2] = "SANC";
  names[3] = "ARJO";
  names[4] = "CANI";
  names[5] = "HALC";
  results.resize(25);

  // Example 01
  results[0] = CMatrixD(6, 3);
  results[0](0, 0) = 435699.5503;
  results[0](0, 1) = 4194142.0571;
  results[0](0, 2) = 515.5790;
  results[0](1, 0) = 443948.2295;
  results[0](1, 1) = 4160754.7114;
  results[0](1, 2) = 1489.1880;
  results[0](2, 0) = 436542.0710;
  results[0](2, 1) = 4177367.6694;
  results[0](2, 2) = 1054.1890;
  results[0](3, 0) = 406284.9288;
  results[0](3, 1) = 4176492.3033;
  results[0](3, 2) = 569.1820;
  results[0](4, 0) = 406546.3268;
  results[0](4, 1) = 4156628.3641;
  results[0](4, 2) = 897.6260;
  results[0](5, 0) = 408051.6599;
  results[0](5, 1) = 4193733.3066;
  results[0](5, 2) = 530.4460;

  // Example 02
  results[1] = CMatrixD(6, 3);
  results[1](0, 0) = 435810.797;
  results[1](0, 1) = 4194348.753;
  results[1](0, 2) = 437.516;
  results[1](1, 0) = 444059.747;
  results[1](1, 1) = 4160961.358;
  results[1](1, 2) = 1410.518;
  results[1](2, 0) = 436653.444;
  results[1](2, 1) = 4177574.314;
  results[1](2, 2) = 975.764;
  results[1](3, 0) = 406396.235;
  results[1](3, 1) = 4176698.718;
  results[1](3, 2) = 490.219;
  results[1](4, 0) = 406657.783;
  results[1](4, 1) = 4156834.717;
  results[1](4, 2) = 818.224;
  results[1](5, 0) = 408162.836;
  results[1](5, 1) = 4193939.783;
  results[1](5, 2) = 451.896;

  // Example 03
  results[2] = CMatrixD(6, 3);
  results[2](0, 0) = 435811.252;
  results[2](0, 1) = 4194347.983;
  results[2](0, 2) = 515.579;
  results[2](1, 0) = 444059.929;
  results[2](1, 1) = 4160960.606;
  results[2](1, 2) = 1489.188;
  results[2](2, 0) = 436653.768;
  results[2](2, 1) = 4177573.581;
  results[2](2, 2) = 1054.189;
  results[2](3, 0) = 406396.600;
  results[2](3, 1) = 4176698.222;
  results[2](3, 2) = 569.182;
  results[2](4, 0) = 406657.992;
  results[2](4, 1) = 4156834.266;
  results[2](4, 2) = 897.626;
  results[2](5, 0) = 408163.337;
  results[2](5, 1) = 4193939.241;
  results[2](5, 2) = 530.446;

  // Example 04
  results[3] = CMatrixD(6, 3);
  results[3](0, 0) = 435811.073;
  results[3](0, 1) = 4194347.990;
  results[3](0, 2) = 466.175;
  results[3](1, 0) = 444059.962;
  results[3](1, 1) = 4160960.412;
  results[3](1, 2) = 1439.784;
  results[3](2, 0) = 436653.708;
  results[3](2, 1) = 4177573.506;
  results[3](2, 2) = 1004.785;
  results[3](3, 0) = 406396.665;
  results[3](3, 1) = 4176698.318;
  results[3](3, 2) = 519.778;
  results[3](4, 0) = 406658.202;
  results[3](4, 1) = 4156834.269;
  results[3](4, 2) = 848.222;
  results[3](5, 0) = 408163.269;
  results[3](5, 1) = 4193939.405;
  results[3](5, 2) = 481.042;

  // Example 05
  results[4] = CMatrixD(6, 3);
  results[4](0, 0) = 435811.251;
  results[4](0, 1) = 4194347.974;
  results[4](0, 2) = 465.655;
  results[4](1, 0) = 444059.934;
  results[4](1, 1) = 4160960.612;
  results[4](1, 2) = 1439.740;
  results[4](2, 0) = 436653.771;
  results[4](2, 1) = 4177573.582;
  results[4](2, 2) = 1004.556;
  results[4](3, 0) = 406396.596;
  results[4](3, 1) = 4176698.222;
  results[4](3, 2) = 520.037;
  results[4](4, 0) = 406657.988;
  results[4](4, 1) = 4156834.272;
  results[4](4, 2) = 848.836;
  results[4](5, 0) = 408163.337;
  results[4](5, 1) = 4193939.239;
  results[4](5, 2) = 480.961;

  // Example 06
  results[5] = CMatrixD(6, 3);
  results[5](0, 0) = 435811.250;
  results[5](0, 1) = 4194347.994;
  results[5](0, 2) = 437.516;
  results[5](1, 0) = 444059.921;
  results[5](1, 1) = 4160960.599;
  results[5](1, 2) = 1410.518;
  results[5](2, 0) = 436653.764;
  results[5](2, 1) = 4177573.581;
  results[5](2, 2) = 975.764;
  results[5](3, 0) = 406396.606;
  results[5](3, 1) = 4176698.225;
  results[5](3, 2) = 490.219;
  results[5](4, 0) = 406657.997;
  results[5](4, 1) = 4156834.260;
  results[5](4, 2) = 818.224;
  results[5](5, 0) = 408163.340;
  results[5](5, 1) = 4193939.242;
  results[5](5, 2) = 451.896;

  // Example 07
  results[6] = CMatrixD(6, 3);
  results[6](0, 0) = 435811.074;
  results[6](0, 1) = 4194347.994;
  results[6](0, 2) = 466.791;
  results[6](1, 0) = 444059.961;
  results[6](1, 1) = 4160960.410;
  results[6](1, 2) = 1439.793;
  results[6](2, 0) = 436653.708;
  results[6](2, 1) = 4177573.505;
  results[6](2, 2) = 1005.039;
  results[6](3, 0) = 406396.667;
  results[6](3, 1) = 4176698.320;
  results[6](3, 2) = 519.494;
  results[6](4, 0) = 406658.203;
  results[6](4, 1) = 4156834.270;
  results[6](4, 2) = 847.499;
  results[6](5, 0) = 408163.267;
  results[6](5, 1) = 4193939.401;
  results[6](5, 2) = 481.171;

  // Example 08
  results[7] = CMatrixD(6, 3);
  results[7](0, 0) = 435811.250;
  results[7](0, 1) = 4194347.974;
  results[7](0, 2) = 465.657;
  results[7](1, 0) = 444059.935;
  results[7](1, 1) = 4160960.612;
  results[7](1, 2) = 1439.739;
  results[7](2, 0) = 436653.772;
  results[7](2, 1) = 4177573.582;
  results[7](2, 2) = 1004.556;
  results[7](3, 0) = 406396.597;
  results[7](3, 1) = 4176698.223;
  results[7](3, 2) = 520.037;
  results[7](4, 0) = 406657.988;
  results[7](4, 1) = 4156834.271;
  results[7](4, 2) = 848.837;
  results[7](5, 0) = 408163.339;
  results[7](5, 1) = 4193939.239;
  results[7](5, 2) = 480.959;

  // Example 10
  results[9] = CMatrixD(6, 3);
  results[9](0, 0) = 435811.2512;
  results[9](0, 1) = 4194347.9756;
  results[9](0, 2) = 465.6558;
  results[9](1, 0) = 444059.9337;
  results[9](1, 1) = 4160960.6109;
  results[9](1, 2) = 1439.7390;
  results[9](2, 0) = 436653.7721;
  results[9](2, 1) = 4177573.5812;
  results[9](2, 2) = 1004.5560;
  results[9](3, 0) = 406396.5970;
  results[9](3, 1) = 4176698.2216;
  results[9](3, 2) = 520.0376;
  results[9](4, 0) = 406657.9894;
  results[9](4, 1) = 4156834.2734;
  results[9](4, 2) = 848.8373;
  results[9](5, 0) = 408163.3366;
  results[9](5, 1) = 4193939.2373;
  results[9](5, 2) = 480.9593;

  // Example 11
  results[10] = CMatrixD(6, 3);
  results[10](0, 0) = 435811.2512;
  results[10](0, 1) = 4194347.9756;
  results[10](0, 2) = 465.6558;
  results[10](1, 0) = 444059.9337;
  results[10](1, 1) = 4160960.6109;
  results[10](1, 2) = 1439.7390;
  results[10](2, 0) = 436653.7721;
  results[10](2, 1) = 4177573.5812;
  results[10](2, 2) = 1004.5560;
  results[10](3, 0) = 406396.5970;
  results[10](3, 1) = 4176698.2216;
  results[10](3, 2) = 520.0376;
  results[10](4, 0) = 406657.9894;
  results[10](4, 1) = 4156834.2734;
  results[10](4, 2) = 848.8373;
  results[10](5, 0) = 408163.3366;
  results[10](5, 1) = 4193939.2373;
  results[10](5, 2) = 480.9593;

  // Example 12
  results[11] = CMatrixD(6, 3);
  results[11](0, 0) = 435811.156;
  results[11](0, 1) = 4194347.892;
  results[11](0, 2) = 466.100;
  results[11](1, 0) = 444059.719;
  results[11](1, 1) = 4160960.489;
  results[11](1, 2) = 1439.389;
  results[11](2, 0) = 436653.606;
  results[11](2, 1) = 4177573.398;
  results[11](2, 2) = 1004.594;
  results[11](3, 0) = 406396.045;
  results[11](3, 1) = 4176697.926;
  results[11](3, 2) = 520.238;
  results[11](4, 0) = 406658.812;
  results[11](4, 1) = 4156834.183;
  results[11](4, 2) = 849.050;
  results[11](5, 0) = 408163.542;
  results[11](5, 1) = 4193940.012;
  results[11](5, 2) = 480.414;

  // Example 13
  results[12] = CMatrixD(6, 3);
  results[12](0, 0) = 435811.095;
  results[12](0, 1) = 4194348.146;
  results[12](0, 2) = 465.884;
  results[12](1, 0) = 444059.906;
  results[12](1, 1) = 4160960.276;
  results[12](1, 2) = 1439.564;
  results[12](2, 0) = 436653.748;
  results[12](2, 1) = 4177573.521;
  results[12](2, 2) = 1004.572;
  results[12](3, 0) = 406396.375;
  results[12](3, 1) = 4176698.033;
  results[12](3, 2) = 520.147;
  results[12](4, 0) = 406658.370;
  results[12](4, 1) = 4156834.517;
  results[12](4, 2) = 848.945;
  results[12](5, 0) = 408163.386;
  results[12](5, 1) = 4193939.406;
  results[12](5, 2) = 480.674;
}

void displayResults(const CVectorDouble& thisResults, const unsigned int& example, const bool color)
{
  cout << "Example " << example << ". Results" << setprecision(16) << endl;
  cout << "------------------------------------------------------------------"
          "----------"
       << endl;
  cout << "N\t"
       << "X\t\t\t"
       << "Y\t\t\t"
       << "Z" << endl;
  cout << "------------------------------------------------------------------"
          "----------"
       << endl;

  if (color)
  {
    const size_t N = thisResults.size() / 3;
    for (unsigned int i = 0; i < N; ++i)
    {
      cout << names[i] << "\t";
      if (fabs(thisResults[3 * i + 0] - results[example - 1](i, 0)) < TH)
        consoleColorAndStyle(ConsoleForegroundColor::GREEN);
      else
        consoleColorAndStyle(ConsoleForegroundColor::RED);
      cout << thisResults[3 * i + 0] << "\t";

      if (fabs(thisResults[3 * i + 1] - results[example - 1](i, 1)) < TH)
        consoleColorAndStyle(ConsoleForegroundColor::GREEN);
      else
        consoleColorAndStyle(ConsoleForegroundColor::RED);
      cout << thisResults[3 * i + 1] << "\t";

      if (fabs(thisResults[3 * i + 2] - results[example - 1](i, 2)) < TH)
        consoleColorAndStyle(ConsoleForegroundColor::GREEN);
      else
        consoleColorAndStyle(ConsoleForegroundColor::RED);
      cout << thisResults[3 * i + 2] << endl;

      consoleColorAndStyle(ConsoleForegroundColor::DEFAULT);
    }
    cout << endl;
  }
  else
  {
    const size_t N = thisResults.size() / 3;
    for (unsigned int i = 0; i < N; ++i)
      cout << names[i] << "\t" << thisResults[3 * i + 0] << "\t" << thisResults[3 * i + 1] << "\t"
           << thisResults[3 * i + 2] << endl;
    cout << endl;
  }
}

void TestCoordinatesConversions()
{
  // Initial UTM coordinates (X,Y,Z)
  mrpt::math::TPoint3D UTMCoords;
  UTMCoords.x = 435500;
  UTMCoords.y = 4194142.057;
  UTMCoords.z = 515.579;

  const int huso = 30;
  const char hem = 'n';

  TGeodeticCoords GeodeticCoords;
  TEllipsoid ellip = TEllipsoid::Ellipsoid_WGS84();

  // Dump to console of input values
  cout << "INPUT DATA: " << endl << "----------------------------------" << endl;
  cout << "UTM Coordinates: " << endl;
  cout << "X = " << setprecision(15) << UTMCoords.x << endl;
  cout << "Y = " << UTMCoords.y << endl;
  cout << "Z = " << UTMCoords.z << endl;
  cout << "Time zone: " << huso << endl;
  cout << "Hemisphery: " << hem << endl;
  cout << "Ellipsoid: " << ellip.name << endl;
  cout << "----------------------------------" << endl << endl;

  // UTM to Geodetic ...
  UTMToGeodetic(UTMCoords, huso, hem, GeodeticCoords, ellip);
  cout << "UTM to Geodetic" << endl;
  cout << "Geodetic Coordinates:" << endl;
  cout << "Lon = " << TCoords(GeodeticCoords.lon) << " [" << GeodeticCoords.lon << "]" << endl;
  cout << "Lat = " << TCoords(GeodeticCoords.lat) << " [" << GeodeticCoords.lon << "]" << endl;
  cout << "H = " << GeodeticCoords.height << endl;
  cout << "----------------------------------" << endl;

  // Geodetic to Geocentric ...
  TGeocentricCoords GeocentricCoords;
  geodeticToGeocentric(GeodeticCoords, GeocentricCoords, ellip);
  cout << "Geodetic to Geocentric" << endl;
  cout << "Geocentric Coordinates:" << endl;
  cout << "X = " << GeocentricCoords.x << endl;
  cout << "Y = " << GeocentricCoords.y << endl;
  cout << "Z = " << GeocentricCoords.z << endl;
  cout << "----------------------------------" << endl;

  // 7 parameter transformation (X,Y,Z) -> (X',Y',Z')
  // TDatum7Params datum( dx, dy, dz, rx(sec), ry(sec), rz(sec), ds(ppm) );
  TDatum7Params datum(109.4714, 106.7407, 141.7916, 4.7834, 7.9668, -5.3771, -6.690000);
  TGeocentricCoords GeocentricCoords2;
  transform7params(GeocentricCoords, datum, GeocentricCoords2);
  // transform7params(
  // TGeocentricCoords(5029475.945,-328201.0396,3896351.728), datum,
  // GeocentricCoords2 );
  cout << "transform7params" << endl;
  cout << "Transformed Geocentric Coordinates:" << endl;
  cout << "X = " << GeocentricCoords2.x << endl;
  cout << "Y = " << GeocentricCoords2.y << endl;
  cout << "Z = " << GeocentricCoords2.z << endl;
  cout << "----------------------------------" << endl;

  // ... and back to Geodetic
  TGeodeticCoords GeodeticCoords2;
  ellip = TEllipsoid::Ellipsoid_Hough_1960();
  geocentricToGeodetic(GeocentricCoords2, GeodeticCoords2, ellip);
  cout << "Geocentric to Geodetic" << endl;
  cout << "Geodetic Coordinates:" << endl;
  cout << "Lon = " << TCoords(GeodeticCoords2.lon) << " [" << GeodeticCoords2.lon << "]" << endl;
  cout << "Lat = " << TCoords(GeodeticCoords2.lat) << " [" << GeodeticCoords2.lat << "]" << endl;
  cout << "H = " << GeodeticCoords2.height << endl;
  cout << "----------------------------------" << endl;

  // ... and back to UTM
  TUTMCoords UTMCoords2;
  int time_zone2;
  char latitude_band2;
  // geodeticToUTM( GeodeticCoords2, UTMCoords2, time_zone2, latitude_band2,
  // ellip );
  geodeticToUTM(
      TGeodeticCoords(37.89604181, -3.72987289, 542.8624741), UTMCoords2, time_zone2,
      latitude_band2, TEllipsoid(6378270, 6356794.343, "USER"));
  cout << "Geodetic to UTM" << endl;
  cout << "UTM Coordinates:" << endl;
  cout << "X = " << UTMCoords2.x << endl;
  cout << "Y = " << UTMCoords2.y << endl;
  cout << "Z = " << UTMCoords2.z << endl;
  cout << "Time zone: " << time_zone2 << endl;
  cout << "----------------------------------" << endl;

  // 10 parameter transformation (X,Y,Z) -> (X',Y',Z')

  // Helmert 2D transformation (X,Y) -> (X',Y')

  // Helmert 3D transformation (X,Y,Z) -> (X',Y',Z')

  // 1D transformation (X,Y,Z) -> (X')

  // Interpolation (X,Y) -> (X',Y')
}

void Examples_01()
{
  TGeodeticCoords MAND_92633(
      TCoords(37, 53, 33.072573).getDecimalValue(), TCoords(-3, 43, 52.68965).getDecimalValue(),
      515.579);
  TGeodeticCoords OROZ_96965(
      TCoords(37, 35, 31.75505).getDecimalValue(), TCoords(-3, 38, 5.70754).getDecimalValue(),
      1489.188);
  TGeodeticCoords SANC_94744(
      TCoords(37, 44, 29.04253).getDecimalValue(), TCoords(-3, 43, 12.90285).getDecimalValue(),
      1054.189);
  TGeodeticCoords ARJO_94633(
      TCoords(37, 43, 51.28918).getDecimalValue(), TCoords(-4, 3, 48.64503).getDecimalValue(),
      569.182);
  TGeodeticCoords CANI_96833(
      TCoords(37, 33, 6.94237).getDecimalValue(), TCoords(-4, 3, 28.81611).getDecimalValue(),
      897.626);
  TGeodeticCoords HALC_92543(
      TCoords(37, 53, 11.26838).getDecimalValue(), TCoords(-4, 2, 44.35794).getDecimalValue(),
      530.446);

  // A2
  int UTMZone;
  char UTMBand;
  TUTMCoords MAND_UTM, OROZ_UTM, SANC_UTM, ARJO_UTM, CANI_UTM, HALC_UTM;
  geodeticToUTM(MAND_92633, MAND_UTM, UTMZone, UTMBand, TEllipsoid::Ellipsoid_WGS84());
  geodeticToUTM(OROZ_96965, OROZ_UTM, UTMZone, UTMBand, TEllipsoid::Ellipsoid_WGS84());
  geodeticToUTM(SANC_94744, SANC_UTM, UTMZone, UTMBand, TEllipsoid::Ellipsoid_WGS84());
  geodeticToUTM(ARJO_94633, ARJO_UTM, UTMZone, UTMBand, TEllipsoid::Ellipsoid_WGS84());
  geodeticToUTM(CANI_96833, CANI_UTM, UTMZone, UTMBand, TEllipsoid::Ellipsoid_WGS84());
  geodeticToUTM(HALC_92543, HALC_UTM, UTMZone, UTMBand, TEllipsoid::Ellipsoid_WGS84());

  CVectorDouble thisResults;
  thisResults.resize(18);

  thisResults[0] = MAND_UTM.x;
  thisResults[1] = MAND_UTM.y;
  thisResults[2] = MAND_UTM.z;
  thisResults[3] = OROZ_UTM.x;
  thisResults[4] = OROZ_UTM.y;
  thisResults[5] = OROZ_UTM.z;
  thisResults[6] = SANC_UTM.x;
  thisResults[7] = SANC_UTM.y;
  thisResults[8] = SANC_UTM.z;
  thisResults[9] = ARJO_UTM.x;
  thisResults[10] = ARJO_UTM.y;
  thisResults[11] = ARJO_UTM.z;
  thisResults[12] = CANI_UTM.x;
  thisResults[13] = CANI_UTM.y;
  thisResults[14] = CANI_UTM.z;
  thisResults[15] = HALC_UTM.x;
  thisResults[16] = HALC_UTM.y;
  thisResults[17] = HALC_UTM.z;

  displayResults(thisResults, 1, true);
}

void Examples_02()
{
  TGeodeticCoords MAND_92633(
      TCoords(37, 53, 33.072573).getDecimalValue(), TCoords(-3, 43, 52.68965).getDecimalValue(),
      515.579);
  TGeodeticCoords OROZ_96965(
      TCoords(37, 35, 31.75505).getDecimalValue(), TCoords(-3, 38, 5.70754).getDecimalValue(),
      1489.188);
  TGeodeticCoords SANC_94744(
      TCoords(37, 44, 29.04253).getDecimalValue(), TCoords(-3, 43, 12.90285).getDecimalValue(),
      1054.189);
  TGeodeticCoords ARJO_94633(
      TCoords(37, 43, 51.28918).getDecimalValue(), TCoords(-4, 3, 48.64503).getDecimalValue(),
      569.182);
  TGeodeticCoords CANI_96833(
      TCoords(37, 33, 6.94237).getDecimalValue(), TCoords(-4, 3, 28.81611).getDecimalValue(),
      897.626);
  TGeodeticCoords HALC_92543(
      TCoords(37, 53, 11.26838).getDecimalValue(), TCoords(-4, 2, 44.35794).getDecimalValue(),
      530.446);

  const TEllipsoid ellip = TEllipsoid::Ellipsoid_Internacional_1924();

  // A3
  TGeocentricCoords MAND_Geoc, OROZ_Geoc, SANC_Geoc, ARJO_Geoc, CANI_Geoc, HALC_Geoc;
  geodeticToGeocentric(MAND_92633, MAND_Geoc, TEllipsoid::Ellipsoid_WGS84());
  geodeticToGeocentric(OROZ_96965, OROZ_Geoc, TEllipsoid::Ellipsoid_WGS84());
  geodeticToGeocentric(SANC_94744, SANC_Geoc, TEllipsoid::Ellipsoid_WGS84());
  geodeticToGeocentric(ARJO_94633, ARJO_Geoc, TEllipsoid::Ellipsoid_WGS84());
  geodeticToGeocentric(CANI_96833, CANI_Geoc, TEllipsoid::Ellipsoid_WGS84());
  geodeticToGeocentric(HALC_92543, HALC_Geoc, TEllipsoid::Ellipsoid_WGS84());

  // A5
  TGeocentricCoords MAND_Geoc2, OROZ_Geoc2, SANC_Geoc2, ARJO_Geoc2, CANI_Geoc2, HALC_Geoc2;
  TDatum7Params datum(131.0320, 100.2510, 163.3540, -1.2438, -0.0195, -1.1436, -9.3900);
  transform7params(MAND_Geoc, datum, MAND_Geoc2);
  transform7params(OROZ_Geoc, datum, OROZ_Geoc2);
  transform7params(SANC_Geoc, datum, SANC_Geoc2);
  transform7params(ARJO_Geoc, datum, ARJO_Geoc2);
  transform7params(CANI_Geoc, datum, CANI_Geoc2);
  transform7params(HALC_Geoc, datum, HALC_Geoc2);

  // A4
  TGeodeticCoords MAND_Geod, OROZ_Geod, SANC_Geod, ARJO_Geod, CANI_Geod, HALC_Geod;
  geocentricToGeodetic(MAND_Geoc2, MAND_Geod, ellip);
  geocentricToGeodetic(OROZ_Geoc2, OROZ_Geod, ellip);
  geocentricToGeodetic(SANC_Geoc2, SANC_Geod, ellip);
  geocentricToGeodetic(ARJO_Geoc2, ARJO_Geod, ellip);
  geocentricToGeodetic(CANI_Geoc2, CANI_Geod, ellip);
  geocentricToGeodetic(HALC_Geoc2, HALC_Geod, ellip);

  // A2
  int UTMZone;
  char UTMBand;
  TUTMCoords MAND_UTM, OROZ_UTM, SANC_UTM, ARJO_UTM, CANI_UTM, HALC_UTM;
  geodeticToUTM(MAND_Geod, MAND_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(OROZ_Geod, OROZ_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(SANC_Geod, SANC_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(ARJO_Geod, ARJO_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(CANI_Geod, CANI_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(HALC_Geod, HALC_UTM, UTMZone, UTMBand, ellip);

  CVectorDouble thisResults;
  thisResults.resize(18);

  thisResults[0] = MAND_UTM.x;
  thisResults[1] = MAND_UTM.y;
  thisResults[2] = MAND_UTM.z;
  thisResults[3] = OROZ_UTM.x;
  thisResults[4] = OROZ_UTM.y;
  thisResults[5] = OROZ_UTM.z;
  thisResults[6] = SANC_UTM.x;
  thisResults[7] = SANC_UTM.y;
  thisResults[8] = SANC_UTM.z;
  thisResults[9] = ARJO_UTM.x;
  thisResults[10] = ARJO_UTM.y;
  thisResults[11] = ARJO_UTM.z;
  thisResults[12] = CANI_UTM.x;
  thisResults[13] = CANI_UTM.y;
  thisResults[14] = CANI_UTM.z;
  thisResults[15] = HALC_UTM.x;
  thisResults[16] = HALC_UTM.y;
  thisResults[17] = HALC_UTM.z;

  displayResults(thisResults, 2, true);
}

void Examples_03()
{
  // TOPCON
  TGeodeticCoords MAND_92633(
      TCoords(37, 53, 33.072573).getDecimalValue(), TCoords(-3, 43, 52.68965).getDecimalValue(),
      515.579);
  TGeodeticCoords OROZ_96965(
      TCoords(37, 35, 31.75505).getDecimalValue(), TCoords(-3, 38, 5.70754).getDecimalValue(),
      1489.188);
  TGeodeticCoords SANC_94744(
      TCoords(37, 44, 29.04253).getDecimalValue(), TCoords(-3, 43, 12.90285).getDecimalValue(),
      1054.189);
  TGeodeticCoords ARJO_94633(
      TCoords(37, 43, 51.28918).getDecimalValue(), TCoords(-4, 3, 48.64503).getDecimalValue(),
      569.182);
  TGeodeticCoords CANI_96833(
      TCoords(37, 33, 6.94237).getDecimalValue(), TCoords(-4, 3, 28.81611).getDecimalValue(),
      897.626);
  TGeodeticCoords HALC_92543(
      TCoords(37, 53, 11.26838).getDecimalValue(), TCoords(-4, 2, 44.35794).getDecimalValue(),
      530.446);

  const TEllipsoid ellip = TEllipsoid::Ellipsoid_WGS84();

  // A2
  int UTMZone;
  char UTMBand;
  TUTMCoords MAND_UTM, OROZ_UTM, SANC_UTM, ARJO_UTM, CANI_UTM, HALC_UTM;
  geodeticToUTM(MAND_92633, MAND_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(OROZ_96965, OROZ_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(SANC_94744, SANC_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(ARJO_94633, ARJO_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(CANI_96833, CANI_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(HALC_92543, HALC_UTM, UTMZone, UTMBand, ellip);

  // A7
  TPoint2D MAND_point, OROZ_point, SANC_point, ARJO_point, CANI_point, HALC_point;
  TDatumHelmert2D_TOPCON datum(1.0000008551, 0.0000002900, 110.1121641064, 202.4657352579);
  transformHelmert2D_TOPCON(TPoint2D(MAND_UTM.x, MAND_UTM.y), datum, MAND_point);
  transformHelmert2D_TOPCON(TPoint2D(OROZ_UTM.x, OROZ_UTM.y), datum, OROZ_point);
  transformHelmert2D_TOPCON(TPoint2D(SANC_UTM.x, SANC_UTM.y), datum, SANC_point);
  transformHelmert2D_TOPCON(TPoint2D(ARJO_UTM.x, ARJO_UTM.y), datum, ARJO_point);
  transformHelmert2D_TOPCON(TPoint2D(CANI_UTM.x, CANI_UTM.y), datum, CANI_point);
  transformHelmert2D_TOPCON(TPoint2D(HALC_UTM.x, HALC_UTM.y), datum, HALC_point);

  CVectorDouble thisResults;
  thisResults.resize(18);

  thisResults[0] = MAND_point.x;
  thisResults[1] = MAND_point.y;
  thisResults[2] = MAND_UTM.z;
  thisResults[3] = OROZ_point.x;
  thisResults[4] = OROZ_point.y;
  thisResults[5] = OROZ_UTM.z;
  thisResults[6] = SANC_point.x;
  thisResults[7] = SANC_point.y;
  thisResults[8] = SANC_UTM.z;
  thisResults[9] = ARJO_point.x;
  thisResults[10] = ARJO_point.y;
  thisResults[11] = ARJO_UTM.z;
  thisResults[12] = CANI_point.x;
  thisResults[13] = CANI_point.y;
  thisResults[14] = CANI_UTM.z;
  thisResults[15] = HALC_point.x;
  thisResults[16] = HALC_point.y;
  thisResults[17] = HALC_UTM.z;

  displayResults(thisResults, 3, true);
}

void Examples_04()
{
  // TOPCON
  TGeodeticCoords MAND_92633(
      TCoords(37, 53, 33.072573).getDecimalValue(), TCoords(-3, 43, 52.68965).getDecimalValue(),
      515.579);
  TGeodeticCoords OROZ_96965(
      TCoords(37, 35, 31.75505).getDecimalValue(), TCoords(-3, 38, 5.70754).getDecimalValue(),
      1489.188);
  TGeodeticCoords SANC_94744(
      TCoords(37, 44, 29.04253).getDecimalValue(), TCoords(-3, 43, 12.90285).getDecimalValue(),
      1054.189);
  TGeodeticCoords ARJO_94633(
      TCoords(37, 43, 51.28918).getDecimalValue(), TCoords(-4, 3, 48.64503).getDecimalValue(),
      569.182);
  TGeodeticCoords CANI_96833(
      TCoords(37, 33, 6.94237).getDecimalValue(), TCoords(-4, 3, 28.81611).getDecimalValue(),
      897.626);
  TGeodeticCoords HALC_92543(
      TCoords(37, 53, 11.26838).getDecimalValue(), TCoords(-4, 2, 44.35794).getDecimalValue(),
      530.446);

  const TEllipsoid ellip = TEllipsoid::Ellipsoid_WGS84();

  // A2
  int UTMZone;
  char UTMBand;
  TUTMCoords MAND_UTM, OROZ_UTM, SANC_UTM, ARJO_UTM, CANI_UTM, HALC_UTM;
  geodeticToUTM(MAND_92633, MAND_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(OROZ_96965, OROZ_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(SANC_94744, SANC_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(ARJO_94633, ARJO_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(CANI_96833, CANI_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(HALC_92543, HALC_UTM, UTMZone, UTMBand, ellip);

  // A7
  TUTMCoords MAND_point, OROZ_point, SANC_point, ARJO_point, CANI_point, HALC_point;
  TDatumHelmert3D_TOPCON datum(
      0.9999969509, -0.0000070551, 142.4402790576, -0.0000060616, 1.0000054540, 185.6991268722,
      -49.4041666667);
  transformHelmert3D_TOPCON(MAND_UTM, datum, MAND_point);
  transformHelmert3D_TOPCON(OROZ_UTM, datum, OROZ_point);
  transformHelmert3D_TOPCON(SANC_UTM, datum, SANC_point);
  transformHelmert3D_TOPCON(ARJO_UTM, datum, ARJO_point);
  transformHelmert3D_TOPCON(CANI_UTM, datum, CANI_point);
  transformHelmert3D_TOPCON(HALC_UTM, datum, HALC_point);

  CVectorDouble thisResults;
  thisResults.resize(18);

  thisResults[0] = MAND_point.x;
  thisResults[1] = MAND_point.y;
  thisResults[2] = MAND_point.z;
  thisResults[3] = OROZ_point.x;
  thisResults[4] = OROZ_point.y;
  thisResults[5] = OROZ_point.z;
  thisResults[6] = SANC_point.x;
  thisResults[7] = SANC_point.y;
  thisResults[8] = SANC_point.z;
  thisResults[9] = ARJO_point.x;
  thisResults[10] = ARJO_point.y;
  thisResults[11] = ARJO_point.z;
  thisResults[12] = CANI_point.x;
  thisResults[13] = CANI_point.y;
  thisResults[14] = CANI_point.z;
  thisResults[15] = HALC_point.x;
  thisResults[16] = HALC_point.y;
  thisResults[17] = HALC_point.z;

  displayResults(thisResults, 4, true);
}

void Examples_05()
{
  // TOPCON
  TGeodeticCoords MAND_92633(
      TCoords(37, 53, 33.072573).getDecimalValue(), TCoords(-3, 43, 52.68965).getDecimalValue(),
      515.579);
  TGeodeticCoords OROZ_96965(
      TCoords(37, 35, 31.75505).getDecimalValue(), TCoords(-3, 38, 5.70754).getDecimalValue(),
      1489.188);
  TGeodeticCoords SANC_94744(
      TCoords(37, 44, 29.04253).getDecimalValue(), TCoords(-3, 43, 12.90285).getDecimalValue(),
      1054.189);
  TGeodeticCoords ARJO_94633(
      TCoords(37, 43, 51.28918).getDecimalValue(), TCoords(-4, 3, 48.64503).getDecimalValue(),
      569.182);
  TGeodeticCoords CANI_96833(
      TCoords(37, 33, 6.94237).getDecimalValue(), TCoords(-4, 3, 28.81611).getDecimalValue(),
      897.626);
  TGeodeticCoords HALC_92543(
      TCoords(37, 53, 11.26838).getDecimalValue(), TCoords(-4, 2, 44.35794).getDecimalValue(),
      530.446);

  const TEllipsoid ellip = TEllipsoid(6378137, 6356752.31424518, "USER");

  // A2
  int UTMZone;
  char UTMBand;
  TUTMCoords MAND_UTM, OROZ_UTM, SANC_UTM, ARJO_UTM, CANI_UTM, HALC_UTM;
  geodeticToUTM(MAND_92633, MAND_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(OROZ_96965, OROZ_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(SANC_94744, SANC_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(ARJO_94633, ARJO_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(CANI_96833, CANI_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(HALC_92543, HALC_UTM, UTMZone, UTMBand, ellip);

  // A5
  TUTMCoords MAND_point, OROZ_point, SANC_point, ARJO_point, CANI_point, HALC_point;
  TDatum7Params_TOPCON datum(
      109.035107801496, 202.610276063935, 32.727057571807, 0.9999999999, 0.0000005460, 0.0000156068,
      -0.0000005463, 0.9999999998, 0.0000180851, -0.0000156068, -0.0000180851, 0.9999999997,
      0.842993545636);
  transform7params_TOPCON(MAND_UTM, datum, MAND_point);
  transform7params_TOPCON(OROZ_UTM, datum, OROZ_point);
  transform7params_TOPCON(SANC_UTM, datum, SANC_point);
  transform7params_TOPCON(ARJO_UTM, datum, ARJO_point);
  transform7params_TOPCON(CANI_UTM, datum, CANI_point);
  transform7params_TOPCON(HALC_UTM, datum, HALC_point);

  CVectorDouble thisResults;
  thisResults.resize(18);

  thisResults[0] = MAND_point.x;
  thisResults[1] = MAND_point.y;
  thisResults[2] = MAND_point.z;
  thisResults[3] = OROZ_point.x;
  thisResults[4] = OROZ_point.y;
  thisResults[5] = OROZ_point.z;
  thisResults[6] = SANC_point.x;
  thisResults[7] = SANC_point.y;
  thisResults[8] = SANC_point.z;
  thisResults[9] = ARJO_point.x;
  thisResults[10] = ARJO_point.y;
  thisResults[11] = ARJO_point.z;
  thisResults[12] = CANI_point.x;
  thisResults[13] = CANI_point.y;
  thisResults[14] = CANI_point.z;
  thisResults[15] = HALC_point.x;
  thisResults[16] = HALC_point.y;
  thisResults[17] = HALC_point.z;

  displayResults(thisResults, 5, true);
}

void Examples_06()
{
  TGeodeticCoords MAND_92633(
      TCoords(37, 53, 33.072573).getDecimalValue(), TCoords(-3, 43, 52.68965).getDecimalValue(),
      515.579);
  TGeodeticCoords OROZ_96965(
      TCoords(37, 35, 31.75505).getDecimalValue(), TCoords(-3, 38, 5.70754).getDecimalValue(),
      1489.188);
  TGeodeticCoords SANC_94744(
      TCoords(37, 44, 29.04253).getDecimalValue(), TCoords(-3, 43, 12.90285).getDecimalValue(),
      1054.189);
  TGeodeticCoords ARJO_94633(
      TCoords(37, 43, 51.28918).getDecimalValue(), TCoords(-4, 3, 48.64503).getDecimalValue(),
      569.182);
  TGeodeticCoords CANI_96833(
      TCoords(37, 33, 6.94237).getDecimalValue(), TCoords(-4, 3, 28.81611).getDecimalValue(),
      897.626);
  TGeodeticCoords HALC_92543(
      TCoords(37, 53, 11.26838).getDecimalValue(), TCoords(-4, 2, 44.35794).getDecimalValue(),
      530.446);

  const TEllipsoid ellip = TEllipsoid::Ellipsoid_Internacional_1924();

  // A3
  TGeocentricCoords MAND_Geoc, OROZ_Geoc, SANC_Geoc, ARJO_Geoc, CANI_Geoc, HALC_Geoc;
  geodeticToGeocentric(MAND_92633, MAND_Geoc, ellip);
  geodeticToGeocentric(OROZ_96965, OROZ_Geoc, ellip);
  geodeticToGeocentric(SANC_94744, SANC_Geoc, ellip);
  geodeticToGeocentric(ARJO_94633, ARJO_Geoc, ellip);
  geodeticToGeocentric(CANI_96833, CANI_Geoc, ellip);
  geodeticToGeocentric(HALC_92543, HALC_Geoc, ellip);

  // A5
  TGeocentricCoords MAND_Geoc2, OROZ_Geoc2, SANC_Geoc2, ARJO_Geoc2, CANI_Geoc2, HALC_Geoc2;
  TDatum7Params datum(131.0320, 100.2510, 163.3540, -1.2438, -0.0195, -1.1436, -9.3900);
  transform7params(MAND_Geoc, datum, MAND_Geoc2);
  transform7params(OROZ_Geoc, datum, OROZ_Geoc2);
  transform7params(SANC_Geoc, datum, SANC_Geoc2);
  transform7params(ARJO_Geoc, datum, ARJO_Geoc2);
  transform7params(CANI_Geoc, datum, CANI_Geoc2);
  transform7params(HALC_Geoc, datum, HALC_Geoc2);

  // A4
  TGeodeticCoords MAND_Geod, OROZ_Geod, SANC_Geod, ARJO_Geod, CANI_Geod, HALC_Geod;
  geocentricToGeodetic(MAND_Geoc2, MAND_Geod, ellip);
  geocentricToGeodetic(OROZ_Geoc2, OROZ_Geod, ellip);
  geocentricToGeodetic(SANC_Geoc2, SANC_Geod, ellip);
  geocentricToGeodetic(ARJO_Geoc2, ARJO_Geod, ellip);
  geocentricToGeodetic(CANI_Geoc2, CANI_Geod, ellip);
  geocentricToGeodetic(HALC_Geoc2, HALC_Geod, ellip);

  // A2
  int UTMZone;
  char UTMBand;
  TUTMCoords MAND_UTM, OROZ_UTM, SANC_UTM, ARJO_UTM, CANI_UTM, HALC_UTM;
  geodeticToUTM(MAND_Geod, MAND_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(OROZ_Geod, OROZ_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(SANC_Geod, SANC_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(ARJO_Geod, ARJO_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(CANI_Geod, CANI_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(HALC_Geod, HALC_UTM, UTMZone, UTMBand, ellip);

  CVectorDouble thisResults;
  thisResults.resize(18);

  thisResults[0] = MAND_UTM.x;
  thisResults[1] = MAND_UTM.y;
  thisResults[2] = MAND_UTM.z;
  thisResults[3] = OROZ_UTM.x;
  thisResults[4] = OROZ_UTM.y;
  thisResults[5] = OROZ_UTM.z;
  thisResults[6] = SANC_UTM.x;
  thisResults[7] = SANC_UTM.y;
  thisResults[8] = SANC_UTM.z;
  thisResults[9] = ARJO_UTM.x;
  thisResults[10] = ARJO_UTM.y;
  thisResults[11] = ARJO_UTM.z;
  thisResults[12] = CANI_UTM.x;
  thisResults[13] = CANI_UTM.y;
  thisResults[14] = CANI_UTM.z;
  thisResults[15] = HALC_UTM.x;
  thisResults[16] = HALC_UTM.y;
  thisResults[17] = HALC_UTM.z;

  displayResults(thisResults, 6, false);

  // A7
  TPoint2D MAND_point, OROZ_point, SANC_point, ARJO_point, CANI_point, HALC_point;
  TDatumHelmert2D_TOPCON dat(0.9999980621, 0.0000078756, -31.7350304827, 10.8014994871);
  transformHelmert2D_TOPCON(TPoint2D(MAND_UTM.x, MAND_UTM.y), dat, MAND_point);
  transformHelmert2D_TOPCON(TPoint2D(OROZ_UTM.x, OROZ_UTM.y), dat, OROZ_point);
  transformHelmert2D_TOPCON(TPoint2D(SANC_UTM.x, SANC_UTM.y), dat, SANC_point);
  transformHelmert2D_TOPCON(TPoint2D(ARJO_UTM.x, ARJO_UTM.y), dat, ARJO_point);
  transformHelmert2D_TOPCON(TPoint2D(CANI_UTM.x, CANI_UTM.y), dat, CANI_point);
  transformHelmert2D_TOPCON(TPoint2D(HALC_UTM.x, HALC_UTM.y), dat, HALC_point);

  thisResults[0] = MAND_point.x;
  thisResults[1] = MAND_point.y;
  thisResults[2] = MAND_UTM.z;
  thisResults[3] = OROZ_point.x;
  thisResults[4] = OROZ_point.y;
  thisResults[5] = OROZ_UTM.z;
  thisResults[6] = SANC_point.x;
  thisResults[7] = SANC_point.y;
  thisResults[8] = SANC_UTM.z;
  thisResults[9] = ARJO_point.x;
  thisResults[10] = ARJO_point.y;
  thisResults[11] = ARJO_UTM.z;
  thisResults[12] = CANI_point.x;
  thisResults[13] = CANI_point.y;
  thisResults[14] = CANI_UTM.z;
  thisResults[15] = HALC_point.x;
  thisResults[16] = HALC_point.y;
  thisResults[17] = HALC_UTM.z;

  displayResults(thisResults, 6, true);
}

void Examples_07()
{
  TGeodeticCoords MAND_92633(
      TCoords(37, 53, 33.072573).getDecimalValue(), TCoords(-3, 43, 52.68965).getDecimalValue(),
      515.579);
  TGeodeticCoords OROZ_96965(
      TCoords(37, 35, 31.75505).getDecimalValue(), TCoords(-3, 38, 5.70754).getDecimalValue(),
      1489.188);
  TGeodeticCoords SANC_94744(
      TCoords(37, 44, 29.04253).getDecimalValue(), TCoords(-3, 43, 12.90285).getDecimalValue(),
      1054.189);
  TGeodeticCoords ARJO_94633(
      TCoords(37, 43, 51.28918).getDecimalValue(), TCoords(-4, 3, 48.64503).getDecimalValue(),
      569.182);
  TGeodeticCoords CANI_96833(
      TCoords(37, 33, 6.94237).getDecimalValue(), TCoords(-4, 3, 28.81611).getDecimalValue(),
      897.626);
  TGeodeticCoords HALC_92543(
      TCoords(37, 53, 11.26838).getDecimalValue(), TCoords(-4, 2, 44.35794).getDecimalValue(),
      530.446);

  const TEllipsoid ellip = TEllipsoid::Ellipsoid_Internacional_1924();

  // A3
  TGeocentricCoords MAND_Geoc, OROZ_Geoc, SANC_Geoc, ARJO_Geoc, CANI_Geoc, HALC_Geoc;
  geodeticToGeocentric(MAND_92633, MAND_Geoc, ellip);
  geodeticToGeocentric(OROZ_96965, OROZ_Geoc, ellip);
  geodeticToGeocentric(SANC_94744, SANC_Geoc, ellip);
  geodeticToGeocentric(ARJO_94633, ARJO_Geoc, ellip);
  geodeticToGeocentric(CANI_96833, CANI_Geoc, ellip);
  geodeticToGeocentric(HALC_92543, HALC_Geoc, ellip);

  // A5
  TGeocentricCoords MAND_Geoc2, OROZ_Geoc2, SANC_Geoc2, ARJO_Geoc2, CANI_Geoc2, HALC_Geoc2;
  TDatum7Params datum(131.0320, 100.2510, 163.3540, -1.2438, -0.0195, -1.1436, -9.3900);
  transform7params(MAND_Geoc, datum, MAND_Geoc2);
  transform7params(OROZ_Geoc, datum, OROZ_Geoc2);
  transform7params(SANC_Geoc, datum, SANC_Geoc2);
  transform7params(ARJO_Geoc, datum, ARJO_Geoc2);
  transform7params(CANI_Geoc, datum, CANI_Geoc2);
  transform7params(HALC_Geoc, datum, HALC_Geoc2);

  // A4
  TGeodeticCoords MAND_Geod, OROZ_Geod, SANC_Geod, ARJO_Geod, CANI_Geod, HALC_Geod;
  geocentricToGeodetic(MAND_Geoc2, MAND_Geod, ellip);
  geocentricToGeodetic(OROZ_Geoc2, OROZ_Geod, ellip);
  geocentricToGeodetic(SANC_Geoc2, SANC_Geod, ellip);
  geocentricToGeodetic(ARJO_Geoc2, ARJO_Geod, ellip);
  geocentricToGeodetic(CANI_Geoc2, CANI_Geod, ellip);
  geocentricToGeodetic(HALC_Geoc2, HALC_Geod, ellip);

  // A2
  int UTMZone;
  char UTMBand;
  TUTMCoords MAND_UTM, OROZ_UTM, SANC_UTM, ARJO_UTM, CANI_UTM, HALC_UTM;
  geodeticToUTM(MAND_Geod, MAND_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(OROZ_Geod, OROZ_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(SANC_Geod, SANC_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(ARJO_Geod, ARJO_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(CANI_Geod, CANI_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(HALC_Geod, HALC_UTM, UTMZone, UTMBand, ellip);

  CVectorDouble thisResults;
  thisResults.resize(18);

  thisResults[0] = MAND_UTM.x;
  thisResults[1] = MAND_UTM.y;
  thisResults[2] = MAND_UTM.z;
  thisResults[3] = OROZ_UTM.x;
  thisResults[4] = OROZ_UTM.y;
  thisResults[5] = OROZ_UTM.z;
  thisResults[6] = SANC_UTM.x;
  thisResults[7] = SANC_UTM.y;
  thisResults[8] = SANC_UTM.z;
  thisResults[9] = ARJO_UTM.x;
  thisResults[10] = ARJO_UTM.y;
  thisResults[11] = ARJO_UTM.z;
  thisResults[12] = CANI_UTM.x;
  thisResults[13] = CANI_UTM.y;
  thisResults[14] = CANI_UTM.z;
  thisResults[15] = HALC_UTM.x;
  thisResults[16] = HALC_UTM.y;
  thisResults[17] = HALC_UTM.z;

  displayResults(thisResults, 7, false);

  // A8
  TPoint3D MAND_point, OROZ_point, SANC_point, ARJO_point, CANI_point, HALC_point;
  TDatumHelmert3D_TOPCON dat(
      0.9999944446, 0.0000005236, 0.5022460081, -0.0000136628, 1.0000023039, -4.4675776973,
      29.2747378118);
  transformHelmert3D_TOPCON(MAND_UTM, dat, MAND_point);
  transformHelmert3D_TOPCON(OROZ_UTM, dat, OROZ_point);
  transformHelmert3D_TOPCON(SANC_UTM, dat, SANC_point);
  transformHelmert3D_TOPCON(ARJO_UTM, dat, ARJO_point);
  transformHelmert3D_TOPCON(CANI_UTM, dat, CANI_point);
  transformHelmert3D_TOPCON(HALC_UTM, dat, HALC_point);

  thisResults[0] = MAND_point.x;
  thisResults[1] = MAND_point.y;
  thisResults[2] = MAND_point.z;
  thisResults[3] = OROZ_point.x;
  thisResults[4] = OROZ_point.y;
  thisResults[5] = OROZ_point.z;
  thisResults[6] = SANC_point.x;
  thisResults[7] = SANC_point.y;
  thisResults[8] = SANC_point.z;
  thisResults[9] = ARJO_point.x;
  thisResults[10] = ARJO_point.y;
  thisResults[11] = ARJO_point.z;
  thisResults[12] = CANI_point.x;
  thisResults[13] = CANI_point.y;
  thisResults[14] = CANI_point.z;
  thisResults[15] = HALC_point.x;
  thisResults[16] = HALC_point.y;
  thisResults[17] = HALC_point.z;

  displayResults(thisResults, 7, true);
}

void Examples_08()
{
  TGeodeticCoords MAND_92633(
      TCoords(37, 53, 33.072573).getDecimalValue(), TCoords(-3, 43, 52.68965).getDecimalValue(),
      515.579);
  TGeodeticCoords OROZ_96965(
      TCoords(37, 35, 31.75505).getDecimalValue(), TCoords(-3, 38, 5.70754).getDecimalValue(),
      1489.188);
  TGeodeticCoords SANC_94744(
      TCoords(37, 44, 29.04253).getDecimalValue(), TCoords(-3, 43, 12.90285).getDecimalValue(),
      1054.189);
  TGeodeticCoords ARJO_94633(
      TCoords(37, 43, 51.28918).getDecimalValue(), TCoords(-4, 3, 48.64503).getDecimalValue(),
      569.182);
  TGeodeticCoords CANI_96833(
      TCoords(37, 33, 6.94237).getDecimalValue(), TCoords(-4, 3, 28.81611).getDecimalValue(),
      897.626);
  TGeodeticCoords HALC_92543(
      TCoords(37, 53, 11.26838).getDecimalValue(), TCoords(-4, 2, 44.35794).getDecimalValue(),
      530.446);

  const TEllipsoid ellip = TEllipsoid::Ellipsoid_Internacional_1924();

  // A3
  TGeocentricCoords MAND_Geoc, OROZ_Geoc, SANC_Geoc, ARJO_Geoc, CANI_Geoc, HALC_Geoc;
  geodeticToGeocentric(MAND_92633, MAND_Geoc, ellip);
  geodeticToGeocentric(OROZ_96965, OROZ_Geoc, ellip);
  geodeticToGeocentric(SANC_94744, SANC_Geoc, ellip);
  geodeticToGeocentric(ARJO_94633, ARJO_Geoc, ellip);
  geodeticToGeocentric(CANI_96833, CANI_Geoc, ellip);
  geodeticToGeocentric(HALC_92543, HALC_Geoc, ellip);

  // A5
  TGeocentricCoords MAND_Geoc2, OROZ_Geoc2, SANC_Geoc2, ARJO_Geoc2, CANI_Geoc2, HALC_Geoc2;
  TDatum7Params datum(131.0320, 100.2510, 163.3540, -1.2438, -0.0195, -1.1436, -9.3900);
  transform7params(MAND_Geoc, datum, MAND_Geoc2);
  transform7params(OROZ_Geoc, datum, OROZ_Geoc2);
  transform7params(SANC_Geoc, datum, SANC_Geoc2);
  transform7params(ARJO_Geoc, datum, ARJO_Geoc2);
  transform7params(CANI_Geoc, datum, CANI_Geoc2);
  transform7params(HALC_Geoc, datum, HALC_Geoc2);

  // A4
  TGeodeticCoords MAND_Geod, OROZ_Geod, SANC_Geod, ARJO_Geod, CANI_Geod, HALC_Geod;
  geocentricToGeodetic(MAND_Geoc2, MAND_Geod, ellip);
  geocentricToGeodetic(OROZ_Geoc2, OROZ_Geod, ellip);
  geocentricToGeodetic(SANC_Geoc2, SANC_Geod, ellip);
  geocentricToGeodetic(ARJO_Geoc2, ARJO_Geod, ellip);
  geocentricToGeodetic(CANI_Geoc2, CANI_Geod, ellip);
  geocentricToGeodetic(HALC_Geoc2, HALC_Geod, ellip);

  // A2
  int UTMZone;
  char UTMBand;
  TUTMCoords MAND_UTM, OROZ_UTM, SANC_UTM, ARJO_UTM, CANI_UTM, HALC_UTM;
  geodeticToUTM(MAND_Geod, MAND_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(OROZ_Geod, OROZ_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(SANC_Geod, SANC_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(ARJO_Geod, ARJO_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(CANI_Geod, CANI_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(HALC_Geod, HALC_UTM, UTMZone, UTMBand, ellip);

  CVectorDouble thisResults;
  thisResults.resize(18);

  thisResults[0] = MAND_UTM.x;
  thisResults[1] = MAND_UTM.y;
  thisResults[2] = MAND_UTM.z;
  thisResults[3] = OROZ_UTM.x;
  thisResults[4] = OROZ_UTM.y;
  thisResults[5] = OROZ_UTM.z;
  thisResults[6] = SANC_UTM.x;
  thisResults[7] = SANC_UTM.y;
  thisResults[8] = SANC_UTM.z;
  thisResults[9] = ARJO_UTM.x;
  thisResults[10] = ARJO_UTM.y;
  thisResults[11] = ARJO_UTM.z;
  thisResults[12] = CANI_UTM.x;
  thisResults[13] = CANI_UTM.y;
  thisResults[14] = CANI_UTM.z;
  thisResults[15] = HALC_UTM.x;
  thisResults[16] = HALC_UTM.y;
  thisResults[17] = HALC_UTM.z;

  displayResults(thisResults, 8, false);

  // A5
  TGeocentricCoords MAND_Geoc3, OROZ_Geoc3, SANC_Geoc3, ARJO_Geoc3, CANI_Geoc3, HALC_Geoc3;
  // TDatum7Params	dat( -34.095438458048, 10.843234125336,
  // 212.169692142148,
  // -8.348308019638, 6.751893142065, -1.738975581025, -1.898114919019 );
  TDatum7Params_TOPCON dat(
      -34.095438458048, 10.843234125336, 212.169692142148, 0.9999999994, 0.0000084308, 0.0000327341,
      -0.0000084321, 0.9999999991, 0.0000404737, -0.0000327338, -0.0000404737, 0.9999999986,
      -1.898114919019);
  transform7params_TOPCON(MAND_UTM, dat, MAND_Geoc3);
  transform7params_TOPCON(OROZ_UTM, dat, OROZ_Geoc3);
  transform7params_TOPCON(SANC_UTM, dat, SANC_Geoc3);
  transform7params_TOPCON(ARJO_UTM, dat, ARJO_Geoc3);
  transform7params_TOPCON(CANI_UTM, dat, CANI_Geoc3);
  transform7params_TOPCON(HALC_UTM, dat, HALC_Geoc3);

  thisResults[0] = MAND_Geoc3.x;
  thisResults[1] = MAND_Geoc3.y;
  thisResults[2] = MAND_Geoc3.z;
  thisResults[3] = OROZ_Geoc3.x;
  thisResults[4] = OROZ_Geoc3.y;
  thisResults[5] = OROZ_Geoc3.z;
  thisResults[6] = SANC_Geoc3.x;
  thisResults[7] = SANC_Geoc3.y;
  thisResults[8] = SANC_Geoc3.z;
  thisResults[9] = ARJO_Geoc3.x;
  thisResults[10] = ARJO_Geoc3.y;
  thisResults[11] = ARJO_Geoc3.z;
  thisResults[12] = CANI_Geoc3.x;
  thisResults[13] = CANI_Geoc3.y;
  thisResults[14] = CANI_Geoc3.z;
  thisResults[15] = HALC_Geoc3.x;
  thisResults[16] = HALC_Geoc3.y;
  thisResults[17] = HALC_Geoc3.z;

  displayResults(thisResults, 8, true);
}

void Examples_10()
{
  TGeodeticCoords MAND_92633(
      TCoords(37, 53, 33.072573).getDecimalValue(), TCoords(-3, 43, 52.68965).getDecimalValue(),
      515.579);
  TGeodeticCoords OROZ_96965(
      TCoords(37, 35, 31.75505).getDecimalValue(), TCoords(-3, 38, 5.70754).getDecimalValue(),
      1489.188);
  TGeodeticCoords SANC_94744(
      TCoords(37, 44, 29.04253).getDecimalValue(), TCoords(-3, 43, 12.90285).getDecimalValue(),
      1054.189);
  TGeodeticCoords ARJO_94633(
      TCoords(37, 43, 51.28918).getDecimalValue(), TCoords(-4, 3, 48.64503).getDecimalValue(),
      569.182);
  TGeodeticCoords CANI_96833(
      TCoords(37, 33, 6.94237).getDecimalValue(), TCoords(-4, 3, 28.81611).getDecimalValue(),
      897.626);
  TGeodeticCoords HALC_92543(
      TCoords(37, 53, 11.26838).getDecimalValue(), TCoords(-4, 2, 44.35794).getDecimalValue(),
      530.446);

  const TEllipsoid ellip = TEllipsoid::Ellipsoid_Hayford_1909();

  // A3
  TGeocentricCoords MAND_Geoc, OROZ_Geoc, SANC_Geoc, ARJO_Geoc, CANI_Geoc, HALC_Geoc;
  geodeticToGeocentric(MAND_92633, MAND_Geoc, ellip);
  geodeticToGeocentric(OROZ_96965, OROZ_Geoc, ellip);
  geodeticToGeocentric(SANC_94744, SANC_Geoc, ellip);
  geodeticToGeocentric(ARJO_94633, ARJO_Geoc, ellip);
  geodeticToGeocentric(CANI_96833, CANI_Geoc, ellip);
  geodeticToGeocentric(HALC_92543, HALC_Geoc, ellip);

  // A5
  TGeocentricCoords MAND_Geoc2, OROZ_Geoc2, SANC_Geoc2, ARJO_Geoc2, CANI_Geoc2, HALC_Geoc2;
  TDatum7Params datum(284.2535, -116.9549, -34.8027, 4.78337, 7.96684, -5.37707, -6.6900);
  transform7params(MAND_Geoc, datum, MAND_Geoc2);
  transform7params(OROZ_Geoc, datum, OROZ_Geoc2);
  transform7params(SANC_Geoc, datum, SANC_Geoc2);
  transform7params(ARJO_Geoc, datum, ARJO_Geoc2);
  transform7params(CANI_Geoc, datum, CANI_Geoc2);
  transform7params(HALC_Geoc, datum, HALC_Geoc2);

  // A4
  TGeodeticCoords MAND_Geod, OROZ_Geod, SANC_Geod, ARJO_Geod, CANI_Geod, HALC_Geod;
  geocentricToGeodetic(MAND_Geoc2, MAND_Geod, ellip);
  geocentricToGeodetic(OROZ_Geoc2, OROZ_Geod, ellip);
  geocentricToGeodetic(SANC_Geoc2, SANC_Geod, ellip);
  geocentricToGeodetic(ARJO_Geoc2, ARJO_Geod, ellip);
  geocentricToGeodetic(CANI_Geoc2, CANI_Geod, ellip);
  geocentricToGeodetic(HALC_Geoc2, HALC_Geod, ellip);

  // A2
  int UTMZone;
  char UTMBand;
  TUTMCoords MAND_UTM, OROZ_UTM, SANC_UTM, ARJO_UTM, CANI_UTM, HALC_UTM;
  geodeticToUTM(MAND_Geod, MAND_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(OROZ_Geod, OROZ_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(SANC_Geod, SANC_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(ARJO_Geod, ARJO_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(CANI_Geod, CANI_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(HALC_Geod, HALC_UTM, UTMZone, UTMBand, ellip);

  CVectorDouble thisResults;
  thisResults.resize(18);

  thisResults[0] = MAND_UTM.x;
  thisResults[1] = MAND_UTM.y;
  thisResults[2] = MAND_UTM.z;
  thisResults[3] = OROZ_UTM.x;
  thisResults[4] = OROZ_UTM.y;
  thisResults[5] = OROZ_UTM.z;
  thisResults[6] = SANC_UTM.x;
  thisResults[7] = SANC_UTM.y;
  thisResults[8] = SANC_UTM.z;
  thisResults[9] = ARJO_UTM.x;
  thisResults[10] = ARJO_UTM.y;
  thisResults[11] = ARJO_UTM.z;
  thisResults[12] = CANI_UTM.x;
  thisResults[13] = CANI_UTM.y;
  thisResults[14] = CANI_UTM.z;
  thisResults[15] = HALC_UTM.x;
  thisResults[16] = HALC_UTM.y;
  thisResults[17] = HALC_UTM.z;

  displayResults(thisResults, 10, true);
}

void Examples_11()
{
  TGeodeticCoords MAND_92633(
      TCoords(37, 53, 33.072573).getDecimalValue(), TCoords(-3, 43, 52.68965).getDecimalValue(),
      515.579);
  TGeodeticCoords OROZ_96965(
      TCoords(37, 35, 31.75505).getDecimalValue(), TCoords(-3, 38, 5.70754).getDecimalValue(),
      1489.188);
  TGeodeticCoords SANC_94744(
      TCoords(37, 44, 29.04253).getDecimalValue(), TCoords(-3, 43, 12.90285).getDecimalValue(),
      1054.189);
  TGeodeticCoords ARJO_94633(
      TCoords(37, 43, 51.28918).getDecimalValue(), TCoords(-4, 3, 48.64503).getDecimalValue(),
      569.182);
  TGeodeticCoords CANI_96833(
      TCoords(37, 33, 6.94237).getDecimalValue(), TCoords(-4, 3, 28.81611).getDecimalValue(),
      897.626);
  TGeodeticCoords HALC_92543(
      TCoords(37, 53, 11.26838).getDecimalValue(), TCoords(-4, 2, 44.35794).getDecimalValue(),
      530.446);

  const TEllipsoid ellip = TEllipsoid::Ellipsoid_Hayford_1909();

  // A3
  TGeocentricCoords MAND_Geoc, OROZ_Geoc, SANC_Geoc, ARJO_Geoc, CANI_Geoc, HALC_Geoc;
  geodeticToGeocentric(MAND_92633, MAND_Geoc, ellip);
  geodeticToGeocentric(OROZ_96965, OROZ_Geoc, ellip);
  geodeticToGeocentric(SANC_94744, SANC_Geoc, ellip);
  geodeticToGeocentric(ARJO_94633, ARJO_Geoc, ellip);
  geodeticToGeocentric(CANI_96833, CANI_Geoc, ellip);
  geodeticToGeocentric(HALC_92543, HALC_Geoc, ellip);

  // A6
  TGeocentricCoords MAND_Geoc2, OROZ_Geoc2, SANC_Geoc2, ARJO_Geoc2, CANI_Geoc2, HALC_Geoc2;
  TDatum10Params datum(
      109.4714, 106.7407, 141.7916, 5039726.4242, -341417.6071, 3882515.5524, 4.78337, 7.96684,
      -5.37707, -6.6900);
  transform10params(MAND_Geoc, datum, MAND_Geoc2);
  transform10params(OROZ_Geoc, datum, OROZ_Geoc2);
  transform10params(SANC_Geoc, datum, SANC_Geoc2);
  transform10params(ARJO_Geoc, datum, ARJO_Geoc2);
  transform10params(CANI_Geoc, datum, CANI_Geoc2);
  transform10params(HALC_Geoc, datum, HALC_Geoc2);

  // A4
  TGeodeticCoords MAND_Geod, OROZ_Geod, SANC_Geod, ARJO_Geod, CANI_Geod, HALC_Geod;
  geocentricToGeodetic(MAND_Geoc2, MAND_Geod, ellip);
  geocentricToGeodetic(OROZ_Geoc2, OROZ_Geod, ellip);
  geocentricToGeodetic(SANC_Geoc2, SANC_Geod, ellip);
  geocentricToGeodetic(ARJO_Geoc2, ARJO_Geod, ellip);
  geocentricToGeodetic(CANI_Geoc2, CANI_Geod, ellip);
  geocentricToGeodetic(HALC_Geoc2, HALC_Geod, ellip);

  // A2
  int UTMZone;
  char UTMBand;
  TUTMCoords MAND_UTM, OROZ_UTM, SANC_UTM, ARJO_UTM, CANI_UTM, HALC_UTM;
  geodeticToUTM(MAND_Geod, MAND_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(OROZ_Geod, OROZ_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(SANC_Geod, SANC_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(ARJO_Geod, ARJO_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(CANI_Geod, CANI_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(HALC_Geod, HALC_UTM, UTMZone, UTMBand, ellip);

  CVectorDouble thisResults;
  thisResults.resize(18);

  thisResults[0] = MAND_UTM.x;
  thisResults[1] = MAND_UTM.y;
  thisResults[2] = MAND_UTM.z;
  thisResults[3] = OROZ_UTM.x;
  thisResults[4] = OROZ_UTM.y;
  thisResults[5] = OROZ_UTM.z;
  thisResults[6] = SANC_UTM.x;
  thisResults[7] = SANC_UTM.y;
  thisResults[8] = SANC_UTM.z;
  thisResults[9] = ARJO_UTM.x;
  thisResults[10] = ARJO_UTM.y;
  thisResults[11] = ARJO_UTM.z;
  thisResults[12] = CANI_UTM.x;
  thisResults[13] = CANI_UTM.y;
  thisResults[14] = CANI_UTM.z;
  thisResults[15] = HALC_UTM.x;
  thisResults[16] = HALC_UTM.y;
  thisResults[17] = HALC_UTM.z;

  displayResults(thisResults, 11, true);
}

void Examples_12()
{
  TGeodeticCoords MAND_92633(
      TCoords(37, 53, 33.072573).getDecimalValue(), TCoords(-3, 43, 52.68965).getDecimalValue(),
      515.579);
  TGeodeticCoords OROZ_96965(
      TCoords(37, 35, 31.75505).getDecimalValue(), TCoords(-3, 38, 5.70754).getDecimalValue(),
      1489.188);
  TGeodeticCoords SANC_94744(
      TCoords(37, 44, 29.04253).getDecimalValue(), TCoords(-3, 43, 12.90285).getDecimalValue(),
      1054.189);
  TGeodeticCoords ARJO_94633(
      TCoords(37, 43, 51.28918).getDecimalValue(), TCoords(-4, 3, 48.64503).getDecimalValue(),
      569.182);
  TGeodeticCoords CANI_96833(
      TCoords(37, 33, 6.94237).getDecimalValue(), TCoords(-4, 3, 28.81611).getDecimalValue(),
      897.626);
  TGeodeticCoords HALC_92543(
      TCoords(37, 53, 11.26838).getDecimalValue(), TCoords(-4, 2, 44.35794).getDecimalValue(),
      530.446);

  const TEllipsoid ellip = TEllipsoid::Ellipsoid_Hayford_1909();

  // A2
  int UTMZone;
  char UTMBand;
  TUTMCoords MAND_UTM, OROZ_UTM, SANC_UTM, ARJO_UTM, CANI_UTM, HALC_UTM;
  geodeticToUTM(MAND_92633, MAND_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(OROZ_96965, OROZ_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(SANC_94744, SANC_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(ARJO_94633, ARJO_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(CANI_96833, CANI_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(HALC_92543, HALC_UTM, UTMZone, UTMBand, ellip);

  // A7
  TPoint2D MAND_point, OROZ_point, SANC_point, ARJO_point, CANI_point, HALC_point;
  TDatumHelmert2D dat(
      15.8778, 0.4491, TCoords(0, 32, 8.75881).getDecimalValue() /*degrees*/, -325.9604,
      422956.6976, 4176709.7722);
  transformHelmert2D(TPoint2D(MAND_UTM.x, MAND_UTM.y), dat, MAND_point);
  transformHelmert2D(TPoint2D(OROZ_UTM.x, OROZ_UTM.y), dat, OROZ_point);
  transformHelmert2D(TPoint2D(SANC_UTM.x, SANC_UTM.y), dat, SANC_point);
  transformHelmert2D(TPoint2D(ARJO_UTM.x, ARJO_UTM.y), dat, ARJO_point);
  transformHelmert2D(TPoint2D(CANI_UTM.x, CANI_UTM.y), dat, CANI_point);
  transformHelmert2D(TPoint2D(HALC_UTM.x, HALC_UTM.y), dat, HALC_point);

  // A9
  TPoint3D MAND_point2, OROZ_point2, SANC_point2, ARJO_point2, CANI_point2, HALC_point2;
  TDatum1DTransf datum(-0.00001847 /*rad*/, -0.00001536 /*rad*/, -49.4041, 0);
  transform1D(TPoint3D(MAND_point.x, MAND_point.y, MAND_UTM.z), datum, MAND_point2);
  transform1D(TPoint3D(OROZ_point.x, OROZ_point.y, OROZ_UTM.z), datum, OROZ_point2);
  transform1D(TPoint3D(SANC_point.x, SANC_point.y, SANC_UTM.z), datum, SANC_point2);
  transform1D(TPoint3D(ARJO_point.x, ARJO_point.y, ARJO_UTM.z), datum, ARJO_point2);
  transform1D(TPoint3D(CANI_point.x, CANI_point.y, CANI_UTM.z), datum, CANI_point2);
  transform1D(TPoint3D(HALC_point.x, HALC_point.y, HALC_UTM.z), datum, HALC_point2);

  CVectorDouble thisResults;
  thisResults.resize(18);

  thisResults[0] = MAND_point2.x;
  thisResults[1] = MAND_point2.y;
  thisResults[2] = MAND_point2.z;
  thisResults[3] = OROZ_point2.x;
  thisResults[4] = OROZ_point2.y;
  thisResults[5] = OROZ_point2.z;
  thisResults[6] = SANC_point2.x;
  thisResults[7] = SANC_point2.y;
  thisResults[8] = SANC_point2.z;
  thisResults[9] = ARJO_point2.x;
  thisResults[10] = ARJO_point2.y;
  thisResults[11] = ARJO_point2.z;
  thisResults[12] = CANI_point2.x;
  thisResults[13] = CANI_point2.y;
  thisResults[14] = CANI_point2.z;
  thisResults[15] = HALC_point2.x;
  thisResults[16] = HALC_point2.y;
  thisResults[17] = HALC_point2.z;

  displayResults(thisResults, 12, true);
}

void Examples_13()
{
  TGeodeticCoords MAND_92633(
      TCoords(37, 53, 33.072573).getDecimalValue(), TCoords(-3, 43, 52.68965).getDecimalValue(),
      515.579);
  TGeodeticCoords OROZ_96965(
      TCoords(37, 35, 31.75505).getDecimalValue(), TCoords(-3, 38, 5.70754).getDecimalValue(),
      1489.188);
  TGeodeticCoords SANC_94744(
      TCoords(37, 44, 29.04253).getDecimalValue(), TCoords(-3, 43, 12.90285).getDecimalValue(),
      1054.189);
  TGeodeticCoords ARJO_94633(
      TCoords(37, 43, 51.28918).getDecimalValue(), TCoords(-4, 3, 48.64503).getDecimalValue(),
      569.182);
  TGeodeticCoords CANI_96833(
      TCoords(37, 33, 6.94237).getDecimalValue(), TCoords(-4, 3, 28.81611).getDecimalValue(),
      897.626);
  TGeodeticCoords HALC_92543(
      TCoords(37, 53, 11.26838).getDecimalValue(), TCoords(-4, 2, 44.35794).getDecimalValue(),
      530.446);

  const TEllipsoid ellip = TEllipsoid::Ellipsoid_Hayford_1909();

  // A2
  int UTMZone;
  char UTMBand;
  TUTMCoords MAND_UTM, OROZ_UTM, SANC_UTM, ARJO_UTM, CANI_UTM, HALC_UTM;
  geodeticToUTM(MAND_92633, MAND_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(OROZ_96965, OROZ_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(SANC_94744, SANC_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(ARJO_94633, ARJO_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(CANI_96833, CANI_UTM, UTMZone, UTMBand, ellip);
  geodeticToUTM(HALC_92543, HALC_UTM, UTMZone, UTMBand, ellip);

  // A10
  TPoint3D MAND_point, OROZ_point, SANC_point, ARJO_point, CANI_point, HALC_point;
  TDatumTransfInterpolation dat(
      423150.0514, 4197393.9437, -334.2393 /*ppm*/, -314.2785 /*ppm*/, 1.33958 /*secs*/);
  transfInterpolation(MAND_UTM, dat, MAND_point);
  transfInterpolation(OROZ_UTM, dat, OROZ_point);
  transfInterpolation(SANC_UTM, dat, SANC_point);
  transfInterpolation(ARJO_UTM, dat, ARJO_point);
  transfInterpolation(CANI_UTM, dat, CANI_point);
  transfInterpolation(HALC_UTM, dat, HALC_point);

  // A9
  TPoint3D MAND_point2, OROZ_point2, SANC_point2, ARJO_point2, CANI_point2, HALC_point2;
  TDatum1DTransf datum(-0.00001822 /*rad*/, -0.00001304 /*rad*/, -49.8094, 0);
  transform1D(MAND_point, datum, MAND_point2);
  transform1D(OROZ_point, datum, OROZ_point2);
  transform1D(SANC_point, datum, SANC_point2);
  transform1D(ARJO_point, datum, ARJO_point2);
  transform1D(CANI_point, datum, CANI_point2);
  transform1D(HALC_point, datum, HALC_point2);

  CVectorDouble thisResults;
  thisResults.resize(18);

  thisResults[0] = MAND_point2.x;
  thisResults[1] = MAND_point2.y;
  thisResults[2] = MAND_point2.z;
  thisResults[3] = OROZ_point2.x;
  thisResults[4] = OROZ_point2.y;
  thisResults[5] = OROZ_point2.z;
  thisResults[6] = SANC_point2.x;
  thisResults[7] = SANC_point2.y;
  thisResults[8] = SANC_point2.z;
  thisResults[9] = ARJO_point2.x;
  thisResults[10] = ARJO_point2.y;
  thisResults[11] = ARJO_point2.z;
  thisResults[12] = CANI_point2.x;
  thisResults[13] = CANI_point2.y;
  thisResults[14] = CANI_point2.z;
  thisResults[15] = HALC_point2.x;
  thisResults[16] = HALC_point2.y;
  thisResults[17] = HALC_point2.z;

  displayResults(thisResults, 13, true);
}

int main(int argc, char** argv)
{
  try
  {
    exampleResults();
    TestCoordinatesConversions();
    consoleColorAndStyle(ConsoleForegroundColor::BLUE);
    cout << "**************************************" << endl;
    cout << "\tTOPCON with th = " << TH << endl;
    cout << "**************************************" << endl;
    consoleColorAndStyle(ConsoleForegroundColor::DEFAULT);
    Examples_01();
    Examples_02();
    Examples_03();
    Examples_04();
    Examples_05();
    Examples_06();
    Examples_07();
    Examples_08();
    consoleColorAndStyle(ConsoleForegroundColor::BLUE);
    cout << "**************************************" << endl;
    cout << "\tLEICA with th = " << TH << endl;
    cout << "**************************************" << endl;
    consoleColorAndStyle(ConsoleForegroundColor::DEFAULT);
    cout << "Example 09 missing in pdf" << endl;
    Examples_10();
    Examples_11();
    Examples_12();
    Examples_13();

    return 0;
  }
  catch (const std::exception& e)
  {
    std::cerr << "MRPT error: " << mrpt::exception_to_str(e) << std::endl;
    return -1;
  }
  catch (...)
  {
    printf("Another exception!!");
    return -1;
  }
}
