~ubuntu-branches/ubuntu/hardy/qgis/hardy

« back to all changes in this revision

Viewing changes to src/providers/gpx/gpsdata.cpp

  • Committer: Bazaar Package Importer
  • Author(s): William Grant
  • Date: 2007-05-06 13:42:32 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070506134232-pyli6t388w5asd8x
Tags: 0.8.0-3ubuntu1
* Merge from Debian unstable. Remaining Ubuntu changes:
  - debian/rules, debian/qgis.install, debian/qgis.dirs debian/qgis.desktop:
    Add and install .desktop.
* debian/qgis.desktop: Remove Applications category; it's not real.
* Modify Maintainer value to match Debian-Maintainer-Field Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
      gpsdata.cpp  -  Data structures for GPS data
 
3
                             -------------------
 
4
    begin                : 2004-04-14
 
5
    copyright            : (C) 2004 by Lars Luthman
 
6
    email                : larsl@users.sourceforge.net
 
7
 ***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
 *                                                                         *
 
11
 *   This program is free software; you can redistribute it and/or modify  *
 
12
 *   it under the terms of the GNU General Public License as published by  *
 
13
 *   the Free Software Foundation; either version 2 of the License, or     *
 
14
 *   (at your option) any later version.                                   *
 
15
 *                                                                         *
 
16
 ***************************************************************************/
 
17
 
 
18
#include <limits>
 
19
#include <stdexcept>
 
20
 
 
21
#include <QFile>
 
22
#include <QTextStream>
 
23
#include <QObject>
 
24
 
 
25
#include "gpsdata.h"
 
26
#include <qgslogger.h>
 
27
 
 
28
QString GPSObject::xmlify(const QString& str) {
 
29
  QString tmp = str;
 
30
  tmp.replace("&", "&amp;");
 
31
  tmp.replace("<", "&lt;");
 
32
  tmp.replace(">", "&gt;");
 
33
  tmp.replace("\"", "&quot;");
 
34
  tmp.replace("\'", "&apos;");
 
35
  return tmp;
 
36
}
 
37
 
 
38
 
 
39
void GPSObject::writeXML(QTextStream& stream) {
 
40
  if (!name.isEmpty())
 
41
    stream<<"<name>"<<xmlify(name)<<"</name>\n";
 
42
  if (!cmt.isEmpty())
 
43
    stream<<"<cmt>"<<xmlify(cmt)<<"</cmt>\n";
 
44
  if (!desc.isEmpty())
 
45
    stream<<"<desc>"<<xmlify(desc)<<"</desc>\n";
 
46
  if (!src.isEmpty())
 
47
    stream<<"<src>"<<xmlify(src)<<"</src>\n";
 
48
  if (!url.isEmpty())
 
49
    stream<<"<url>"<<xmlify(url)<<"</url>\n";
 
50
  if (!urlname.isEmpty())
 
51
    stream<<"<urlname>"<<xmlify(urlname)<<"</urlname>\n";
 
52
}
 
53
 
 
54
 
 
55
GPSPoint::GPSPoint() {
 
56
  ele = -std::numeric_limits<double>::max();
 
57
}
 
58
 
 
59
 
 
60
void GPSPoint::writeXML(QTextStream& stream) {
 
61
  GPSObject::writeXML(stream);
 
62
  if (ele != -std::numeric_limits<double>::max())
 
63
    stream<<"<ele>"<<ele<<"</ele>\n";
 
64
  if (!sym.isEmpty())
 
65
    stream<<"<sym>"<<xmlify(sym)<<"</sym>\n";
 
66
}
 
67
 
 
68
 
 
69
GPSExtended::GPSExtended()
 
70
  : xMin(std::numeric_limits<double>::max()),
 
71
    xMax(-std::numeric_limits<double>::max()),
 
72
    yMin(std::numeric_limits<double>::max()),
 
73
    yMax(-std::numeric_limits<double>::max()),
 
74
    number(std::numeric_limits<int>::max()) {
 
75
  
 
76
}
 
