GeographicLib: IntersectTool.cpp Source File (original) (raw)

26int main(int argc, const char* const argv[]) {

27 try {

28 enum { CLOSE = 0, OFFSET, NEXT, SEGMENT };

33 maxdist = -1;

34 bool exact = false, check = false, longfirst = false;

35 int prec = 3, mode = CLOSE;

36 std::string istring, ifile, ofile, cdelim;

37 char lsep = ';';

38

39 for (int m = 1; m < argc; ++m) {

40 std::string arg(argv[m]);

41 if (arg == "-e") {

42 if (m + 2 >= argc) return usage(1, true);

43 try {

44 a = Utility::val(std::string(argv[m + 1]));

45 f = Utility::fract(std::string(argv[m + 2]));

46 }

47 catch (const std::exception& e) {

48 std::cerr << "Error decoding arguments of -e: " << e.what() << "\n";

49 return 1;

50 }

51 m += 2;

52 } else if (arg == "-E")

53 exact = true;

54 else if (arg == "-p") {

55 if (++m == argc) return usage(1, true);

56 try {

57 prec = Utility::val(std::string(argv[m]));

58 }

59 catch (const std::exception&) {

60 std::cerr << "Precision " << argv[m] << " is not a number\n";

61 return 1;

62 }

63 } else if (arg == "-R") {

64 if (++m == argc) return usage(1, true);

65 try {

66 maxdist = Utility::val(std::string(argv[m]));

67 }

68 catch (const std::exception&) {

69 std::cerr << "Maxdist " << argv[m] << " is not a number\n";

70 return 1;

71 }

72 if (!(maxdist >= 0)) {

73 std::cerr << "Maxdist must be nonnegative\n";

74 return 1;

75 }

76 } else if (arg == "-c")

77 mode = CLOSE;

78 else if (arg == "-o")

79 mode = OFFSET;

80 else if (arg == "-n")

81 mode = NEXT;

82 else if (arg == "-i")

83 mode = SEGMENT;

84 else if (arg == "-C")

85 check = true;

86 else if (arg == "-w")

87 longfirst = true;

88 else if (arg == "--input-string") {

89 if (++m == argc) return usage(1, true);

90 istring = argv[m];

91 } else if (arg == "--input-file") {

92 if (++m == argc) return usage(1, true);

93 ifile = argv[m];

94 } else if (arg == "--output-file") {

95 if (++m == argc) return usage(1, true);

96 ofile = argv[m];

97 } else if (arg == "--line-separator") {

98 if (++m == argc) return usage(1, true);

99 if (std::string(argv[m]).size() != 1) {

100 std::cerr << "Line separator must be a single character\n";

101 return 1;

102 }

103 lsep = argv[m][0];

104 } else if (arg == "--comment-delimiter") {

105 if (++m == argc) return usage(1, true);

106 cdelim = argv[m];

107 } else if (arg == "--version") {

108 std::cout << argv[0] << ": GeographicLib version "

109 << GEOGRAPHICLIB_VERSION_STRING << "\n";

110 return 0;

111 } else

112 return usage(!(arg == "-h" || arg == "--help"), arg != "--help");

113 }

114

115 if (!ifile.empty() && !istring.empty()) {

116 std::cerr << "Cannot specify --input-string and --input-file together\n";

117 return 1;

118 }

119 if (ifile == "-") ifile.clear();

120 std::ifstream infile;

121 std::istringstream instring;

122 if (!ifile.empty()) {

123 infile.open(ifile.c_str());

124 if (!infile.is_open()) {

125 std::cerr << "Cannot open " << ifile << " for reading\n";

126 return 1;

127 }

128 } else if (!istring.empty()) {

129 std:🧵:size_type m = 0;

130 while (true) {

131 m = istring.find(lsep, m);

132 if (m == std:🧵:npos)

133 break;

134 istring[m] = '\n';

135 }

136 instring.str(istring);

137 }

138 std::istream* input = !ifile.empty() ? &infile :

139 (!istring.empty() ? &instring : &std::cin);

140

141 std::ofstream outfile;

142 if (ofile == "-") ofile.clear();

143 if (!ofile.empty()) {

144 outfile.open(ofile.c_str());

145 if (!outfile.is_open()) {

146 std::cerr << "Cannot open " << ofile << " for writing\n";

147 return 1;

148 }

149 }

150 std::ostream* output = !ofile.empty() ? &outfile : &std::cout;

151

154 real latX1, lonX1, aziX, latY1, lonY1, aziY, latX2, lonX2, latY2, lonY2,

155 x0 = 0, y0 = 0, x, y;

156 std::string inp[8], s, sc, eol;

157 std::istringstream str;

158 int retval = 0,

159 ninp = mode == CLOSE ? 6 : (mode == NEXT ? 4 :

160 8);

163 while (std::getline(*input, s)) {

164 try {

165 eol = "\n";

166 if (!cdelim.empty()) {

167 std:🧵:size_type m = s.find(cdelim);

168 if (m != std:🧵:npos) {

169 eol = " " + s.substr(m) + "\n";

170 s = s.substr(0, m);

171 }

172 }

173 str.clear(); str.str(s);

174 for (int i = 0; i < ninp; ++i) {

175 if (!(str >> inp[i]))

177 }

178 if (str >> sc)

180 if (mode == CLOSE || mode == OFFSET) {

185 if (mode == OFFSET) {

186 x0 = Utility::val(inp[6]);

187 y0 = Utility::val(inp[7]);

188 } else

189 x0 = y0 = 0;

190 lineX = geod.Line(latX1, lonX1, aziX, caps);

191 lineY = geod.Line(latY1, lonY1, aziY, caps);

192 } else if (mode == NEXT) {

196 lineX = geod.Line(latX1, lonX1, aziX, caps);

197 lineY = geod.Line(latX1, lonX1, aziY, caps);

198 } else {

203 lineX = geod.InverseLine(latX1, lonX1, latX2, lonX2,

205 lineY = geod.InverseLine(latY1, lonY1, latY2, lonY2,

209 }

210 std::pair<real, real> p0(x0, y0);

211 if (maxdist < 0) {

212 int segmode = 0, c;

213 auto p = mode == CLOSE || mode == OFFSET ?

214 intersect.Closest(lineX, lineY, p0, &c) :

215 mode == NEXT ? intersect.Next(lineX, lineY, &c) :

216 intersect.Segment(lineX, lineY, segmode, &c);

217 x = p.first; y = p.second;

220 if (mode == SEGMENT)

221 *output << " " << segmode;

222 *output << eol;

223 if (check) {

224 lineX.Position(x, latX2, lonX2);

225 lineY.Position(y, latY2, lonY2);

227 geod.Inverse(latX2, lonX2, latY2, lonY2, sXY);

228 std::cerr << Utility::str(longfirst ? lonX2 : latX2, prec+5) << " "

229 << Utility::str(longfirst ? latX2 : lonX2, prec+5) << " "

230 << Utility::str(longfirst ? lonY2 : latY2, prec+5) << " "

231 << Utility::str(longfirst ? latY2 : lonY2, prec+5) << " "

233 }

234 } else {

235 std::vector c;

236 auto v = intersect.All(lineX, lineY, maxdist, c, p0);

237 unsigned n = unsigned(v.size());

238 for (unsigned i = 0; i < n; ++i) {

239 x = v[i].first; y = v[i].second;

241 << " " << c[i] << " "

243 << eol;

244 if (check) {

245 lineX.Position(x, latX2, lonX2);

246 lineY.Position(y, latY2, lonY2);

248 geod.Inverse(latX2, lonX2, latY2, lonY2, sXY);

249 std::cerr << Utility::str(longfirst ? lonX2 : latX2, prec+5) << " "

250 << Utility::str(longfirst ? latX2 : lonX2, prec+5) << " "

251 << Utility::str(longfirst ? lonY2 : latY2, prec+5) << " "

252 << Utility::str(longfirst ? latY2 : lonY2, prec+5) << " "

254 }

255 }

256 *output << "nan nan 0 nan" << eol;

257 if (check)

258 std::cerr << "nan nan nan nan nan" << eol;

259 }

260 }

261 catch (const std::exception& e) {

262

263 *output << "ERROR: " << e.what() << "\n";

264 retval = 1;

265 }

266 }

267 return retval;

268 }

269 catch (const std::exception& e) {

270 std::cerr << "Caught exception: " << e.what() << "\n";

271 return 1;

272 }

273 catch (...) {

274 std::cerr << "Caught unknown exception\n";

275 return 1;

276 }

277}