EquidistantTest.cpp

Go to the documentation of this file.
00001 /**
00002  * \file EquidistantTest.cpp
00003  * \brief Command line utility for azimuthal equidistant and Cassini-Soldner
00004  * projections
00005  *
00006  * Copyright (c) Charles Karney (2009, 2010, 2011) <charles@karney.com>
00007  * and licensed under the LGPL.  For more information, see
00008  * http://geographiclib.sourceforge.net/
00009  *
00010  * Compile with -I../include and link with Geodesic.o GeodesicLine.o
00011  * AzimuthalEquidistant.o Gnomonic.o CassiniSoldner.o
00012  *
00013  * See the <a href="EquidistantTest.1.html">man page</a> for usage
00014  * information.
00015  **********************************************************************/
00016 
00017 #include "GeographicLib/Geodesic.hpp"
00018 #include "GeographicLib/AzimuthalEquidistant.hpp"
00019 #include "GeographicLib/CassiniSoldner.hpp"
00020 #include "GeographicLib/Gnomonic.hpp"
00021 #include "GeographicLib/DMS.hpp"
00022 #include <iostream>
00023 #include <sstream>
00024 
00025 #include "EquidistantTest.usage"
00026 
00027 int main(int argc, char* argv[]) {
00028   using namespace GeographicLib;
00029   typedef Math::real real;
00030   bool azimuthal = false, cassini = false, gnomonic = false, reverse = false;
00031   real lat0 = 0, lon0 = 0;
00032   real
00033     a = Constants::WGS84_a<real>(),
00034     r = Constants::WGS84_r<real>();
00035   for (int m = 1; m < argc; ++m) {
00036     std::string arg(argv[m]);
00037     if (arg == "-r")
00038       reverse = true;
00039     else if (arg == "-c" || arg == "-z" || arg == "-g") {
00040       cassini = arg == "-c";
00041       azimuthal = arg == "-z";
00042       gnomonic = arg == "-g";
00043       if (m + 2 >= argc) return usage(1, true);
00044       try {
00045         DMS::DecodeLatLon(std::string(argv[m + 1]), std::string(argv[m + 2]),
00046                           lat0, lon0);
00047       }
00048       catch (const std::exception& e) {
00049         std::cerr << "Error decoding arguments of " << arg << ": "
00050                   << e.what() << "\n";
00051         return 1;
00052       }
00053       m += 2;
00054     } else if (arg == "-e") {
00055       if (m + 2 >= argc) return usage(1, true);
00056       try {
00057         a = DMS::Decode(std::string(argv[m + 1]));
00058         r = DMS::Decode(std::string(argv[m + 2]));
00059       }
00060       catch (const std::exception& e) {
00061         std::cerr << "Error decoding arguments of -e: " << e.what() << "\n";
00062         return 1;
00063       }
00064       m += 2;
00065     } else if (arg == "--version") {
00066       std::cout
00067         << PROGRAM_NAME
00068         << ": $Id: EquidistantTest.cpp 6978 2011-02-21 22:42:11Z karney $\n"
00069         << "GeographicLib version " << GEOGRAPHICLIB_VERSION << "\n";
00070       return 0;
00071     } else
00072       return usage(!(arg == "-h" || arg == "--help"), arg != "--help");
00073   }
00074 
00075   if (!(azimuthal || cassini || gnomonic)) {
00076     std::cerr << "Must specify \"-z lat0 lon0\" or "
00077               << "\"-c lat0 lon0\" or \"-g lat0 lon0\"\n";
00078     return 1;
00079   }
00080 
00081   const Geodesic geod(a, r);
00082   const CassiniSoldner cs = cassini ?
00083     CassiniSoldner(lat0, lon0, geod) : CassiniSoldner(geod);
00084   const AzimuthalEquidistant az(geod);
00085   const Gnomonic gn(geod);
00086 
00087   std::string s;
00088   int retval = 0;
00089   std::cout << std::fixed;
00090   while (std::getline(std::cin, s)) {
00091     try {
00092       std::istringstream str(s);
00093       real lat, lon, x, y, azi, rk;
00094       std::string stra, strb;
00095       if (!(str >> stra >> strb))
00096         throw GeographicErr("Incomplete input: " + s);
00097       if (reverse) {
00098         x = DMS::Decode(stra);
00099         y = DMS::Decode(strb);
00100       } else
00101         DMS::DecodeLatLon(stra, strb, lat, lon);
00102       std::string strc;
00103       if (str >> strc)
00104         throw GeographicErr("Extraneous input: " + strc);
00105       if (reverse) {
00106         if (cassini)
00107           cs.Reverse(x, y, lat, lon, azi, rk);
00108         else if (azimuthal)
00109           az.Reverse(lat0, lon0, x, y, lat, lon, azi, rk);
00110         else
00111           gn.Reverse(lat0, lon0, x, y, lat, lon, azi, rk);
00112         std::cout << DMS::Encode(lat, 15, DMS::NUMBER) << " "
00113                   << DMS::Encode(lon, 15, DMS::NUMBER) << " "
00114                   << DMS::Encode(azi, 15, DMS::NUMBER) << " "
00115                   << DMS::Encode(rk, 16, DMS::NUMBER) << "\n";
00116       } else {
00117         if (cassini)
00118           cs.Forward(lat, lon, x, y, azi, rk);
00119         else if (azimuthal)
00120           az.Forward(lat0, lon0, lat, lon, x, y, azi, rk);
00121         else
00122           gn.Forward(lat0, lon0, lat, lon, x, y, azi, rk);
00123         std::cout << DMS::Encode(x, 10, DMS::NUMBER) << " "
00124                   << DMS::Encode(y, 10, DMS::NUMBER) << " "
00125                   << DMS::Encode(azi, 15, DMS::NUMBER) << " "
00126                   << DMS::Encode(rk, 16, DMS::NUMBER) << "\n";
00127       }
00128     }
00129     catch (const std::exception& e) {
00130       std::cout << "ERROR: " << e.what() << "\n";
00131       retval = 1;
00132     }
00133   }
00134 
00135   return retval;
00136 }