gpxrm.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. #include <iostream>
  2. #include <cstring>
  3. #include <fstream>
  4. #include "XMLRawParser.h"
  5. #include "Arguments.h"
  6. const std::string version= "0.1.0";
  7. // ----------------------------------------------------------------------------
  8. namespace gpxtools
  9. {
  10. class GPXRm : public XMLParserHandler
  11. {
  12. public:
  13. // -- Constructor -----------------------------------------------------------
  14. GPXRm() :
  15. _arguments("gpxrm [OPTION].. [FILE]\nRemove waypoint, track or route from GPX-file.\n", "gpxrm v0.1", "Remove waypoint, track or route from GPX-file and display the resulting file on standard output."),
  16. _waypoint(_arguments, true, 'w', "waypoint", "NAME", "remove the waypoint with NAME", ""),
  17. _track (_arguments, true, 't', "track", "NAME", "remove the track with NAME", ""),
  18. _segment (_arguments, true, 's', "segment", "NR", "remove only segment in track with NR", ""),
  19. _route (_arguments, true, 'r', "route", "NAME", "remove the route with NAME", ""),
  20. _xmlParser(this),
  21. _inWaypoint(false),
  22. _inRoute(false),
  23. _inTrack(false),
  24. _inSegment(false),
  25. _segmentNr(0)
  26. {
  27. }
  28. // -- Deconstructor ---------------------------------------------------------
  29. virtual ~GPXRm()
  30. {
  31. }
  32. // -- Properties ------------------------------------------------------------
  33. // -- Parse arguments -------------------------------------------------------
  34. bool processArguments(int argc, char *argv[])
  35. {
  36. std::vector<std::string> filenames;
  37. if (!_arguments.parse(argc,argv, filenames))
  38. {
  39. return false;
  40. }
  41. else if (!checkArguments(filenames))
  42. {
  43. return false;
  44. }
  45. else if (filenames.empty())
  46. {
  47. return _xmlParser.parse(std::cin);
  48. }
  49. else
  50. {
  51. return parseFile(filenames.front());
  52. }
  53. }
  54. // -- Check arguments ---------------------------------------------------------
  55. bool checkArguments(const std::vector<std::string> &filenames)
  56. {
  57. if (filenames.size() > 1)
  58. {
  59. std::cerr << "Too many input files." << std::endl;
  60. return false;
  61. }
  62. if (!_segment.value().empty())
  63. {
  64. try
  65. {
  66. _segmentNr = std::stoi(_segment.value());
  67. }
  68. catch (...)
  69. {
  70. std::cerr << "Invalid segment number: " << _segment.value() << std::endl;
  71. return false;
  72. }
  73. if (_track.value().empty())
  74. {
  75. std::cerr << "Missing track filter for segment number." << std::endl;
  76. return false;
  77. }
  78. }
  79. return true;
  80. }
  81. // -- Parse a file ----------------------------------------------------------
  82. bool parseFile(const std::string &filename)
  83. {
  84. bool ok =false;
  85. std::ifstream file(filename);
  86. if (file.is_open())
  87. {
  88. ok = _xmlParser.parse(file);
  89. file.close();
  90. }
  91. else
  92. {
  93. std::cerr << "Unable to open: " << filename << std::endl;
  94. }
  95. return ok;
  96. }
  97. private:
  98. void store(const std::string &text)
  99. {
  100. if (_inWaypoint || _inRoute || _inTrack || _inSegment)
  101. {
  102. _currentText.append(text);
  103. }
  104. else
  105. {
  106. std::cout << text;
  107. }
  108. }
  109. public:
  110. // -- Callbacks -------------------------------------------------------------
  111. virtual void unhandled(const std::string &, const std::string &text)
  112. {
  113. store(text);
  114. }
  115. virtual void startElement(const std::string &path, const std::string &text, const std::string &, const Attributes &)
  116. {
  117. if (path == "/gpx/wpt")
  118. {
  119. if (!_waypoint.value().empty())
  120. {
  121. _inWaypoint = true;
  122. }
  123. _currentText.clear();
  124. _currentName.clear();
  125. _currentSegmentNr = 0;
  126. }
  127. else if (path == "/gpx/rte")
  128. {
  129. if (!_route.value().empty())
  130. {
  131. _inRoute = true;
  132. }
  133. _currentText.clear();
  134. _currentName.clear();
  135. _currentSegmentNr = 0;
  136. }
  137. else if (path == "/gpx/trk")
  138. {
  139. if (!_track.value().empty() && (_segmentNr == 0))
  140. {
  141. _inTrack = true;
  142. }
  143. _currentText.clear();
  144. _currentName.clear();
  145. _currentSegmentNr = 0;
  146. }
  147. else if (path == "/gpx/trk/trkseg")
  148. {
  149. _currentSegmentNr++;
  150. if ((_segmentNr != 0) && (_segmentNr == _currentSegmentNr))
  151. {
  152. _currentText.clear();
  153. _inSegment = true;
  154. }
  155. }
  156. store(text);
  157. }
  158. virtual void text(const std::string &path, const std::string &text)
  159. {
  160. if (path == "/gpx/wpt/name" || path == "/gpx/rte/name" || path == "/gpx/trk/name")
  161. {
  162. _currentName.append(text);
  163. }
  164. store(text);
  165. }
  166. virtual void endElement(const std::string &path, const std::string &text, const std::string &)
  167. {
  168. store(text);
  169. XMLRawParser::trim(_currentName);
  170. if (path == "/gpx/wpt")
  171. {
  172. if (_inWaypoint && (_currentName != _waypoint.value()))
  173. {
  174. std::cout << _currentText;
  175. }
  176. _inWaypoint = false;
  177. }
  178. else if (path == "/gpx/rte")
  179. {
  180. if (_inRoute && (_currentName != _route.value()))
  181. {
  182. std::cout << _currentText;
  183. }
  184. _inRoute = false;
  185. }
  186. else if (path == "/gpx/trk")
  187. {
  188. if (_inTrack && (_currentName != _track.value()))
  189. {
  190. std::cout << _currentText;
  191. }
  192. _inTrack = false;
  193. }
  194. else if (path == "/gpx/trk/trkseg")
  195. {
  196. if (_inSegment && (_currentName != _track.value()))
  197. {
  198. std::cout << _currentText;
  199. }
  200. _inSegment = false;
  201. }
  202. }
  203. private:
  204. // Members
  205. arg::Arguments _arguments;
  206. arg::Argument _waypoint;
  207. arg::Argument _track;
  208. arg::Argument _segment;
  209. arg::Argument _route;
  210. XMLRawParser _xmlParser;
  211. bool _inWaypoint;
  212. bool _inRoute;
  213. bool _inTrack;
  214. std::string _currentText;
  215. std::string _currentName;
  216. bool _inSegment;
  217. int _segmentNr;
  218. int _currentSegmentNr;
  219. };
  220. }
  221. // -- Main program ------------------------------------------------------------
  222. int main(int argc, char *argv[])
  223. {
  224. gpxtools::GPXRm gpxRm;
  225. return gpxRm.processArguments(argc, argv) ? 0 : 1;
  226. }