77
 
 
78
 
 
79
void GPSExtended::writeXML(QTextStream& stream) {
 
80
  GPSObject::writeXML(stream);
 
81
  if (number != std::numeric_limits<int>::max())
 
82
    stream<<"<number>"<<number<<"</number>\n";
 
83
}
 
84
 
 
85
 
 
86
void Waypoint::writeXML(QTextStream& stream) {
 
87
  stream<<"<wpt lat=\""<<lat<<"\" lon=\""<<lon<<"\">\n";
 
88
  GPSPoint::writeXML(stream);
 
89
  stream<<"</wpt>\n";
 
90
}
 
91
 
 
92
 
 
93
void Route::writeXML(QTextStream& stream) {
 
94
  stream<<"<rte>\n";
 
95
  GPSExtended::writeXML(stream);
 
96
  for (int i = 0; i < points.size(); ++i) {
 
97
    stream<<"<rtept lat=\""<<points[i].lat
 
98
          <<"\" lon=\""<<points[i].lon<<"\">\n";
 
99
    points[i].writeXML(stream);
 
100
    stream<<"</rtept>\n";
 
101
  }
 
102
  stream<<"</rte>\n";
 
103
}
 
104
 
 
105
 
 
106
void Track::writeXML(QTextStream& stream) {
 
107
  stream<<"<trk>\n";
 
108
  GPSExtended::writeXML(stream);
 
109
  for (int i = 0; i < segments.size(); ++i) {
 
110
    stream<<"<trkseg>\n";
 
111
    for (int j = 0; j < segments[i].points.size(); ++j) {
 
112
      stream<<"<trkpt lat=\""<<segments[i].points[j].lat
 
113
      <<"\" lon=\""<<segments[i].points[j].lon<<"\">\n";
 
114
      segments[i].points[j].writeXML(stream);
 
115
      stream<<"</trkpt>\n";
 
116
    }
 
117
    stream<<"</trkseg>\n";
 
118
  }
 
119
  stream<<"</trk>\n";
 
120
}
 
121
 
 
122
 
 
123
GPSData::GPSData() {
 
124
  xMin = std::numeric_limits<double>::max();
 
125
  xMax = -std::numeric_limits<double>::max();
 
126
  yMin = std::numeric_limits<double>::max();
 
127
  yMax = -std::numeric_limits<double>::max();
 
128
  nextWaypoint = 0;
 
129
  nextRoute = 0;
 
130
  nextTrack = 0;
 
131
}
 
132
 
 
133
 
 
134
QgsRect* GPSData::getExtent() const {
 
135
  return new QgsRect(xMin, yMin, xMax, yMax);
 
136
}
 
137
 
 
138
void GPSData::setNoDataExtent() {
 
139
  if (getNumberOfWaypoints() + getNumberOfRoutes() + getNumberOfTracks() == 0)
 
140
  {
 
141
    xMin = -1.0;
 
142
    xMax =  1.0;
 
143
    yMin = -1.0;
 
144
    yMax =  1.0;
 
145
  }
 
146
}
 
147
 
 
148
int GPSData::getNumberOfWaypoints() const {
 
149
  return waypoints.size();
 
150
}
 
151
 
 
152
 
 
153
int GPSData::getNumberOfRoutes() const {
 
154
  return routes.size();
 
155
}
 
156
 
 
157
 
 
158
int GPSData::getNumberOfTracks() const {
 
159
  return tracks.size();
 
160
}
 
161
 
 
162
 
 
163
GPSData::WaypointIterator GPSData::waypointsBegin() {
 
164
  return waypoints.begin();
 
165
}
 
166
 
 
167
 
 
168
GPSData::RouteIterator GPSData::routesBegin() {
 
169
  return routes.begin();
 
170
}
 
171
 
 
172
 
 
173
GPSData::TrackIterator GPSData::tracksBegin() {
 
174
  return tracks.begin();
 
175
}
 
176
 
 
177
 
 
178
GPSData::WaypointIterator GPSData::waypointsEnd() {
 
179
  return waypoints.end();
 
180
}
 
