This repository has been archived by the owner on Feb 13, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGPXmerge.cpp
155 lines (136 loc) · 4.86 KB
/
GPXmerge.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// GPXmerge.cpp
/*
The MIT License (MIT)
Copyright (c) 2013 Wiredprairie.us
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "stdafx.h"
#include "pugixml.hpp"
#include <iostream>
#include <string>
#include "dirent.h"
#include "helpers.h"
#include "boost/algorithm/string.hpp"
#include <vector>
#include <memory>
#include <map>
using namespace pugi;
using namespace std;
#ifdef _WIN32
const std::string os_folder_separator("\\");
#elif
const std::string os_folder_separator("/");
#endif
typedef shared_ptr<xml_document> xml_document_ptr;
int _tmain(int argc, _TCHAR* argv[])
{
vector<xml_document_ptr> gpxDocs;
map<string, xml_node> trkseg_map;
DIR *pDir;
dirent *pEnt;
xml_document_ptr first_doc;
if (argc < 2) {
cout << "GPXMerge - merges GPX files into a single file." << endl ;
cout << "GPXMERGE source-path" << endl;
cout << " source-path Specifies the folder to non-recursively search." << endl;
cout << " All files with the extension .GPX are merged" << endl;
cout << " into a single GPX file named MERGED.GPX." << endl << endl;
cout << "Skips duplicate segments." << endl << endl;
return EXIT_FAILURE;
}
string start_dir(argv[1]);
auto last_char = start_dir.back();
if (last_char != os_folder_separator.at(0)) {
start_dir.append(os_folder_separator);
}
if ((pDir = opendir (start_dir.c_str())) != NULL) {
xml_document temp;
auto temp_trk_seg_nodes = temp.append_child("all_tracks");
/* print all the files and directories within directory */
while ((pEnt = readdir (pDir)) != NULL) {
string file_name(pEnt->d_name);
auto pos = file_name.rfind(".");
if (pos != 0 && pos != file_name.size() - 1) {
string ext;
ext.append(file_name.begin() + pos, file_name.end());
std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
if (hasEnding(ext, ".gpx")) {
int segments = 0;
auto doc = make_shared<xml_document>();
if (!first_doc) {
first_doc = doc;
}
file_name.insert(0, start_dir);
auto result = doc->load_file(file_name.c_str());
if (result.status == xml_parse_status::status_ok) {
gpxDocs.push_back(doc);
auto gpx = doc->child("gpx");
if (gpx) {
if (auto trk = gpx.child("trk")) {
string name(trk.child("name").value());
std::cout << name << endl;
for (auto trkseg_node = trk.child("trkseg"); trkseg_node; trkseg_node = trkseg_node.next_sibling("trkseg")) {
auto first_seg = trkseg_node.child("trkpt");
if (first_seg) {
if(auto time_node = first_seg.child("time")) {
auto time = string(time_node.first_child().value());
if (time.size() > 0) {
// if there's more than one at a time,
// it's lost (but how did that happen anyway?)
auto copy = temp_trk_seg_nodes.append_copy(trkseg_node);
trkseg_map[time] = copy;
++segments;
}
}
}
}
// remove all trksegs!
while(trk.remove_child("trkseg"));
}
}
std::cout << "Parsed " << file_name << " with " << segments << " segments." << endl;
}
}
}
}
// make sure handles are closed
closedir (pDir);
// uses the first document as a master/template for the merged file
if (first_doc) {
auto gpx = first_doc->child("gpx");
auto trk_node = gpx.child("trk");
// grab everything from the map and put it into the doc
for(auto it=trkseg_map.begin(); it != trkseg_map.end(); ++it) {
trk_node.append_copy(it->second);
}
string path("merged.gpx");
path.insert(0, start_dir);
first_doc->save_file(path.c_str());
} else {
cout << "No gpx files found." << endl;
return EXIT_FAILURE;
}
} else {
cout << "Error, could not open directory." << endl;
return EXIT_FAILURE;
}
#if DEBUG
string pause;
getline(cin, pause);
#endif
return EXIT_SUCCESS;
}