void HrPwPlot::setDataFromRide(RideItem *_rideItem) { rideItem = _rideItem; // ignore null / bad rides if (!_rideItem || !_rideItem->ride()) return; RideFile *ride = rideItem->ride(); const RideFileDataPresent *dataPresent = ride->areDataPresent(); int npoints = ride->dataPoints().size(); if (dataPresent->watts && dataPresent->hr) { wattsArray.resize(npoints); hrArray.resize(npoints); timeArray.resize(npoints); interArray.resize(npoints); arrayLength = 0; //QListIterator<RideFilePoint*> i(ride->dataPoints()); //while (i.hasNext()) { foreach (const RideFilePoint *point, ride->dataPoints()) { //RideFilePoint *point = i.next(); if (!timeArray.empty()) timeArray[arrayLength] = point->secs; if (!wattsArray.empty()) wattsArray[arrayLength] = max(0, point->watts); if (!hrArray.empty()) hrArray[arrayLength] = max(0, point->hr); if (!interArray.empty()) interArray[arrayLength] = point->interval; ++arrayLength; } delay = -1; recalc(); }
void Aerolab::setData(RideItem *_rideItem, bool new_zoom) { // HARD-CODED DATA: p1->kph double vfactor = 3.600; double m = totalMass; double small_number = 0.00001; rideItem = _rideItem; RideFile *ride = rideItem->ride(); veArray.clear(); altArray.clear(); distanceArray.clear(); timeArray.clear(); if( ride ) { const RideFileDataPresent *dataPresent = ride->areDataPresent(); //setTitle(ride->startTime().toString(GC_DATETIME_FORMAT)); if( dataPresent->watts ) { // If watts are present, then we can fill the veArray data: const RideFileDataPresent *dataPresent = ride->areDataPresent(); int npoints = ride->dataPoints().size(); double dt = ride->recIntSecs(); veArray.resize(dataPresent->watts ? npoints : 0); altArray.resize(dataPresent->alt || constantAlt ? npoints : 0); timeArray.resize(dataPresent->watts ? npoints : 0); distanceArray.resize(dataPresent->watts ? npoints : 0); // quickly erase old data veCurve->setVisible(false); altCurve->setVisible(false); // detach and re-attach the ve curve: veCurve->detach(); if (!veArray.empty()) { veCurve->attach(this); veCurve->setVisible(dataPresent->watts); } // detach and re-attach the ve curve: bool have_recorded_alt_curve = false; altCurve->detach(); if (!altArray.empty()) { have_recorded_alt_curve = true; altCurve->attach(this); altCurve->setVisible(dataPresent->alt || constantAlt ); } // Fill the virtual elevation profile with data from the ride data: double t = 0.0; double vlast = 0.0; double e = 0.0; arrayLength = 0; foreach(const RideFilePoint *p1, ride->dataPoints()) { if ( arrayLength == 0 ) e = eoffset; timeArray[arrayLength] = p1->secs / 60.0; if ( have_recorded_alt_curve ) { if ( constantAlt && arrayLength > 0) { altArray[arrayLength] = altArray[arrayLength-1]; } else { if ( constantAlt && !dataPresent->alt) altArray[arrayLength] = 0; else altArray[arrayLength] = (context->athlete->useMetricUnits ? p1->alt : p1->alt * FEET_PER_METER); } } // Unpack: double power = max(0, p1->watts); double v = p1->kph/vfactor; double headwind = v; if( dataPresent->headwind ) { headwind = p1->headwind/vfactor; } double f = 0.0; double a = 0.0; // Use km data insteed of formula for file with a stop (gap). //d += v * dt; //distanceArray[arrayLength] = d/1000; distanceArray[arrayLength] = p1->km; if( v > small_number ) { f = power/v; a = ( v*v - vlast*vlast ) / ( 2.0 * dt * v ); } else { a = ( v - vlast ) / dt; } f *= eta; // adjust for drivetrain efficiency if using a crank-based meter double s = slope( f, a, m, crr, cda, rho, headwind ); double de = s * v * dt; e += de; t += dt; veArray[arrayLength] = e; vlast = v; ++arrayLength; } } else { veCurve->setVisible(false); altCurve->setVisible(false); } recalc(new_zoom); adjustEoffset(); } else {
void GenerateHeatMapDialog::generateNow() { double minLat = 999; double maxLat = -999; double minLon = 999; double maxLon = -999; QHash<QString, int> hash; // loop through the table and export all selected for(int i=0; i<files->invisibleRootItem()->childCount(); i++) { // give user a chance to abort.. QApplication::processEvents(); // did they? if (aborted == true) return; // user aborted! QTreeWidgetItem *current = files->invisibleRootItem()->child(i); // is it selected if (static_cast<QCheckBox*>(files->itemWidget(current,0))->isChecked()) { files->setCurrentItem(current); QApplication::processEvents(); // this one then current->setText(4, tr("Reading...")); QApplication::processEvents(); // open it.. QStringList errors; QList<RideFile*> rides; QFile thisfile(QString(context->athlete->home->activities().absolutePath()+"/"+current->text(1))); RideFile *ride = RideFileFactory::instance().openRideFile(context, thisfile, errors, &rides); // open success? if (ride) { current->setText(4, tr("Writing...")); QApplication::processEvents(); if (ride->areDataPresent()->lat == true && ride->areDataPresent()->lon == true) { int lastDistance = 0; foreach(const RideFilePoint *point, ride->dataPoints()) { if (lastDistance < (int) (point->km * 1000) && (point->lon!=0 || point->lat!=0)) { // Pick up a point max every 15m lastDistance = (int) (point->km * 1000) + 15; //outhtml << " new google.maps.LatLng("<<point->lat<<", "<<point->lon<<"),\n"; QString lonlat = QString("%1,%2").arg(floorf(point->lat*100000)/100000).arg(floorf(point->lon*100000)/100000); if (hash.contains(lonlat)) { hash[lonlat] = hash[lonlat] + 1; } else { hash[lonlat] = 1; } if (minLon > point->lon) minLon = point->lon; if (minLat > point->lat) minLat = point->lat; if (maxLon < point->lon) maxLon = point->lon; if (maxLat < point->lat) maxLat = point->lat; } } } delete ride; // free memory! // open failed } else {
void PowerHist::setData(RideItem *_rideItem, bool force) { // predefined deltas for each series static const double wattsDelta = 1.0; static const double wattsKgDelta = 0.01; static const double nmDelta = 0.1; static const double hrDelta = 1.0; static const double kphDelta = 0.1; static const double cadDelta = 1.0; source = Ride; // we set with this data already if (force == false && _rideItem == LASTrideItem && source == LASTsource) return; rideItem = _rideItem; if (!rideItem) return; RideFile *ride = rideItem->ride(); bool hasData = ((series == RideFile::watts || series == RideFile::wattsKg) && ride->areDataPresent()->watts) || (series == RideFile::nm && ride->areDataPresent()->nm) || (series == RideFile::kph && ride->areDataPresent()->kph) || (series == RideFile::cad && ride->areDataPresent()->cad) || (series == RideFile::aPower && ride->areDataPresent()->apower) || (series == RideFile::hr && ride->areDataPresent()->hr); if (ride && hasData) { //setTitle(ride->startTime().toString(GC_DATETIME_FORMAT)); static const int maxSize = 4096; // recording interval in minutes dt = ride->recIntSecs() / 60.0; wattsArray.resize(0); wattsZoneArray.resize(0); wattsKgArray.resize(0); aPowerArray.resize(0); nmArray.resize(0); hrArray.resize(0); hrZoneArray.resize(0); kphArray.resize(0); cadArray.resize(0); wattsSelectedArray.resize(0); wattsZoneSelectedArray.resize(0); wattsKgSelectedArray.resize(0); aPowerSelectedArray.resize(0); nmSelectedArray.resize(0); hrSelectedArray.resize(0); hrZoneSelectedArray.resize(0); kphSelectedArray.resize(0); cadSelectedArray.resize(0); // unit conversion factor for imperial units for selected parameters double torque_factor = (context->athlete->useMetricUnits ? 1.0 : 0.73756215); double speed_factor = (context->athlete->useMetricUnits ? 1.0 : 0.62137119); foreach(const RideFilePoint *p1, ride->dataPoints()) { bool selected = isSelected(p1, ride->recIntSecs()); // watts array int wattsIndex = int(floor(p1->watts / wattsDelta)); if (wattsIndex >= 0 && wattsIndex < maxSize) { if (wattsIndex >= wattsArray.size()) wattsArray.resize(wattsIndex + 1); wattsArray[wattsIndex]++; if (selected) { if (wattsIndex >= wattsSelectedArray.size()) wattsSelectedArray.resize(wattsIndex + 1); wattsSelectedArray[wattsIndex]++; } } // watts zoned array const Zones *zones = rideItem->zones; int zoneRange = zones ? zones->whichRange(ride->startTime().date()) : -1; // Only calculate zones if we have a valid range and check zeroes if (zoneRange > -1 && (withz || (!withz && p1->watts))) { wattsIndex = zones->whichZone(zoneRange, p1->watts); if (wattsIndex >= 0 && wattsIndex < maxSize) { if (wattsIndex >= wattsZoneArray.size()) wattsZoneArray.resize(wattsIndex + 1); wattsZoneArray[wattsIndex]++; if (selected) { if (wattsIndex >= wattsZoneSelectedArray.size()) wattsZoneSelectedArray.resize(wattsIndex + 1); wattsZoneSelectedArray[wattsIndex]++; } } } // aPower array int aPowerIndex = int(floor(p1->apower / wattsDelta)); if (aPowerIndex >= 0 && aPowerIndex < maxSize) { if (aPowerIndex >= aPowerArray.size()) aPowerArray.resize(aPowerIndex + 1); aPowerArray[aPowerIndex]++; if (selected) { if (aPowerIndex >= aPowerSelectedArray.size()) aPowerSelectedArray.resize(aPowerIndex + 1); aPowerSelectedArray[aPowerIndex]++; } } // wattsKg array int wattsKgIndex = int(floor(p1->watts / ride->getWeight() / wattsKgDelta)); if (wattsKgIndex >= 0 && wattsKgIndex < maxSize) { if (wattsKgIndex >= wattsKgArray.size()) wattsKgArray.resize(wattsKgIndex + 1); wattsKgArray[wattsKgIndex]++; if (selected) { if (wattsKgIndex >= wattsKgSelectedArray.size()) wattsKgSelectedArray.resize(wattsKgIndex + 1); wattsKgSelectedArray[wattsKgIndex]++; } } int nmIndex = int(floor(p1->nm * torque_factor / nmDelta)); if (nmIndex >= 0 && nmIndex < maxSize) { if (nmIndex >= nmArray.size()) nmArray.resize(nmIndex + 1); nmArray[nmIndex]++; if (selected) { if (nmIndex >= nmSelectedArray.size()) nmSelectedArray.resize(nmIndex + 1); nmSelectedArray[nmIndex]++; } } int hrIndex = int(floor(p1->hr / hrDelta)); if (hrIndex >= 0 && hrIndex < maxSize) { if (hrIndex >= hrArray.size()) hrArray.resize(hrIndex + 1); hrArray[hrIndex]++; if (selected) { if (hrIndex >= hrSelectedArray.size()) hrSelectedArray.resize(hrIndex + 1); hrSelectedArray[hrIndex]++; } } // hr zoned array int hrZoneRange = context->athlete->hrZones() ? context->athlete->hrZones()->whichRange(ride->startTime().date()) : -1; // Only calculate zones if we have a valid range if (hrZoneRange > -1 && (withz || (!withz && p1->hr))) { hrIndex = context->athlete->hrZones()->whichZone(hrZoneRange, p1->hr); if (hrIndex >= 0 && hrIndex < maxSize) { if (hrIndex >= hrZoneArray.size()) hrZoneArray.resize(hrIndex + 1); hrZoneArray[hrIndex]++; if (selected) { if (hrIndex >= hrZoneSelectedArray.size()) hrZoneSelectedArray.resize(hrIndex + 1); hrZoneSelectedArray[hrIndex]++; } } } int kphIndex = int(floor(p1->kph * speed_factor / kphDelta)); if (kphIndex >= 0 && kphIndex < maxSize) { if (kphIndex >= kphArray.size()) kphArray.resize(kphIndex + 1); kphArray[kphIndex]++; if (selected) { if (kphIndex >= kphSelectedArray.size()) kphSelectedArray.resize(kphIndex + 1); kphSelectedArray[kphIndex]++; } } int cadIndex = int(floor(p1->cad / cadDelta)); if (cadIndex >= 0 && cadIndex < maxSize) { if (cadIndex >= cadArray.size()) cadArray.resize(cadIndex + 1); cadArray[cadIndex]++; if (selected) { if (cadIndex >= cadSelectedArray.size()) cadSelectedArray.resize(cadIndex + 1); cadSelectedArray[cadIndex]++; } } } } else {