181
 
 
182
 
 
183
GPSData::RouteIterator GPSData::routesEnd() {
 
184
  return routes.end();
 
185
}
 
186
 
 
187
 
 
188
GPSData::TrackIterator GPSData::tracksEnd() {
 
189
  return tracks.end();
 
190
}
 
191
 
 
192
 
 
193
GPSData::WaypointIterator GPSData::addWaypoint(double lat, double lon, 
 
194
                 QString name, double ele) {
 
195
  Waypoint wpt;
 
196
  wpt.lat = lat;
 
197
  wpt.lon = lon;
 
198
  wpt.name = name;
 
199
  wpt.ele = ele;
 
200
  return addWaypoint(wpt);
 
201
}
 
202
 
 
203
 
 
204
GPSData::WaypointIterator GPSData::addWaypoint(const Waypoint& wpt) {
 
205
  xMax = xMax > wpt.lon ? xMax : wpt.lon;
 
206
  xMin = xMin < wpt.lon ? xMin : wpt.lon;
 
207
  yMax = yMax > wpt.lat ? yMax : wpt.lat;
 
208
  yMin = yMin < wpt.lat ? yMin : wpt.lat;
 
209
  WaypointIterator iter = waypoints.insert(waypoints.end(), wpt);
 
210
  iter->id = nextWaypoint++;
 
211
  return iter;
 
212
}
 
213
 
 
214
 
 
215
GPSData::RouteIterator GPSData::addRoute(QString name) {
 
216
  Route rte;
 
217
  rte.name = name;
 
218
  return addRoute(rte);
 
219
}
 
220
 
 
221
 
 
222
GPSData::RouteIterator GPSData::addRoute(const Route& rte) {
 
223
  xMax = xMax > rte.xMax ? xMax : rte.xMax;
 
224
  xMin = xMin < rte.xMin ? xMin : rte.xMin;
 
225
  yMax = yMax > rte.yMax ? yMax : rte.yMax;
 
226
  yMin = yMin < rte.yMin ? yMin : rte.yMin;
 
227
  RouteIterator iter = routes.insert(routes.end(), rte);
 
228
  iter->id = nextRoute++;
 
229
  return iter;
 
230
}
 
231
 
 
232
 
 
233
GPSData::TrackIterator GPSData::addTrack(QString name) {
 
234
  Track trk;
 
235
  trk.name = name;
 
236
  return addTrack(trk);
 
237
}
 
238
  
 
239
 
 
240
GPSData::TrackIterator GPSData::addTrack(const Track& trk) {
 
241
  xMax = xMax > trk.xMax ? xMax : trk.xMax;
 
242
  xMin = xMin < trk.xMin ? xMin : trk.xMin;
 
243
  yMax = yMax > trk.yMax ? yMax : trk.yMax;
 
244
  yMin = yMin < trk.yMin ? yMin : trk.yMin;
 
245
  TrackIterator iter = tracks.insert(tracks.end(), trk);
 
246
  iter->id = nextTrack++;
 
247
  return iter;
 
248
}
 
249
 
 
250
 
 
251
void GPSData::removeWaypoints(std::list<int> const & ids) {
 
252
  std::list<int> ids2 = ids;
 
253
  ids2.sort();
 
254
  std::list<int>::const_iterator iter = ids2.begin();
 
255
  WaypointIterator wIter;
 
256
  for (wIter = waypoints.begin(); 
 
257
       wIter != waypoints.end() && iter != ids2.end(); ) {
 
258
    WaypointIterator tmpIter = wIter;
 
259
    ++tmpIter;
 
260
    if (wIter->id == *iter) {
 
261
      waypoints.erase(wIter);
 
262
      ++iter;
 
263
    }
 
264
    wIter = tmpIter;
 
265
  }
 
266
}
 
