GeographicLib: GeoConvert.cpp Source File

GeographicLib 2.7

Loading...
Searching...
No Matches
GeoConvert.cpp
Go to the documentation of this file.
1/**
2 * \file GeoConvert.cpp
3 * \brief Command line utility for geographic coordinate conversions
4 *
5 * Copyright (c) Charles Karney (2008-2017) <karney@alum.mit.edu> and licensed
6 * under the MIT/X11 License. For more information, see
7 * https://geographiclib.sourceforge.io/
8 *
9 * See the <a href="GeoConvert.1.html">man page</a> for usage information.
10 **********************************************************************/
11
12#include <iostream>
13#include <string>
14#include <sstream>
15#include <fstream>
16#include <GeographicLib/GeoCoords.hpp>
17#include <GeographicLib/DMS.hpp>
18#include <GeographicLib/Utility.hpp>
19#include <GeographicLib/MGRS.hpp>
20
21#include "GeoConvert.usage"
22
23 int main(int argc, const char* const argv[]) {
24 try {
25 using namespace GeographicLib;
26 typedef Math::real real;
27 Utility::set_digits();
28 enum { GEOGRAPHIC, DMS, UTMUPS, MGRS, CONVERGENCE };
29 int outputmode = GEOGRAPHIC;
30 int prec = 0;
31 int zone = UTMUPS::MATCH;
32 bool centerp = true, longfirst = false;
33 std::string istring, ifile, ofile, cdelim;
34 char lsep = ';', dmssep = char(0);
35 bool sethemisphere = false, northp = false, abbrev = true, latch = false;
36
37 for (int m = 1; m < argc; ++m) {
38 std::string arg(argv[m]);
39 if (arg == "-g")
40 outputmode = GEOGRAPHIC;
41 else if (arg == "-d") {
42 outputmode = DMS;
43 dmssep = '\0';
44 } else if (arg == "-:") {
45 outputmode = DMS;
46 dmssep = ':';
47 } else if (arg == "-u")
48 outputmode = UTMUPS;
49 else if (arg == "-m")
50 outputmode = MGRS;
51 else if (arg == "-c")
52 outputmode = CONVERGENCE;
53 else if (arg == "-n")
54 centerp = false;
55 else if (arg == "-z") {
56 if (++m == argc) return usage(1, true);
57 std::string zonestr(argv[m]);
58 try {
59 UTMUPS::DecodeZone(zonestr, zone, northp);
60 sethemisphere = true;
61 }
62 catch (const std::exception&) {
63 std::istringstream str(zonestr);
64 char c;
65 if (!(str >> zone) || (str >> c)) {
66 std::cerr << "Zone " << zonestr
67 << " is not a number or zone+hemisphere\n";
68 return 1;
69 }
70 if (!(zone >= UTMUPS::MINZONE && zone <= UTMUPS::MAXZONE)) {
71 std::cerr << "Zone " << zone << " not in [0, 60]\n";
72 return 1;
73 }
74 sethemisphere = false;
75 }
76 latch = false;
77 } else if (arg == "-s") {
78 zone = UTMUPS::STANDARD;
79 sethemisphere = false;
80 latch = false;
81 } else if (arg == "-S") {
82 zone = UTMUPS::STANDARD;
83 sethemisphere = false;
84 latch = true;
85 } else if (arg == "-t") {
86 zone = UTMUPS::UTM;
87 sethemisphere = false;
88 latch = false;
89 } else if (arg == "-T") {
90 zone = UTMUPS::UTM;
91 sethemisphere = false;
92 latch = true;
93 } else if (arg == "-w")
94 longfirst = !longfirst;
95 else if (arg == "-p") {
96 if (++m == argc) return usage(1, true);
97 try {
98 prec = Utility::val<int>(std::string(argv[m]));
99 }
100 catch (const std::exception&) {
101 std::cerr << "Precision " << argv[m] << " is not a number\n";
102 return 1;
103 }
104 } else if (arg == "-l")
105 abbrev = false;
106 else if (arg == "-a")
107 abbrev = true;
108 else if (arg == "--input-string") {
109 if (++m == argc) return usage(1, true);
110 istring = argv[m];
111 } else if (arg == "--input-file") {
112 if (++m == argc) return usage(1, true);
113 ifile = argv[m];
114 } else if (arg == "--output-file") {
115 if (++m == argc) return usage(1, true);
116 ofile = argv[m];
117 } else if (arg == "--line-separator") {
118 if (++m == argc) return usage(1, true);
119 if (std::string(argv[m]).size() != 1) {
120 std::cerr << "Line separator must be a single character\n";
121 return 1;
122 }
123 lsep = argv[m][0];
124 } else if (arg == "--comment-delimiter") {
125 if (++m == argc) return usage(1, true);
126 cdelim = argv[m];
127 } else if (arg == "--version") {
128 std::cout << argv[0] << ": GeographicLib version "
129 << GEOGRAPHICLIB_VERSION_STRING << "\n";
130 MGRS::Check();
131 return 0;
132 } else
133 return usage(!(arg == "-h" || arg == "--help"), arg != "--help");
134 }
135
136 if (!ifile.empty() && !istring.empty()) {
137 std::cerr << "Cannot specify --input-string and --input-file together\n";
138 return 1;
139 }
140 if (ifile == "-") ifile.clear();
141 std::ifstream infile;
142 std::istringstream instring;
143 if (!ifile.empty()) {
144 infile.open(ifile.c_str());
145 if (!infile.is_open()) {
146 std::cerr << "Cannot open " << ifile << " for reading\n";
147 return 1;
148 }
149 } else if (!istring.empty()) {
150 std::string::size_type m = 0;
151 while (true) {
152 m = istring.find(lsep, m);
153 if (m == std::string::npos)
154 break;
155 istring[m] = '\n';
156 }
157 instring.str(istring);
158 }
159 std::istream* input = !ifile.empty() ? &infile :
160 (!istring.empty() ? &instring : &std::cin);
161
162 std::ofstream outfile;
163 if (ofile == "-") ofile.clear();
164 if (!ofile.empty()) {
165 outfile.open(ofile.c_str());
166 if (!outfile.is_open()) {
167 std::cerr << "Cannot open " << ofile << " for writing\n";
168 return 1;
169 }
170 }
171 std::ostream* output = !ofile.empty() ? &outfile : &std::cout;
172
173 GeoCoords p;
174 std::string s, eol;
175 std::string os;
176 int retval = 0;
177
178 while (std::getline(*input, s)) {
179 eol = "\n";
180 try {
181 if (!cdelim.empty()) {
182 std::string::size_type m = s.find(cdelim);
183 if (m != std::string::npos) {
184 eol = " " + s.substr(m) + "\n";
185 s = s.substr(0, m);
186 }
187 }
188 p.Reset(s, centerp, longfirst);
189 p.SetAltZone(zone);
190 switch (outputmode) {
191 case GEOGRAPHIC:
192 os = p.GeoRepresentation(prec, longfirst);
193 break;
194 case DMS:
195 os = p.DMSRepresentation(prec, longfirst, dmssep);
196 break;
197 case UTMUPS:
198 os = (sethemisphere
199 ? p.AltUTMUPSRepresentation(northp, prec, abbrev)
200 : p.AltUTMUPSRepresentation(prec, abbrev));
201 break;
202 case MGRS:
203 os = p.AltMGRSRepresentation(prec);
204 break;
205 case CONVERGENCE:
206 {
207 real
208 gamma = p.AltConvergence(),
209 k = p.AltScale();
210 int prec1 = std::max(-5, std::min(Math::extra_digits() + 8, prec));
211 os = Utility::str(gamma, prec1 + 5) + " "
212 + Utility::str(k, prec1 + 7);
213 }
214 }
215 if (latch &&
216 zone < UTMUPS::MINZONE && p.AltZone() >= UTMUPS::MINZONE) {
217 zone = p.AltZone();
218 northp = p.Northp();
219 sethemisphere = true;
220 latch = false;
221 }
222 }
223 catch (const std::exception& e) {
224 // Write error message to cout so output lines match input lines
225 os = std::string("ERROR: ") + e.what();
226 retval = 1;
227 }
228 *output << os << eol;
229 }
230 return retval;
231 }
232 catch (const std::exception& e) {
233 std::cerr << "Caught exception: " << e.what() << "\n";
234 return 1;
235 }
236 catch (...) {
237 std::cerr << "Caught unknown exception\n";
238 return 1;
239 }
240}
DMS.hpp
Header for GeographicLib::DMS class.
main
int main(int argc, const char *const argv[])
Definition GeoConvert.cpp:23
GeoCoords.hpp
Header for GeographicLib::GeoCoords class.
usage
int usage(int retval, bool)
Definition Geod3ODE.cpp:41
real
GeographicLib::Math::real real
Definition Geod3Solve.cpp:25
MGRS.hpp
Header for GeographicLib::MGRS class.
Utility.hpp
Header for GeographicLib::Utility class.
GeographicLib::DMS
Convert between degrees and the DMS representation.
Definition DMS.hpp:34
GeographicLib::GeoCoords
Conversion between geographic coordinates.
Definition GeoCoords.hpp:49
GeographicLib::GeoCoords::DMSRepresentation
std::string DMSRepresentation(int prec=0, bool longfirst=false, char dmssep=char(0)) const
Definition GeoCoords.cpp:67
GeographicLib::GeoCoords::AltZone
int AltZone() const
Definition GeoCoords.hpp:353
GeographicLib::GeoCoords::Reset
void Reset(const std::string &s, bool centerp=true, bool longfirst=false)
Definition GeoCoords.cpp:19
GeographicLib::GeoCoords::AltMGRSRepresentation
std::string AltMGRSRepresentation(int prec=0) const
Definition GeoCoords.cpp:84
GeographicLib::GeoCoords::GeoRepresentation
std::string GeoRepresentation(int prec=0, bool longfirst=false) const
Definition GeoCoords.cpp:61
GeographicLib::GeoCoords::SetAltZone
void SetAltZone(int zone=UTMUPS::STANDARD) const
Definition GeoCoords.hpp:335
GeographicLib::GeoCoords::Northp
bool Northp() const
Definition GeoCoords.hpp:306
GeographicLib::GeoCoords::AltConvergence
Math::real AltConvergence() const
Definition GeoCoords.hpp:368
GeographicLib::GeoCoords::AltUTMUPSRepresentation
std::string AltUTMUPSRepresentation(int prec=0, bool abbrev=true) const
Definition GeoCoords.cpp:133
GeographicLib::GeoCoords::AltScale
Math::real AltScale() const
Definition GeoCoords.hpp:373
GeographicLib::MGRS
Convert between UTM/UPS and MGRS.
Definition MGRS.hpp:68
GeographicLib::MGRS::Check
static void Check()
Definition MGRS.cpp:449
GeographicLib::Math::real
double real
Definition Math.hpp:115
GeographicLib::Math::extra_digits
static int extra_digits()
Definition Math.cpp:49
GeographicLib::UTMUPS
Convert between geographic coordinates and UTM/UPS.
Definition UTMUPS.hpp:75
GeographicLib::UTMUPS::MAXZONE
@ MAXZONE
Definition UTMUPS.hpp:162
GeographicLib::UTMUPS::MATCH
@ MATCH
Definition UTMUPS.hpp:122
GeographicLib::UTMUPS::UTM
@ UTM
Definition UTMUPS.hpp:129
GeographicLib::UTMUPS::STANDARD
@ STANDARD
Definition UTMUPS.hpp:138
GeographicLib::UTMUPS::MINZONE
@ MINZONE
Definition UTMUPS.hpp:146
GeographicLib::UTMUPS::DecodeZone
static void DecodeZone(const std::string &zonestr, int &zone, bool &northp)
Definition UTMUPS.cpp:205
GeographicLib::Utility::val
static T val(const std::string &s)
Definition Utility.hpp:225
GeographicLib::Utility::set_digits
static int set_digits(int ndigits=0)
Definition Utility.cpp:184
GeographicLib::Utility::str
static std::string str(T x, int p=-1)
Definition Utility.hpp:161
GeographicLib
Namespace for GeographicLib.
Definition Accumulator.cpp:12