From 13ec408aa343ff08fb09b34d7ade2efba1667177 Mon Sep 17 00:00:00 2001 From: Robert Carlsen Date: Tue, 23 Jun 2009 09:20:00 -0400 Subject: [PATCH] Adding in PolarRideFile.cpp/h --- src/PolarRideFile.cpp | 226 ++++++++++++++++++++++++++++++++++++++++++ src/PolarRideFile.h | 29 ++++++ 2 files changed, 255 insertions(+) create mode 100644 src/PolarRideFile.cpp create mode 100644 src/PolarRideFile.h diff --git a/src/PolarRideFile.cpp b/src/PolarRideFile.cpp new file mode 100644 index 000000000..4d9aa0b7a --- /dev/null +++ b/src/PolarRideFile.cpp @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2007 Sean C. Rhea (srhea@srhea.net) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "PolarRideFile.h" +#include +#include +#include // for std::sort +#include +#include "math.h" + +#define MILES_TO_KM 1.609344 + +static int polarFileReaderRegistered = + RideFileFactory::instance().registerReader("hrm", new PolarFileReader()); + +RideFile *PolarFileReader::openRideFile(QFile &file, QStringList &errors) const +{ + QRegExp metricUnits("(km|kph|km/h)", Qt::CaseInsensitive); + QRegExp englishUnits("(miles|mph|mp/h)", Qt::CaseInsensitive); + bool metric; + + QDate date; + QString note(""); + + double version=0; + + double seconds=0; + double distance=0; + int interval = 0; + + bool speed = false; + bool cadence = false; + bool altitude = false; + bool power = false; + bool balance = false; + bool pedaling_index = false; + + + int recInterval = 1; + + if (!file.open(QFile::ReadOnly)) { + errors << ("Could not open ride file: \"" + + file.fileName() + "\""); + return NULL; + } + + int lineno = 1; + + + double next_interval=0; + QList intervals; + + QTextStream is(&file); + RideFile *rideFile = new RideFile(); + QString section = NULL; + + while (!is.atEnd()) { + // the readLine() method doesn't handle old Macintosh CR line endings + // this workaround will load the the entire file if it has CR endings + // then split and loop through each line + // otherwise, there will be nothing to split and it will read each line as expected. + QString linesIn = is.readLine(); + QStringList lines = linesIn.split('\r'); + // workaround for empty lines + if(lines.size() == 0) { + lineno++; + continue; + } + for (int li = 0; li < lines.size(); ++li) { + QString line = lines[li]; + + if (line == "") { + + } + else if (line.startsWith("[")) { + //fprintf(stderr, "section : %s\n", line.toAscii().constData()); + section=line; + if (section == "[HRData]") + next_interval = intervals.at(0); + } + else if (section == "[Params]"){ + if (line.contains("Version=")) { + QString versionString = QString(line); + versionString.remove(0,8).insert(1, "."); + version = versionString.toFloat(); + rideFile->setDeviceType("Polar HRM (v"+versionString+")"); + + } else if (line.contains("SMode=")) { + line.remove(0,6); + QString smode = QString(line); + if (smode.at(0)=='1') + speed = true; + if (smode.length()>0 && smode.at(1)=='1') + cadence = true; + if (smode.length()>1 && smode.at(2)=='1') + altitude = true; + if (smode.length()>2 && smode.at(3)=='1') + power = true; + if (smode.length()>3 && smode.at(4)=='1') + balance = true; + if (smode.length()>4 && smode.at(5)=='1') + pedaling_index = true; + + if (smode.length()>6 && smode.at(7)=='1') + metric = true; + + } else if (line.contains("Interval=")) { + recInterval = line.remove(0,9).toInt(); + rideFile->setRecIntSecs(recInterval); + } else if (line.contains("Date=")) { + line.remove(0,5); + date= QDate(line.left(4).toInt(), + line.mid(4,2).toInt(), + line.mid(6,2).toInt()); + } else if (line.contains("StartTime=")) { + line.remove(0,10); + QDateTime datetime(date, + QTime(line.left(2).toInt(), + line.mid(3,2).toInt(), + line.mid(6,2).toInt())); + rideFile->setStartTime(datetime); + } + + + } + else if (section == "[Note]"){ + note.append(line); + } + else if (section == "[IntTimes]"){ + double int_seconds = line.left(2).toInt()*60*60+line.mid(3,2).toInt()*60+line.mid(6,3).toFloat(); + intervals.append(int_seconds); + + if (lines.size()==1) { + is.readLine(); + is.readLine(); + if (version>1.05) { + is.readLine(); + is.readLine(); + } + } else { + li+=2; + if (version>1.05) + li+=2; + } + } + else if (section == "[HRData]"){ + double nm=0,kph=0,watts=0,km=0,cad=0,hr=0; + + seconds += recInterval; + + int i=0; + hr = line.section('\t', i, i).toDouble(); + i++; + + if (speed) { + kph = line.section('\t', i, i).toDouble()/10; + + i++; + } + if (cadence) { + cad = line.section('\t', i, i).toDouble(); + i++; + } + if (altitude) { + i++; + } + if (power) { + watts = line.section('\t', i, i).toDouble(); + } + + distance = distance + kph/60/60*recInterval; + km = distance; + + if (!metric) { + km *= MILES_TO_KM; + kph *= MILES_TO_KM; + } + + if (next_interval < seconds) { + interval = intervals.indexOf(next_interval); + if (intervals.count()>interval+1){ + interval++; + next_interval = intervals.at(interval); + } + } + rideFile->appendPoint(seconds, cad, hr, km, kph, nm, watts, interval); + //fprintf(stderr, " %f, %f, %f, %f, %f, %f, %f, %d\n", seconds, cad, hr, km, kph, nm, watts, interval); + } + + ++lineno; + } + } + + QRegExp rideTime("^.*/(\\d\\d\\d\\d)_(\\d\\d)_(\\d\\d)_" + "(\\d\\d)_(\\d\\d)_(\\d\\d)\\.hrm$"); + if (rideTime.indexIn(file.fileName()) >= 0) { + QDateTime datetime(QDate(rideTime.cap(1).toInt(), + rideTime.cap(2).toInt(), + rideTime.cap(3).toInt()), + QTime(rideTime.cap(4).toInt(), + rideTime.cap(5).toInt(), + rideTime.cap(6).toInt())); + + + rideFile->setStartTime(datetime); + } + file.close(); + + return rideFile; +} + diff --git a/src/PolarRideFile.h b/src/PolarRideFile.h new file mode 100644 index 000000000..41a700276 --- /dev/null +++ b/src/PolarRideFile.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2007 Sean C. Rhea (srhea@srhea.net) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _PolarRideFile_h +#define _PolarRideFile_h + +#include "RideFile.h" + +struct PolarFileReader : public RideFileReader { + virtual RideFile *openRideFile(QFile &file, QStringList &errors) const; +}; + +#endif // _PolarRideFile_h +