267
  
 
268
 
 
269
void GPSData::removeRoutes(std::list<int> const & ids) {
 
270
  std::list<int> ids2 = ids;
 
271
  ids2.sort();
 
272
  std::list<int>::const_iterator iter = ids2.begin();
 
273
  RouteIterator rIter;
 
274
  for (rIter = routes.begin(); rIter != routes.end() && iter != ids2.end(); ) {
 
275
    RouteIterator tmpIter = rIter;
 
276
    ++tmpIter;
 
277
    if (rIter->id == *iter) {
 
278
      routes.erase(rIter);
 
279
      ++iter;
 
280
    }
 
281
    rIter = tmpIter;
 
282
  }  
 
283
}
 
284
  
 
285
 
 
286
void GPSData::removeTracks(std::list<int> const & ids) {
 
287
  std::list<int> ids2 = ids;
 
288
  ids2.sort();
 
289
  std::list<int>::const_iterator iter = ids2.begin();
 
290
  TrackIterator tIter;
 
291
  for (tIter = tracks.begin(); tIter != tracks.end() && iter != ids2.end(); ) {
 
292
    TrackIterator tmpIter = tIter;
 
293
    ++tmpIter;
 
294
    if (tIter->id == *iter) {
 
295
      tracks.erase(tIter);
 
296
      ++iter;
 
297
    }
 
298
    tIter = tmpIter;
 
299
  }  
 
300
}
 
301
 
 
302
 
 
303
void GPSData::writeXML(QTextStream& stream) {
 
304
  stream.setEncoding(QTextStream::UnicodeUTF8);
 
305
  stream<<"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
 
306
  <<"<gpx version=\"1.0\" creator=\"Quantum GIS\">\n";
 
307
  for (WaypointIterator wIter = waypoints.begin(); 
 
308
       wIter != waypoints.end(); ++wIter)
 
309
    wIter->writeXML(stream);
 
310
  for (RouteIterator rIter = routes.begin(); rIter != routes.end(); ++rIter)
 
311
    rIter->writeXML(stream);
 
312
  for (TrackIterator tIter = tracks.begin(); tIter != tracks.end(); ++tIter)
 
313
    tIter->writeXML(stream);
 
314
  stream<<"</gpx>\n";
 
315
  stream<<flush;
 
316
}
 
317
 
 
318
 
 
319
GPSData* GPSData::getData(const QString& filename) {
 
320
  // if the data isn't there already, try to load it
 
321
  if (dataObjects.find(filename) == dataObjects.end()) {
 
322
    QFile file(filename);
 
323
    if (!file.open(QIODevice::ReadOnly)) {
 
324
      QgsLogger::warning(QObject::tr("Couldn't open the data source: ") + filename);
 
325
      return 0;
 
326
    }
 
327
    GPSData* data = new GPSData;
 
328
    QgsLogger::debug("Loading file " + filename);
 
329
    GPXHandler handler(*data);
 
330
    bool failed = false;
 
331
    
 
332
    // SAX parsing
 
333
    XML_Parser p = XML_ParserCreate(NULL);
 
334
    XML_SetUserData(p, &handler);
 
335
    XML_SetElementHandler(p, GPXHandler::start, GPXHandler::end);
 
336
    XML_SetCharacterDataHandler(p, GPXHandler::chars);
 
337
    long int bufsize = 10*1024*1024;
 
338
    char* buffer = new char[bufsize];
 
339
    int atEnd = 0;
 
340
    while (!file.atEnd()) {
 
341
      long int readBytes = file.readBlock(buffer, bufsize);
 
342
      if (file.atEnd())
 
343
        atEnd = 1;
 
344
      if (!XML_Parse(p, buffer, readBytes, atEnd)) {
 
345
        QgsLogger::warning(QObject::tr("Parse error at line ") +
 
346
                           QString("%1").arg(XML_GetCurrentLineNumber(p)) + 
 
347
                           " : " +
 
348
                           QString(XML_ErrorString(XML_GetErrorCode(p))));
 
349
        failed = true;
 
350
        break;
 
351
      }
 
352
    }
 
353
    delete [] buffer;
 
354
    XML_ParserFree(p);
 
355
    if (failed)
 
356
      return 0;
 
357
 
 
358
    data->setNoDataExtent();
 
359
 
 
360
    dataObjects[filename] = std::pair<GPSData*, unsigned>(data, 0);
 
361
  }
 
362
  else
 
363
    QgsLogger::debug(filename + " is already loaded");
 
364
  
 
365
  // return a pointer and increase the reference count for that filename
 
366
  DataMap::iterator iter = dataObjects.find(filename);
 
367
  ++(iter->second.second);
 
368
  return (GPSData*)(iter->second.first);
 
369
}
 
