26 # pragma warning (disable: 4127) 37 s << std::scientific << std::setprecision(prec) << err;
42 (retval ? std::cerr : std:: cout ) <<
"Usage:\n" 44 " This implements some of the functionality of Geod3Solve(1) by integrating the\n" 45 " ordinary differential equations for the geodesic. Only direct geodesic\n" 46 " calculations are supported.\n" 48 " The following options of Geod3Solve(1) are supported\n" 49 " -t a b c | -e b e2 k2 kp2 \n" 50 " -L bet1 omg1 alp1\n" 57 " The following options of Geod3Solve(1) are not supported\n" 62 " The following are new options\n" 65 " bufferd mode (only useful with the -L option). Causes all the s12 values\n" 66 " to be buffered and fed into the integrator at the end. This sorts the\n" 67 " entries so that the integrator doesn't have to the continually restarted.\n" 70 " extended mode. Computes and prints the reduced length, m12, and the\n" 71 " geodesic scales, M12, M21.\n" 74 " sets the eps parameter in the constructor for TriaxialGeodesicODE.\n" 77 " use the dense solver allowing interpolated way points to tbe computed\n" 81 " force the solution vector onto the ellipsoid when computing the\n" 85 " print error estimates, the distance from the ellipsoid (in meters) and\n" 86 " the deviation of the velocity from a unit tangential vector.\n" 89 " print the number of integration steps and the number of times the\n" 90 " acceleration was computed.\n";
94 int main(
int argc,
const char*
const argv[]) {
97 using namespace Triaxial;
98 using namespace experimental;
100 bool dms =
false, longfirst =
false,
101 linecalc =
false, extended =
false, dense =
false, normp =
false,
102 buffered =
false, full =
false, errors =
false, steps =
false;
107 e2 = -1, k2 = 0, kp2 = 0, eps = 0;
108 ang bet1 =
ang(0), omg1 =
ang(0), alp1 =
ang(0), bet2, omg2, alp2;
109 real s12, m12, M12, M21;
110 std::vector<real> s12v;
112 std::string istring, ifile, ofile, cdelim;
113 char lsep =
';', dmssep = char(0);
115 for (
int m = 1; m < argc; ++m) {
116 std::string arg(argv[m]);
118 if (m + 3 >= argc)
return usage(1,
true);
120 a = Utility::val<real>(std::string(argv[m + 1]));
121 b = Utility::val<real>(std::string(argv[m + 2]));
122 c = Utility::val<real>(std::string(argv[m + 3]));
124 catch (
const std::exception& e) {
125 std::cerr <<
"Error decoding arguments of -t: " << e.what() <<
"\n";
130 }
else if (arg ==
"-e") {
133 if (m + 4 >= argc)
return usage(1,
true);
135 b = Utility::val<real>(std::string(argv[m + 1]));
136 e2 = Utility::fract<real>(std::string(argv[m + 2]));
137 k2 = Utility::fract<real>(std::string(argv[m + 3]));
138 kp2 = Utility::fract<real>(std::string(argv[m + 4]));
140 catch (
const std::exception& e) {
141 std::cerr <<
"Error decoding arguments of -e: " << e.what() <<
"\n";
146 }
else if (arg ==
"-x")
148 else if (arg ==
"-L") {
150 if (m + 3 >= argc)
return usage(1,
true);
153 std::string(argv[m + 2]),
154 bet1, omg1, longfirst);
157 catch (
const std::exception& e) {
158 std::cerr <<
"Error decoding arguments of -L: " << e.what() <<
"\n";
162 }
else if (arg ==
"--eps") {
163 if (m + 1 >= argc)
return usage(1,
true);
166 eps = pow(std::numeric_limits<real>::epsilon(),
167 Utility::fract<real>(std::string(argv[m + 1])));
169 catch (
const std::exception& e) {
170 std::cerr <<
"Error decoding argument of --eps: " << e.what() <<
"\n";
174 }
else if (arg ==
"--dense")
176 else if (arg ==
"--normp")
178 else if (arg ==
"--errors")
180 else if (arg ==
"--steps")
182 else if (arg ==
"-b")
184 else if (arg ==
"-f")
186 else if (arg ==
"-d") {
189 }
else if (arg ==
"-:") {
192 }
else if (arg ==
"-w")
193 longfirst = !longfirst;
194 else if (arg ==
"-p") {
195 if (++m == argc)
return usage(1,
true);
197 prec = Utility::val<int>(std::string(argv[m]));
199 catch (
const std::exception&) {
200 std::cerr <<
"Precision " << argv[m] <<
" is not a number\n";
203 }
else if (arg ==
"--input-string") {
204 if (++m == argc)
return usage(1,
true);
206 }
else if (arg ==
"--input-file") {
207 if (++m == argc)
return usage(1,
true);
209 }
else if (arg ==
"--output-file") {
210 if (++m == argc)
return usage(1,
true);
212 }
else if (arg ==
"--line-separator") {
213 if (++m == argc)
return usage(1,
true);
214 if (std::string(argv[m]).size() != 1) {
215 std::cerr <<
"Line separator must be a single character\n";
219 }
else if (arg ==
"--comment-delimiter") {
220 if (++m == argc)
return usage(1,
true);
222 }
else if (arg ==
"--version") {
223 std::cout << argv[0] <<
": GeographicLib version " 224 << GEOGRAPHICLIB_VERSION_STRING <<
"\n";
227 return usage(!(arg ==
"-h" || arg ==
"--help"), arg !=
"--help");
230 Ellipsoid3 t(e2 >= 0 ? Ellipsoid3(b, e2, k2, kp2) : Ellipsoid3(a, b, c));
231 if (!ifile.empty() && !istring.empty()) {
232 std::cerr <<
"Cannot specify --input-string and --input-file together\n";
235 if (ifile ==
"-") ifile.clear();
236 std::ifstream infile;
237 std::istringstream instring;
238 if (!ifile.empty()) {
239 infile.open(ifile.c_str());
240 if (!infile.is_open()) {
241 std::cerr <<
"Cannot open " << ifile <<
" for reading\n";
244 }
else if (!istring.empty()) {
245 std::string::size_type m = 0;
247 m = istring.find(lsep, m);
248 if (m == std::string::npos)
252 instring.str(istring);
254 std::istream* input = !ifile.empty() ? &infile :
255 (!istring.empty() ? &instring : &std::cin);
257 std::ofstream outfile;
258 if (ofile ==
"-") ofile.clear();
259 if (!ofile.empty()) {
260 outfile.open(ofile.c_str());
261 if (!outfile.is_open()) {
262 std::cerr <<
"Cannot open " << ofile <<
" for writing\n";
266 std::ostream* output = !ofile.empty() ? &outfile : &std::cout;
268 using std::round, std::log10;
269 int disprec = int(round(log10(6400000/b)));
273 std::string s, eol, sbet1, somg1, salp1, sbet2, somg2, salp2, ss12, strc;
274 std::istringstream str;
276 buffered = buffered && linecalc;
277 errors = errors && !buffered;
278 TriaxialGeodesicODE l = linecalc ?
279 TriaxialGeodesicODE(t, bet1, omg1, alp1, extended, dense, normp, eps) :
280 TriaxialGeodesicODE(t, extended, dense, normp, eps);
282 while (std::getline(*input, s)) {
285 if (!cdelim.empty()) {
286 std::string::size_type m = s.find(cdelim);
287 if (m != std::string::npos) {
288 eol =
" " + s.substr(m) +
"\n";
292 str.clear(); str.str(s);
293 if (!(linecalc ? (str >> ss12) :
294 (str >> sbet1 >> somg1 >> salp1 >> ss12)))
298 s12 = Utility::val<real>(ss12);
300 if (buffered) s12v.push_back(s12);
304 l.Reset(bet1, omg1, alp1);
307 auto errs = l.Position(s12, bet2, omg2, alp2, m12, M12, M21);
322 *output <<
" " << l.NSteps() <<
" " << l.IntSteps();
329 catch (
const std::exception& e) {
334 *output <<
"ERROR: " << e.what() <<
" " << s <<
"\n";
340 std::vector<ang> bet2v, omg2v, alp2v;
341 std::vector<real> m12v, M12v, M21v;
342 l.Position(s12v, bet2v, omg2v, alp2v, m12v, M12v, M21v);
343 for (
size_t i = 0; i < s12v.size(); ++i) {
352 *output <<
" " <<
Utility::str(s12v[i], prec + disprec);
362 catch (
const std::exception& e) {
363 std::cerr <<
"Caught exception: " << e.what() <<
"\n";
367 std::cerr <<
"Caught unknown exception\n";
static void DecodeLatLon(const std::string &stra, const std::string &strb, AngleT &lat, AngleT &lon, bool longfirst=false)
Header for GeographicLib::Utility class.
AngleT< Math::real > Angle
static T Triaxial_Earth_a()
Header for GeographicLib::Triaxial class.
static int extra_digits()
int usage(int retval, bool)
Header for GeographicLib::Math class.
static AngleT DecodeAzimuth(const std::string &azistr)
Namespace for GeographicLib.
static std::string AzimuthString(AngleT azi, int prec, bool dms=false, char dmssep='\0')
static std::string str(T x, int p=-1)
int main(int argc, const char *const argv[])
std::string ErrorString(real err, int prec)
GeographicLib::Math::real real
static int set_digits(int ndigits=0)
Exception handling for GeographicLib.
static T Triaxial_Earth_c()
static std::string LatLonString(AngleT lat, AngleT lon, int prec, bool dms=false, char dmssep='\0', bool longfirst=false)
Header for the GeographicLib::AngleT class.
static T Triaxial_Earth_b()
Header for GeographicLib::DMS class.