3 #include <QXmlStreamWriter>
6 #include <QtCore/qmath.h>
10 Summarized::Summarized(){
12 startTime=QDateTime::currentDateTime();
28 QString Summarized::toSumString(){
29 return QString("Summarized={numPoints: %1, startTime: %2, duration: %3, distance: %4, avgSpeed: %5, maxSpeed: %6, elevationGain: %7, elevationLoss: %8, minElevation: %9, maxElevation: %10, avgPace: %11, minPace: %12}")
30 .arg(numPoints).arg(startTime.toString(CLEAN_DATE_FORMAT)).arg(duration).arg(distance)
31 .arg(avgSpeed).arg(maxSpeed).arg(elevationGain).arg(elevationLoss).arg(minElevation).arg(maxElevation).arg(avgPace).arg(bestPace);
33 void Summarized::addSummary(Summarized summary){
35 duration+=summary.getDuration();
36 distance=distance+summary.getDistance();
37 // avgSpeed of summary is not Avg, is speed of last point!
38 if(summary.getAvgPace()!=-1)
39 avgSpeed=((avgSpeed*numPoints)+summary.getAvgSpeed())/(numPoints+1);
41 elevationGain+=summary.getElevationGain();
42 elevationLoss+=summary.getElevationLoss();
44 if(minElevation!=0 && summary.minElevation!=0){
45 minElevation=min(minElevation,summary.minElevation);
46 }else if(minElevation==0 && summary.minElevation!=0){
47 minElevation=summary.minElevation;
50 maxElevation=max(maxElevation,summary.maxElevation);
51 maxSpeed=max(maxSpeed,summary.maxSpeed);
53 if(bestPace!=0 && summary.avgPace!=0){
54 bestPace=min(bestPace,summary.avgPace);
55 }else if(bestPace==0 && summary.avgPace!=0){
56 bestPace=summary.avgPace;
59 avgPace=(1000*duration)/(60*distance);
63 Summarized& Summarized::account(GpsPoint point){
65 // this just is usefull for accounting the diference
66 // between two points. The summary MUST be new!!!
67 // data in here is not secure and not controlled.
70 startTime=point.getTime();
71 endTime=point.getTime();
72 maxSpeed=point.getSpeed();
73 avgSpeed=point.getSpeed();
74 minElevation=point.getElevation();
75 maxElevation=point.getElevation();
80 Summarized& Summarized::account(GpsPoint first, GpsPoint last){
82 // this just is usefull for accounting the diference
83 // between two points. The summary MUST be new!!!
84 // data in here is not secure and not controlled.
87 distance=first.distance(last);
88 duration=first.getTime().secsTo(last.getTime());
89 startTime=first.getTime();
90 endTime=last.getTime();
91 double lastEle=last.getElevation();
92 double firstEle=first.getElevation();
94 elevationGain=lastEle-firstEle;
96 elevationLoss=firstEle-lastEle;
98 maxSpeed=max(first.getSpeed(),last.getSpeed());
99 // keep speed of last point, will be usefull
101 avgSpeed=last.getSpeed();
102 minElevation=min(first.getElevation(),last.getElevation());
103 maxElevation=max(first.getElevation(),last.getElevation());
104 avgPace=(1000*duration)/(60*distance);
110 GpsPoint::GpsPoint(double latitude, double longitude, int elevation)
112 longitude(longitude),
113 elevation(elevation),speed(0),direction(0),magneticVariation(0),horizontalAccuracy(0),verticalAccuracy(0){
116 GpsPoint::GpsPoint(double latitude, double longitude, int elevation,QDateTime time,
117 qreal speed, qreal direction, qreal magneticVariation, qreal horizontalAccuracy, qreal verticalAccuracy)
118 :latitude(latitude),longitude(longitude),elevation(elevation),time(time),
119 speed(speed), direction(direction), magneticVariation(magneticVariation),
120 horizontalAccuracy(horizontalAccuracy),verticalAccuracy(verticalAccuracy){
124 GpsPoint::GpsPoint(double latitude, double longitude, int elevation,QDateTime time,
125 qreal speed, qreal direction, qreal magneticVariation, qreal horizontalAccuracy, qreal verticalAccuracy,
126 qreal distancePrev, QTime timeToPrev)
127 :latitude(latitude),longitude(longitude),elevation(elevation),time(time),
128 speed(speed), direction(direction), magneticVariation(magneticVariation),
129 horizontalAccuracy(horizontalAccuracy),verticalAccuracy(verticalAccuracy),distancePrev(distancePrev), timeToPrev(timeToPrev){
133 QString GpsPoint::toString(){
134 QString point = QString("GpsPoint{latitude: %1, longitude: %2, elevation: %3, time: %4, speed: %5, direction: %6, magneticVariation: %7, horizontalAccuracy: %8, verticalAccuracy: %9:, distancePrev: %10}")
135 .arg(latitude).arg(longitude).arg(elevation).arg(time.toString("dd-MM-yyyy hh:mm:ss")).arg(speed).arg(direction).arg(magneticVariation)
136 .arg(horizontalAccuracy).arg(verticalAccuracy).arg(QString::number(distancePrev,'f',10));
140 GpsPoint& GpsPoint::operator= (const GpsPoint &p){
144 longitude=p.longitude;
145 elevation=p.elevation;
147 direction=p.direction;
148 magneticVariation=p.magneticVariation;
150 distancePrev=p.distancePrev;
151 timeToPrev=p.timeToPrev;
152 horizontalAccuracy=p.horizontalAccuracy;
153 verticalAccuracy=p.verticalAccuracy;
160 double GpsPoint::distance(GpsPoint p){
162 double latitude1 = toRad(latitude);
163 double longitude1 = toRad(longitude);
165 double latitude2 = toRad(p.latitude);
166 double longitude2 = toRad(p.longitude);
168 double temp = sin(latitude1)*sin(latitude2)+cos(latitude1)*cos(latitude2)*cos(longitude2-longitude1);
170 double dist= acos(temp)*EARTH_RADIUS*1000;
171 //qDebug() << "distance between points: " << QString::number(dist,'f',10);
175 int operator== (const GpsPoint& a, const GpsPoint& b)
177 if (a.latitude==b.latitude&&a.longitude==b.longitude&&a.elevation==b.elevation&&a.speed==b.speed
178 &&a.direction==b.direction &&a.magneticVariation==b.magneticVariation&&a.time==b.time
179 &&a.horizontalAccuracy==b.horizontalAccuracy&&a.verticalAccuracy==b.verticalAccuracy
180 &&a.distancePrev==b.distancePrev&&a.timeToPrev==b.timeToPrev)
186 int operator!= (const GpsPoint& a, const GpsPoint& b)
188 if (a.latitude!=b.latitude||a.longitude!=b.longitude||a.elevation!=b.elevation||a.speed!=b.speed
189 ||a.direction!=b.direction || a.magneticVariation!=b.magneticVariation||a.time!=b.time
190 ||a.horizontalAccuracy!=b.horizontalAccuracy||a.verticalAccuracy!=b.verticalAccuracy
191 ||a.distancePrev!=b.distancePrev||a.timeToPrev!=b.timeToPrev)
206 for (int i = 0; i < points.size(); ++i) {
212 Summarized* Lap::addPoint(GpsPoint *point){
213 //qDebug() <<"--- Lap::addPoint ---";
214 Summarized *summary = new Summarized();
216 GpsPoint* last = points.last();
217 point->setDistancePrev(point->distance(*last));
218 //qDebug() << "DistancePrev:" << QString::number(point->getDistancePrev(),'f',10);
219 summary->account(*last,*point);
221 //qDebug() << "First lap point!";
222 summary->account(*point);
224 addSummary(*summary);
225 //qDebug() << "Track summary:" << toSumString();
227 points.append(point);
231 QString Lap::toString(){
232 QString lap = QString("Lap={number:").append(QString::number(number)).append(", numPoints:").append(QString::number(numPoints));
234 QListIterator<GpsPoint*> i(points);
235 while (i.hasNext()) {
236 GpsPoint* p = i.next();
237 lap.append(QString(", %1").arg(p->toString()));
239 lap.append(QString("}"));
243 Activity::Activity(QString sport)
245 id=QDateTime::currentDateTime();
250 Activity::~Activity(){
251 for (int i = 0; i < laps.size(); ++i) {
256 QString Activity::toString(){
257 QString activity = QString("Activity={sport:%1, id:%2, numLaps:%3").arg(sport).arg(id.toString(CLEAN_DATE_FORMAT)).arg(numLaps);
259 QListIterator<Lap*> i(laps);
262 activity.append(QString(", %1").arg(l->toString()));
264 activity.append(QString("}"));
268 void Activity::addLap(){
270 Lap* newLap = new Lap(numLaps);
274 Summarized* Activity::addPoint(GpsPoint* point){
276 //qDebug() <<"--- Activity::addPoint ---";
277 Lap* lastLap = laps.last();
278 Summarized* summary = lastLap->addPoint(point);
279 addSummary(*summary);
280 //qDebug() << "Track summary:" << toSumString();
287 Track::Track(QString file,QString nameTrack)
288 :fileName(file),name(nameTrack){
290 addActivity(nameTrack);
294 :fileName("noname"),name("noname"){
300 for (int i = 0; i < activities.size(); ++i) {
301 delete activities.at(i);
305 void Track::addLap(){
307 if(activities.size()>0){
308 Activity* activity = activities.last();
314 void Track::addActivity(QString sport){
317 Activity* activity = new Activity(sport);
318 activities.append(activity);
322 Summarized* Track::addPoint(GpsPoint* point){
324 //qDebug() <<"--- Track::addPoint ---";
325 //qDebug() << "Adding point: " << point->toString();
327 Activity* actualActivity = activities.last();
328 Summarized* summary = actualActivity->addPoint(point);
329 addSummary(*summary);
330 //qDebug() << "Track summary:" << toSumString();
335 QString Track::toString(){
337 QString track = QString("Track={fileName:%2, numActivities:%3").arg(fileName).arg(numActivities);
339 QListIterator<Activity*> i(activities);
341 Activity* a = i.next();
342 track.append(QString(", %1").arg(a->toString()));
344 track.append(QString("}"));
348 QList<GpsPoint*> Track::getGpsPoints(){
350 QList<GpsPoint*> points=QList<GpsPoint*>();
355 QListIterator<Activity*> iAct(activities);
356 while (iAct.hasNext()) {
357 Activity* act = iAct.next();
359 QListIterator<Lap*> iLap(act->getLaps());
360 while (iLap.hasNext()) {
361 Lap* lap = iLap.next();
363 QListIterator<GpsPoint*> iPts(lap->getPoints());
364 while (iPts.hasNext()) {
365 GpsPoint* point = iPts.next();
366 points.append(point);
373 bool Track::saveToXML(){
375 XMLFileType fileType;
376 QFile file(fileName);
381 if (!file.open(QIODevice::WriteOnly|QIODevice::Truncate)) {
382 qDebug() << "Error: Cannot write file "
383 << qPrintable(fileName) << ": "
384 << qPrintable(file.errorString());
388 if(fileName.endsWith(".tcx",Qt::CaseInsensitive)){
389 fileType=XMLFile_TCX;
390 }else if(fileName.endsWith(".gpx",Qt::CaseInsensitive)){
391 fileType=XMLFile_GPX;
393 qDebug()<<"Error: XML not recognized. " << "nameFile:" << fileName;
396 QXmlStreamWriter xmlWriter(&file);
398 xmlWriter.setAutoFormatting(true);
400 xmlWriter.writeStartDocument();
402 if(fileType==XMLFile_TCX){
403 xmlWriter.writeStartElement("TrainingCenterDatabase");
404 xmlWriter.writeAttribute("xmlns", TCX_XMLNS);
405 xmlWriter.writeAttribute("xmlns:xsi", TCX_XMLNS_XSI);
406 xmlWriter.writeAttribute("xsi:schemaLocation", TCX_XSI_SCHEMALOCATION);
408 writeTCXCourses(&xmlWriter);
411 xmlWriter.writeStartElement("gpx");
412 xmlWriter.writeAttribute("version",GPX_VERSION);
413 xmlWriter.writeAttribute("creator",GPX_CREATOR);
414 xmlWriter.writeAttribute("xmlns",GPX_XMLNS);
416 writeGPXTracks(&xmlWriter);
422 //xmlWriter->writeEndElement();
423 xmlWriter.writeEndDocument();
425 qDebug() << "file closed";
427 qDebug() << "Error on close: Cannot write file "
428 << qPrintable(fileName) << ": "
429 << qPrintable(file.errorString());
435 void Track::writeGPXTracks(QXmlStreamWriter* xmlWriter){
437 QListIterator<Activity*> i(activities);
439 while (i.hasNext()) {
440 Activity* act = i.next();
441 //xmlWriter->writeStartElement("NextSport");
442 writeGPXTrack(xmlWriter, act);
443 xmlWriter->writeEndElement();
445 xmlWriter->writeEndElement();
446 xmlWriter->writeEndElement();
450 void Track::writeTCXCourses(QXmlStreamWriter* xmlWriter){
452 xmlWriter->writeStartElement("Courses");
453 //xmlWriter->writeStartElement("MultiSportSession");
455 //xmlWriter->writeTextElement("Id",startTime.toString(XML_DATE_FORMAT));
457 QListIterator<Activity*> i(activities);
459 while (i.hasNext()) {
460 Activity* act = i.next();
461 //xmlWriter->writeStartElement("NextSport");
462 writeTCXCourse(xmlWriter, act);
463 xmlWriter->writeEndElement();
465 xmlWriter->writeEndElement();
466 xmlWriter->writeEndElement();
469 void Track::writeGPXTrack(QXmlStreamWriter* xmlWriter, Activity* act){
471 xmlWriter->writeStartElement("trk");
473 xmlWriter->writeTextElement("Name",act->getSport());
475 QListIterator<Lap*> i(act->getLaps());
476 while (i.hasNext()) {
478 writeGPXTrkseg(xmlWriter, lap);
480 xmlWriter->writeEndElement();
485 void Track::writeTCXCourse(QXmlStreamWriter* xmlWriter, Activity* act){
488 xmlWriter->writeStartElement("Course");
489 //xmlWriter->writeAttribute("Sport", act->getSport());
490 xmlWriter->writeTextElement("Name",act->getSport());
492 QListIterator<Lap*> i(act->getLaps());
493 while (i.hasNext()) {
495 writeTCXLap(xmlWriter, lap);
497 xmlWriter->writeEndElement();
500 void Track::writeGPXTrkseg(QXmlStreamWriter* xmlWriter, Lap* lap){
502 xmlWriter->writeStartElement("trkseg");
504 QListIterator<GpsPoint*> i(lap->getPoints());
505 while (i.hasNext()) {
506 GpsPoint* point = i.next();
507 writeGPXPoint(xmlWriter,point);
509 xmlWriter->writeEndElement();
512 void Track::writeTCXLap(QXmlStreamWriter* xmlWriter, Lap* lap){
514 xmlWriter->writeStartElement("Lap");
515 xmlWriter->writeAttribute("StartTime", lap->getStartTime().toString(XML_DATE_FORMAT));
516 xmlWriter->writeTextElement("TotalTimeSeconds",QString::number(lap->getDuration()));
517 xmlWriter->writeTextElement("DistanceMeters",QString::number(lap->getDistance(),'f',10));
518 xmlWriter->writeTextElement("MaximumSpeed",QString::number(lap->getMaxSpeed()));
520 QListIterator<GpsPoint*> i(lap->getPoints());
521 xmlWriter->writeStartElement("Track");
522 while (i.hasNext()) {
523 GpsPoint* point = i.next();
524 writeTCXPoint(xmlWriter,point);
526 xmlWriter->writeEndElement();
527 xmlWriter->writeEndElement();
530 void Track::writeGPXPoint(QXmlStreamWriter* xmlWriter, GpsPoint* point){
532 xmlWriter->writeStartElement("trkpt");
533 xmlWriter->writeAttribute("lat",QString::number(point->getLatitude(),'f',20));
534 xmlWriter->writeAttribute("lon",QString::number(point->getLatitude(),'f',20));
537 xmlWriter->writeTextElement("ele",QString::number(point->getElevation(),'f',20));
538 xmlWriter->writeTextElement("time",point->getTime().toString(XML_DATE_FORMAT));
540 xmlWriter->writeEndElement();
543 void Track::writeTCXPoint(QXmlStreamWriter* xmlWriter, GpsPoint* point){
545 xmlWriter->writeStartElement("Trackpoint");
546 xmlWriter->writeTextElement("Time",point->getTime().toString(XML_DATE_FORMAT));
547 xmlWriter->writeStartElement("Position");
548 xmlWriter->writeTextElement("LatitudeDegrees",QString::number(point->getLatitude(),'f',20));
549 xmlWriter->writeTextElement("LongitudeDegrees",QString::number(point->getLongitude(),'f',20));
550 xmlWriter->writeEndElement();
551 xmlWriter->writeTextElement("AltitudeMeters",QString::number(point->getElevation(),'f',20));
552 xmlWriter->writeTextElement("DistanceMeters",QString::number(point->getDistancePrev(),'f',20));
553 xmlWriter->writeEndElement();