370
 
 
371
 
 
372
void GPSData::releaseData(const QString& filename) {
 
373
  
 
374
  /* decrease the reference count for the filename (if it is used), and erase
 
375
     it if the reference count becomes 0 */
 
376
  DataMap::iterator iter = dataObjects.find(filename);
 
377
  if (iter != dataObjects.end()) {
 
378
    QgsLogger::debug("unrefing " + filename);
 
379
    if (--(iter->second.second) == 0) {
 
380
      QgsLogger::debug("No one's using " + filename + ", I'll erase it");
 
381
      delete iter->second.first;
 
382
      dataObjects.erase(iter);
 
383
    }
 
384
  }
 
385
}
 
386
 
 
387
 
 
388
// we have to initialize the static member
 
389
GPSData::DataMap GPSData::dataObjects;
 
390
 
 
391
 
 
392
 
 
393
 
 
394
bool GPXHandler::startElement(const XML_Char* qName, const XML_Char** attr) {
 
395
 
 
396
  if (!std::strcmp(qName, "gpx")) {
 
397
    parseModes.push(ParsingDocument);
 
398
    mData = GPSData();
 
399
  }
 
400
    
 
401
  // top level objects
 
402
  else if (!std::strcmp(qName, "wpt")) {
 
403
    parseModes.push(ParsingWaypoint);
 
404
    mWpt = Waypoint();
 
405
    for (int i = 0; attr[2*i] != NULL; ++i) {
 
406
      if (!std::strcmp(attr[2*i], "lat"))
 
407
        mWpt.lat = QString(attr[2*i+1]).toDouble();
 
408
      else if (!std::strcmp(attr[2*i], "lon"))
 
409
        mWpt.lon = QString(attr[2*i+1]).toDouble();
 
410
    }
 
411
    mObj = &mWpt;
 
412
  }
 
413
  else if (!std::strcmp(qName, "rte")) {
 
414
    parseModes.push(ParsingRoute);
 
415
    mRte = Route();
 
416
    mObj = &mRte;
 
417
  }
 
418
  else if (!std::strcmp(qName, "trk")) {
 
419
    parseModes.push(ParsingTrack);
 
420
    mTrk = Track();
 
421
    mObj = &mTrk;
 
422
  }
 
423
    
 
424
  // common properties
 
425
  else if (!std::strcmp(qName, "name")) {
 
426
    if (parseModes.top() == ParsingWaypoint ||
 
427
        parseModes.top() == ParsingRoute ||
 
428
        parseModes.top() == ParsingTrack) {
 
429
      mString = &mObj->name;
 
430
      mCharBuffer = "";
 
431
      parseModes.push(ParsingString);
 
432
    }
 
433
    else
 
434
      parseModes.push(ParsingUnknown);
 
435
  }
 
436
  else if (!std::strcmp(qName, "cmt")) {
 
437
    if (parseModes.top() == ParsingWaypoint ||
 
438
        parseModes.top() == ParsingRoute ||
 
439
        parseModes.top() == ParsingTrack) {
 
440
      mString = &mObj->cmt;
 
441
      mCharBuffer = "";
 
442
      parseModes.push(ParsingString);
 
443
    }
 
444
    else
 
445
      parseModes.push(ParsingUnknown);
 
446
  }
 
447
  else if (!std::strcmp(qName, "desc")) {
 
448
    if (parseModes.top() == ParsingWaypoint ||
 
449
        parseModes.top() == ParsingRoute ||
 
450
        parseModes.top() == ParsingTrack) {
 
451
      mString = &mObj->desc;
 
452
      mCharBuffer = "";
 
453
      parseModes.push(ParsingString);
 
454
    }
 
455
    else
 
456
      parseModes.push(ParsingUnknown);
 
457
  }
 
458
  else if (!std::strcmp(qName, "src")) {
 
459
    if (parseModes.top() == ParsingWaypoint ||
 
460
        parseModes.top() == ParsingRoute ||
 
461
        parseModes.top() == ParsingTrack) {
 
462
      mString = &mObj->src;
 
463
      mCharBuffer = "";
 
464
      parseModes.push(ParsingString);
 
465
    }
 
466
    else
 
467
      parseModes.push(ParsingUnknown);
 
468
  }
 
469
  else if (!std::strcmp(qName, "url")) {
 
470
    if (parseModes.top() == ParsingWaypoint ||
 
471
        parseModes.top() == ParsingRoute ||
 
472
        parseModes.top() == ParsingTrack) {
 
473
      mString = &mObj->url;
 
474
      mCharBuffer = "";
 
475
      parseModes.push(ParsingString);
 
476
    }
 
477
    else
 
478
      parseModes.push(ParsingUnknown);
 
479
  }
 
480
  else if (!std::strcmp(qName, "urlname")) {
 
481
    if (parseModes.top() == ParsingWaypoint ||
 
482
        parseModes.top() == ParsingRoute ||
 
483
        parseModes.top() == ParsingTrack) {
 
484
      mString = &mObj->urlname;
 
485
      mCharBuffer = "";
 
486
      parseModes.push(ParsingString);
 
487
    }
 
488
    else
 
489
      parseModes.push(ParsingUnknown);
 
490
  }
 
491
    
 
492
  // waypoint-specific attributes
 
493
  else if (!std::strcmp(qName, "ele")) {
 
494
    if (parseModes.top() == ParsingWaypoint) {
 
495
      mDouble = &mWpt.ele;
 
496
      mCharBuffer = "";
 
497
      parseModes.push(ParsingDouble);
 
498
    }
 
499
    else
 
500
      parseModes.push(ParsingUnknown);
 
501
  }
 
502
  else if (!std::strcmp(qName, "sym")) {
 
503
    if (parseModes.top() == ParsingWaypoint) {
 
504
      mString = &mWpt.sym;
 
505
      mCharBuffer = "";
 
506
      parseModes.push(ParsingString);
 
507
    }
 
508
    else
 
509
      parseModes.push(ParsingUnknown);
 
510
  }
 
511
    
 
512
  // route/track-specific attributes
 
513
  else if (!std::strcmp(qName, "number")) {
 
514
    if (parseModes.top() == ParsingRoute) {
 
515
      mInt = &mRte.number;
 
516
      mCharBuffer = "";
 
517
      parseModes.push(ParsingInt);
 
518
    }
 
519
    else if (parseModes.top() == ParsingTrack) {
 
520
      mInt = &mTrk.number;
 
521
      parseModes.push(ParsingInt);
 
522
    }
 
523
    else
 
524
      parseModes.push(ParsingUnknown);
 
525
  }    
 
526
    
 
527
  // route points
 
528
  else if (!std::strcmp(qName, "rtept")) {
 
529
    if (parseModes.top() == ParsingRoute) {
 
530
      mRtept = Routepoint();
 
531
      for (int i = 0; attr[2*i] != NULL; ++i) {
 
532
        if (!std::strcmp(attr[2*i], "lat"))
 
533
          mRtept.lat = QString(attr[2*i+1]).toDouble();
 
534
        else if (!std::strcmp(attr[2*i], "lon"))
 
535
          mRtept.lon = QString(attr[2*i+1]).toDouble();
 
536
      }
 
537
      parseModes.push(ParsingRoutepoint);
 
538
    }
 
539
    else
 
540
      parseModes.push(ParsingUnknown);
 
541
  }
 
542
    
 
543
  // track segments and points
 
544
  else if (!std::strcmp(qName, "trkseg")) {
 
545
    if (parseModes.top() == ParsingTrack) {
 
546
      mTrkseg = TrackSegment();
 
547
      parseModes.push(ParsingTrackSegment);
 
548
    }
 
549
    else
 
550
      parseModes.push(ParsingUnknown);
 
551
  }
 
552
  else if (!std::strcmp(qName, "trkpt")) {
 
553
    if (parseModes.top() == ParsingTrackSegment) {
 
554
      mTrkpt = Trackpoint();
 
555
      for (int i = 0; attr[2*i] != NULL; ++i) {
 
556
        if (!std::strcmp(attr[2*i], "lat"))
 
557
          mTrkpt.lat = QString(attr[2*i+1]).toDouble();
 
558
        else if (!std::strcmp(attr[2*i], "lon"))
 
559
          mTrkpt.lon = QString(attr[2*i+1]).toDouble();
 
560
      }
 
561
      parseModes.push(ParsingTrackpoint);
 
562
    }
 
563
    else
 
564
      parseModes.push(ParsingUnknown);
 
565
  }
 
566
    
 
567
  // unknown
 
568
  else
 
569
    parseModes.push(ParsingUnknown);
 
570
    
 
571
  return true;
 
572
}
 
