23# pragma warning (disable: 4127 5055)
26#include "MagneticField.usage"
28int main(
int argc,
const char*
const argv[]) {
32 Utility::set_digits();
33 bool verbose =
false, longfirst =
false;
35 std::string model = MagneticModel::DefaultMagneticName();
36 std::string istring, ifile, ofile, cdelim;
38 real time = 0, lat = 0, h = 0;
39 bool timeset =
false, circle =
false, rate =
false;
40 real hguard = 500000, tguard = 50;
41 int prec = 1, Nmax = -1, Mmax = -1;
43 for (
int m = 1; m < argc; ++m) {
44 std::string arg(argv[m]);
46 if (++m == argc)
return usage(1,
true);
48 }
else if (arg ==
"-d") {
49 if (++m == argc)
return usage(1,
true);
51 }
else if (arg ==
"-N") {
52 if (++m == argc)
return usage(1,
true);
54 Nmax = Utility::val<int>(std::string(argv[m]));
56 std::cerr <<
"Maximum degree " << argv[m] <<
" is negative\n";
60 catch (
const std::exception&) {
61 std::cerr <<
"Precision " << argv[m] <<
" is not a number\n";
64 }
else if (arg ==
"-M") {
65 if (++m == argc)
return usage(1,
true);
67 Mmax = Utility::val<int>(std::string(argv[m]));
69 std::cerr <<
"Maximum order " << argv[m] <<
" is negative\n";
73 catch (
const std::exception&) {
74 std::cerr <<
"Precision " << argv[m] <<
" is not a number\n";
77 }
else if (arg ==
"-t") {
78 if (++m == argc)
return usage(1,
true);
80 time = Utility::fractionalyear<real>(std::string(argv[m]));
84 catch (
const std::exception& e) {
85 std::cerr <<
"Error decoding argument of " << arg <<
": "
89 }
else if (arg ==
"-c") {
90 if (m + 3 >= argc)
return usage(1,
true);
93 time = Utility::fractionalyear<real>(std::string(argv[++m]));
95 lat = DMS::Decode(std::string(argv[++m]), ind);
96 if (ind == DMS::LONGITUDE)
98 if (!(fabs(lat) <= Math::qd))
99 throw GeographicErr(
"Latitude not in [-" + std::to_string(Math::qd)
100 +
"d, " + std::to_string(Math::qd) +
"d]");
101 h = Utility::val<real>(std::string(argv[++m]));
105 catch (
const std::exception& e) {
106 std::cerr <<
"Error decoding argument of " << arg <<
": "
110 }
else if (arg ==
"-r")
112 else if (arg ==
"-w")
113 longfirst = !longfirst;
114 else if (arg ==
"-p") {
115 if (++m == argc)
return usage(1,
true);
117 prec = Utility::val<int>(std::string(argv[m]));
119 catch (
const std::exception&) {
120 std::cerr <<
"Precision " << argv[m] <<
" is not a number\n";
123 }
else if (arg ==
"-T") {
124 if (++m == argc)
return usage(1,
true);
126 tguard = Utility::val<real>(std::string(argv[m]));
128 catch (
const std::exception& e) {
129 std::cerr <<
"Error decoding argument of " << arg <<
": "
133 }
else if (arg ==
"-H") {
134 if (++m == argc)
return usage(1,
true);
136 hguard = Utility::val<real>(std::string(argv[m]));
138 catch (
const std::exception& e) {
139 std::cerr <<
"Error decoding argument of " << arg <<
": "
143 }
else if (arg ==
"-v")
145 else if (arg ==
"--input-string") {
146 if (++m == argc)
return usage(1,
true);
148 }
else if (arg ==
"--input-file") {
149 if (++m == argc)
return usage(1,
true);
151 }
else if (arg ==
"--output-file") {
152 if (++m == argc)
return usage(1,
true);
154 }
else if (arg ==
"--line-separator") {
155 if (++m == argc)
return usage(1,
true);
156 if (std::string(argv[m]).size() != 1) {
157 std::cerr <<
"Line separator must be a single character\n";
161 }
else if (arg ==
"--comment-delimiter") {
162 if (++m == argc)
return usage(1,
true);
164 }
else if (arg ==
"--version") {
165 std::cout << argv[0] <<
": GeographicLib version "
166 << GEOGRAPHICLIB_VERSION_STRING <<
"\n";
169 int retval = usage(!(arg ==
"-h" || arg ==
"--help"), arg !=
"--help");
171 std::cout<<
"\nDefault magnetic path = \""
172 << MagneticModel::DefaultMagneticPath()
173 <<
"\"\nDefault magnetic name = \""
174 << MagneticModel::DefaultMagneticName()
180 if (!ifile.empty() && !istring.empty()) {
181 std::cerr <<
"Cannot specify --input-string and --input-file together\n";
184 if (ifile ==
"-") ifile.clear();
185 std::ifstream infile;
186 std::istringstream instring;
187 if (!ifile.empty()) {
188 infile.open(ifile.c_str());
189 if (!infile.is_open()) {
190 std::cerr <<
"Cannot open " << ifile <<
" for reading\n";
193 }
else if (!istring.empty()) {
194 std::string::size_type m = 0;
196 m = istring.find(lsep, m);
197 if (m == std::string::npos)
201 instring.str(istring);
203 std::istream* input = !ifile.empty() ? &infile :
204 (!istring.empty() ? &instring : &std::cin);
206 std::ofstream outfile;
207 if (ofile ==
"-") ofile.clear();
208 if (!ofile.empty()) {
209 outfile.open(ofile.c_str());
210 if (!outfile.is_open()) {
211 std::cerr <<
"Cannot open " << ofile <<
" for writing\n";
215 std::ostream* output = !ofile.empty() ? &outfile : &std::cout;
218 tguard = fmax(
real(0), tguard);
219 hguard = fmax(
real(0), hguard);
220 prec = std::min(10 + Math::extra_digits(), std::max(0, prec));
224 const MagneticModel m(model, dir, Geocentric::WGS84(), Nmax, Mmax);
225 if ((timeset || circle)
226 && (!isfinite(time) ||
230 " too far outside allowed range [" +
231 Utility::str(m.
MinTime()) +
"," +
232 Utility::str(m.
MaxTime()) +
"]");
238 "km too far outside allowed range [" +
239 Utility::str(m.
MinHeight()/1000) +
"km," +
240 Utility::str(m.
MaxHeight()/1000) +
"km]");
242 std::cerr <<
"Magnetic file: " << m.
MagneticFile() <<
"\n"
245 <<
"Date & Time: " << m.
DateTime() <<
"\n"
253 if ((timeset || circle) && (time < m.
MinTime() || time > m.
MaxTime()))
254 std::cerr <<
"WARNING: Time " << time
255 <<
" outside allowed range ["
258 std::cerr <<
"WARNING: Height " << h/1000
259 <<
"km outside allowed range ["
264 std::string s, eol, stra, strb;
265 std::istringstream str;
266 while (std::getline(*input, s)) {
269 if (!cdelim.empty()) {
270 std::string::size_type n = s.find(cdelim);
271 if (n != std::string::npos) {
272 eol =
" " + s.substr(n) +
"\n";
276 str.clear(); str.str(s);
277 if (!(timeset || circle)) {
280 time = Utility::fractionalyear<real>(stra);
283 " too far outside allowed range [" +
284 Utility::str(m.
MinTime()) +
"," +
288 std::cerr <<
"WARNING: Time " << time
289 <<
" outside allowed range ["
297 lon = DMS::Decode(strb, ind);
298 if (ind == DMS::LATITUDE)
301 if (!(str >> stra >> strb))
303 DMS::DecodeLatLon(stra, strb, lat, lon, longfirst);
308 "km too far outside allowed range [" +
309 Utility::str(m.
MinHeight()/1000) +
"km," +
310 Utility::str(m.
MaxHeight()/1000) +
"km]");
312 std::cerr <<
"WARNING: Height " << h/1000
313 <<
"km outside allowed range ["
322 real bx, by, bz, bxt, byt, bzt;
324 c(lon, bx, by, bz, bxt, byt, bzt);
326 m(time, lat, lon, h, bx, by, bz, bxt, byt, bzt);
327 real H, F, D, I, Ht, Ft, Dt, It;
328 MagneticModel::FieldComponents(bx, by, bz, bxt, byt, bzt,
329 H, F, D, I, Ht, Ft, Dt, It);
331 *output << DMS::Encode(D, prec + 1, DMS::NUMBER) <<
" "
332 << DMS::Encode(I, prec + 1, DMS::NUMBER) <<
" "
333 << Utility::str(H, prec) <<
" "
334 << Utility::str(by, prec) <<
" "
335 << Utility::str(bx, prec) <<
" "
336 << Utility::str(-bz, prec) <<
" "
337 << Utility::str(F, prec) << eol;
339 *output << DMS::Encode(Dt, prec + 1, DMS::NUMBER) <<
" "
340 << DMS::Encode(It, prec + 1, DMS::NUMBER) <<
" "
341 << Utility::str(Ht, prec) <<
" "
342 << Utility::str(byt, prec) <<
" "
343 << Utility::str(bxt, prec) <<
" "
344 << Utility::str(-bzt, prec) <<
" "
345 << Utility::str(Ft, prec) << eol;
347 catch (
const std::exception& e) {
348 *output <<
"ERROR: " << e.what() <<
"\n";
353 catch (
const std::exception& e) {
354 std::cerr <<
"Error reading " << model <<
": " << e.what() <<
"\n";
359 catch (
const std::exception& e) {
360 std::cerr <<
"Caught exception: " << e.what() <<
"\n";
364 std::cerr <<
"Caught unknown exception\n";
Header for GeographicLib::DMS class.
GeographicLib::Math::real real
Header for GeographicLib::MagneticCircle class.
int main(int argc, const char *const argv[])
Header for GeographicLib::MagneticModel class.
Header for GeographicLib::Utility class.
Exception handling for GeographicLib.
Geomagnetic field on a circle of latitude.
Model of the earth's magnetic field.
MagneticCircle Circle(real t, real lat, real h) const
Math::real MinTime() const
const std::string & Description() const
const std::string & MagneticFile() const
Math::real MaxTime() const
Math::real MaxHeight() const
const std::string & DateTime() const
const std::string & MagneticModelName() const
Math::real MinHeight() const
Namespace for GeographicLib.