573
 
 
574
 
 
575
void GPXHandler::characters(const XML_Char* chars, int len) {
 
576
  // This is horrible.
 
577
#ifdef XML_UNICODE
 
578
  for (int i = 0; i < len; ++i)
 
579
    mCharBuffer += QChar(chars[i]);
 
580
#else
 
581
  mCharBuffer += QString::fromUtf8(chars, len);
 
582
#endif
 
583
}
 
584
 
 
585
 
 
586
bool GPXHandler::endElement(const std::string& qName) {
 
587
  if (parseModes.top() == ParsingWaypoint) {
 
588
    mData.addWaypoint(mWpt);
 
589
  }
 
590
  else if (parseModes.top() == ParsingRoute) {
 
591
    mData.addRoute(mRte);
 
592
  }
 
593
  else if (parseModes.top() == ParsingTrack) {
 
594
    mData.addTrack(mTrk);
 
595
  }
 
596
  else if (parseModes.top() == ParsingRoutepoint) {
 
597
    mRte.points.push_back(mRtept);
 
598
    mRte.xMin = (mRte.xMin < mRtept.lon ? mRte.xMin : mRtept.lon);
 
599
    mRte.xMax = (mRte.xMax > mRtept.lon ? mRte.xMax : mRtept.lon);
 
600
    mRte.yMin = (mRte.yMin < mRtept.lat ? mRte.yMin : mRtept.lat);
 
601
    mRte.yMax = (mRte.yMax > mRtept.lat ? mRte.yMax : mRtept.lat);
 
602
  }
 
603
  else if (parseModes.top() == ParsingTrackSegment) {
 
604
    mTrk.segments.push_back(mTrkseg);
 
605
  }
 
606
  else if (parseModes.top() == ParsingTrackpoint) {
 
607
    mTrkseg.points.push_back(mTrkpt);
 
608
    mTrk.xMin = (mTrk.xMin < mTrkpt.lon ? mTrk.xMin : mTrkpt.lon);
 
609
    mTrk.xMax = (mTrk.xMax > mTrkpt.lon ? mTrk.xMax : mTrkpt.lon);
 
610
    mTrk.yMin = (mTrk.yMin < mTrkpt.lat ? mTrk.yMin : mTrkpt.lat);
 
611
    mTrk.yMax = (mTrk.yMax > mTrkpt.lat ? mTrk.yMax : mTrkpt.lat);
 
612
  }
 
613
  else if (parseModes.top() == ParsingDouble) {
 
614
    *mDouble = QString(mCharBuffer).toDouble();
 
615
    mCharBuffer = "";
 
616
  }
 
617
  else if (parseModes.top() == ParsingInt) {
 
618
    *mInt = QString(mCharBuffer).toInt();
 
619
    mCharBuffer = "";
 
620
  }
 
621
  else if (parseModes.top() == ParsingString) {
 
622
    *mString = mCharBuffer;
 
623
    mCharBuffer = "";
 
624
  }
 
625
  parseModes.pop();
 
626
  
 
627
  return true;
 
628
}
 
629