public PoolLengthInfo(IPoolLengthInfo p, IPoolLengthInfo q) { this.m_StartTime = p.StartTime < q.StartTime ? p.StartTime : q.StartTime; this.m_StrokeCount = p.StrokeCount + q.StrokeCount; this.m_StrokeType = p.StrokeType == q.StrokeType ? p.StrokeType : SwimStroke.Type.Mixed; this.m_TotalDistanceMeters = p.TotalDistanceMeters + q.TotalDistanceMeters; this.m_TotalTime = p.TotalTime + q.TotalTime; this.m_DistanceUnits = p.DistanceUnits; //No automatic merge - should be the same anyway }
private PoolLengthInfo(IPoolLengthInfo p) { this.m_StartTime = p.StartTime; this.m_StrokeCount = p.StrokeCount; this.m_StrokeType = p.StrokeType; this.m_TotalDistanceMeters = p.TotalDistanceMeters; this.m_TotalTime = p.TotalTime; this.m_DistanceUnits = p.DistanceUnits; }
public static IPoolLengthInfo GetPoolLength(IPoolLengthInfo p) { IPoolLengthInfo res = p; if (p.TotalDistanceMeters > 600) { //At least 920XT w fw 5.20/6.10 is imported incorrectly in ST res = new PoolLengthInfo(p); uint iByte = BitConverter.ToUInt32(BitConverter.GetBytes(p.TotalDistanceMeters), 0); if (iByte == 0x442338f6) { res.TotalDistanceMeters = 25; } else if (iByte == 0x4423345c || iByte == 0x44233f5c /*??*/) { res.TotalDistanceMeters = 50; } else if (iByte == 0x44233b85) { res.TotalDistanceMeters = 33.333f; } else if (iByte == 0x44235852) { res.TotalDistanceMeters = 150; } else if (iByte == 0x4423370a) { res.TotalDistanceMeters = 17; } else if (iByte == 0x44233a3d) { res.TotalDistanceMeters = (float)Length.Convert(33.333, Length.Units.Yard, Length.Units.Meter); } else if (iByte == 0x44233852) { res.TotalDistanceMeters = (float)Length.Convert(25, Length.Units.Yard, Length.Units.Meter); } } return(res); }
public override string GetText(object element, TreeList.Column column) { Data.TrailResult row = (element as TrailResultWrapper).Result; //Some special for Summary if (row is SummaryTrailResult) { switch (column.Id) { case TrailResultColumnIds.AveragePowerBalance: case TrailResultColumnIds.AverageTemperature: case TrailResultColumnIds.AverageGroundContactTime: case TrailResultColumnIds.AverageVerticalOscillation: case TrailResultColumnIds.AverageSaturatedHemoglobin: case TrailResultColumnIds.AverageTotalHemoglobinConcentration: //No implementation, ignore return(null); default: if (!Controller.TrailController.Instance.ExplicitSelection && TrailResultColumnIds.ClimbFields.Contains(column.Id) && !row.ClimbCalculated) { //Potentially many selections (of Ascent etc), no value set return(null); } break; } if (TrailsPlugin.Data.Settings.ResultSummaryStdDev) { SummaryTrailResult row2 = row as SummaryTrailResult; if (!row2.IsTotal && row2.Results.Count > 1) { switch (column.Id) { case TrailResultColumnIds.StartTime: //Not interesting to average time when only one activity. Other multi may be interesting. if (row2.Activities.Count <= 1) { return(null); } //Only time of day, averaged return(row.StartTime.ToLocalTime().ToString("T")); case TrailResultColumnIds.Duration: { SummaryValue <TimeSpan> a = row2.DurationStdDev(); return(UnitUtil.Time.ToString(a.Value, "") + " σ" + UnitUtil.Time.ToString(a.StdDev, "")); } case TrailResultColumnIds.Distance: { SummaryValue <double> a = row2.DistanceStdDev(); string d; if (row.PoolLengthInfo != null) { d = UnitUtil.Distance.ToString(a.Value, row.PoolLengthInfo.DistanceUnits, "F0"); } else { d = UnitUtil.Distance.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, ""); } return(d + " σ" + UnitUtil.Elevation.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, "")); } case TrailResultColumnIds.AvgPace: { SummaryValue <double> a = row2.AvgPaceStdDev(); return(UnitUtil.Pace.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "") + " σ" + UnitUtil.Pace.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, "")); } case TrailResultColumnIds.AvgSpeed: { SummaryValue <double> a = row2.AvgSpeedStdDev(); return(UnitUtil.Speed.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "") + " σ" + UnitUtil.Speed.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, "")); } case TrailResultColumnIds.AvgSpeedPace: { SummaryValue <double> a; if (UnitUtil.PaceOrSpeed.IsPace(Controller.TrailController.Instance.ReferenceActivity)) { a = row2.AvgPaceStdDev(); return(UnitUtil.Pace.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "") + " σ" + UnitUtil.Pace.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, "")); } else { a = row2.AvgSpeedStdDev(); return(UnitUtil.Speed.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "") + " σ" + UnitUtil.Speed.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, "")); } } //case TrailResultColumnIds.GradeRunAdjustedTime: // { // SummaryValue<double> a = row2.GradeRunAdjustedTimeStdDev(); // return UnitUtil.Time.ToString(a.Value, "") + " σ" + UnitUtil.Time.ToString(a.StdDev, ""); // } //case TrailResultColumnIds.GradeRunAdjustedPace: // { // SummaryValue<TimeSpan> a = row2.GradeRunAdjustedPaceStdDev(); // return UnitUtil.Pace.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "") + " σ" + UnitUtil.Pace.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, ""); // } //case TrailResultColumnIds.Diff: // { // SummaryValue<double> a = row2.DiffStdDev(); // return UnitUtil.Elevation.ToString(a.Value, Controller.TrailController.Instance.ReferenceActivity, "") + " σ" + UnitUtil.Elevation.ToString(a.StdDev, Controller.TrailController.Instance.ReferenceActivity, ""); // } default: break; } } } } if (row is PausedChildTrailResult) { switch (column.Id) { //Some paused fields should not be visible case TrailResultColumnIds.Order: return(null); default: break; } } if (row is SubChildTrailResult) { switch (column.Id) { //Ignore wildly inaccurate data, few points for Pool swimming, can be lower than Avg //(not always good on lap level too) case TrailResultColumnIds.FastestSpeed: case TrailResultColumnIds.FastestPace: return(null); default: break; } } switch (column.Id) { case TrailResultColumnIds.ResultColor: return(null); //String output without formatting case TrailResultColumnIds.Order: case TrailResultColumnIds.Name: case TrailResultColumnIds.TrailName: return(base.GetText(row, column)); case TrailResultColumnIds.StartTime: if (row.Activity == null) { return(null); } string date = ""; if (m_multiple) { date = row.StartTime.ToLocalTime().ToShortDateString() + " "; } return(date + row.StartTime.ToLocalTime().ToString("T")); case TrailResultColumnIds.StartDistance: if (row.PoolLengthInfo != null) { return(UnitUtil.Distance.ToString(row.StartDistance, row.PoolLengthInfo.DistanceUnits, "F0u")); } else { return(UnitUtil.Distance.ToString(row.StartDistance, Controller.TrailController.Instance.ReferenceActivity, "")); } case TrailResultColumnIds.EndTime: if (row.Activity == null) { return(null); } return(row.EndTime.ToLocalTime().ToString("T")); case TrailResultColumnIds.Duration: return(UnitUtil.Time.ToString(row.Duration, "")); case TrailResultColumnIds.Distance: if (row.PoolLengthInfo != null) { return(UnitUtil.Distance.ToString(row.Distance, row.PoolLengthInfo.DistanceUnits, "F0u")); } else { return(UnitUtil.Distance.ToString(row.Distance, Controller.TrailController.Instance.ReferenceActivity, "")); } case TrailResultColumnIds.AvgCadence: return(UnitUtil.Cadence.ToString(row.AvgCadence)); case TrailResultColumnIds.AvgHR: return(UnitUtil.HeartRate.ToString(row.AvgHR)); case TrailResultColumnIds.MaxHR: return(UnitUtil.HeartRate.ToString(row.MaxHR)); case TrailResultColumnIds.Ascent: return(UnitUtil.Elevation.ToString(row.Ascent)); case TrailResultColumnIds.Descent: return(UnitUtil.Elevation.ToString(row.Descent)); case TrailResultColumnIds.ElevChg: return((row.ElevChg > 0 ? "+" : "") + UnitUtil.Elevation.ToString(row.ElevChg, "")); case TrailResultColumnIds.AvgPower: return(UnitUtil.Power.ToString(row.AvgPower)); case TrailResultColumnIds.AscAvgGrade: return((row.AscAvgGrade).ToString("0.0%")); case TrailResultColumnIds.AscMaxAvgGrade: return((row.AscMaxAvgGrade).ToString("0.0%")); case TrailResultColumnIds.DescAvgGrade: return((row.DescAvgGrade).ToString("0.0%")); case TrailResultColumnIds.AvgSpeed: return(UnitUtil.Speed.ToString(row.AvgSpeed, Controller.TrailController.Instance.ReferenceActivity, "")); case TrailResultColumnIds.FastestSpeed: return(UnitUtil.Speed.ToString(row.FastestSpeed, Controller.TrailController.Instance.ReferenceActivity, "")); case TrailResultColumnIds.AvgPace: return(UnitUtil.Pace.ToString(row.AvgSpeed, Controller.TrailController.Instance.ReferenceActivity, "")); case TrailResultColumnIds.FastestPace: return(UnitUtil.Pace.ToString(row.FastestSpeed, Controller.TrailController.Instance.ReferenceActivity, "")); case TrailResultColumnIds.AvgSpeedPace: return(UnitUtil.PaceOrSpeed.ToString(row.AvgSpeed, Controller.TrailController.Instance.ReferenceActivity, "")); case TrailResultColumnIds.FastestSpeedPace: return(UnitUtil.PaceOrSpeed.ToString(row.FastestSpeed, Controller.TrailController.Instance.ReferenceActivity, "")); case TrailResultColumnIds.PredictDistance: return(UnitUtil.Time.ToString(row.PredictDistance, "")); case TrailResultColumnIds.IdealTime: return(UnitUtil.Time.ToString(row.IdealTime, "")); case TrailResultColumnIds.GradeRunAdjustedTime: return(UnitUtil.Time.ToString(row.GradeRunAdjustedTime, "")); case TrailResultColumnIds.GradeRunAdjustedPace: return(UnitUtil.Pace.ToString(row.GradeRunAdjustedSpeed, Controller.TrailController.Instance.ReferenceActivity, "")); case TrailResultColumnIds.Diff: return(UnitUtil.Elevation.ToString(row.Diff, "")); case TrailResultColumnIds.AscendingSpeed_VAM: return(UnitUtil.Elevation.ToString(row.AscendingSpeed_VAM, "")); case TrailResultColumnIds.AveragePowerBalance: return((row.AveragePowerBalance / 100).ToString("0.0%")); case TrailResultColumnIds.AverageTemperature: return((row.AverageTemperature).ToString("0.0")); case TrailResultColumnIds.AverageGroundContactTime: return((row.AverageGroundContactTime).ToString("0")); case TrailResultColumnIds.AverageVerticalOscillation: return((row.AverageVerticalOscillation).ToString("0.0")); case TrailResultColumnIds.AverageSaturatedHemoglobin: return((row.AverageSaturatedHemoglobin / 100).ToString("0.0%")); case TrailResultColumnIds.AverageTotalHemoglobinConcentration: return((row.AverageTotalHemoglobinConcentration).ToString("0.0")); default: if (TrailResultColumns.IsLapField(column.Id)) { ILapInfo lap = row.LapInfo; if (lap != null) { //The column Id is faked to not clash with the internal ids TreeList.Column c = new TreeList.Column(TrailResultColumns.LapId(column.Id)); return(base.GetText(lap, c)); } //Not Splits trail return(null); } else if (TrailResultColumns.IsSwimLapField(column.Id)) { IPoolLengthInfo lap = row.PoolLengthInfo; if (lap != null) { //The column Id is faked to not clash with the internal ids TreeList.Column c = new TreeList.Column(TrailResultColumns.SwimLapId(column.Id)); return(base.GetText(lap, c)); } //Not Splits trail return(null); } else if (TrailResultColumns.IsActivityField(column.Id)) { if (row is ParentTrailResult) { if (row.Activity == null) { return(null); } if (column.Id == TrailResultColumnIds.MetaData_Source) { return(row.Activity.Metadata.Source); } return(base.GetText(row.Activity, column)); } return(null); } else { if (row.Activity == null) { return(null); } ICustomDataFieldDefinition cust = TrailResultColumns.CustomDef(column.Id); if (cust != null) { if (row is ParentTrailResult) { return(row.Activity.GetCustomDataValue(TrailResultColumns.CustomDef(column.Id)).ToString()); } return(null); } } System.Diagnostics.Debug.Assert(false, string.Format("No label info for id {0}", column.Id)); return(null); } }
public static TrailResultInfo TrailResultInfoFromSplits(IActivity activity, bool onlyActiveLaps) { TrailResultInfo results = new TrailResultInfo(activity, false); if (activity == null) { //summary result return(results); } //Get around a problem with only Rest laps if (onlyActiveLaps) { onlyActiveLaps = false; for (int j = 0; j < activity.Laps.Count; j++) { if (!activity.Laps[j].Rest) { onlyActiveLaps = true; break; } } } bool lastIsRestlap = false; if (null == activity.Laps || 0 == activity.Laps.Count) { //Use MovingDistanceMetersTrack rather than ActualDistanceMetersTrack, assume similar activities have similar pauses/slow parts IDistanceDataTrack track = ActivityInfoCache.Instance.GetInfo(activity).MovingDistanceMetersTrack; if (track != null && track.Max > 0) { //Create some kind of points - could be dependent on length const float cDist = 1000; float dist = 0; while (dist < track.Max) { DateTime time = track.GetTimeAtDistanceMeters(dist); IGPSPoint p = Utils.TrackUtil.getGpsLoc(activity, time); if (p != null) { results.Points.Add(new TrailResultPoint(new TrailGPSLocation(p), time)); } else { if (activity.GPSRoute == null || activity.GPSRoute.Count == 0) { results.Points.Add(new TrailResultPoint(new TrailGPSLocation(activity.Name, true), time, track.TotalElapsedSeconds)); } else { System.Diagnostics.Debug.Assert(false, "out of GPS"); if (results.Points.Count > 0) { //end insert break; } } } dist = Math.Min(track.Max, dist + cDist); } } else { DateTime time = ActivityInfoCache.Instance.GetInfo(activity).ActualTrackStart; IGPSPoint p = Utils.TrackUtil.getGpsLoc(activity, time); if (p != null) { results.Points.Add(new TrailResultPoint(new TrailGPSLocation(p), time)); } } } else { int subresultIndex = 1; for (int j = 0; j < activity.Laps.Count; j++) { ILapInfo l = activity.Laps[j]; if (!onlyActiveLaps || !l.Rest || j > 0 && !activity.Laps[j - 1].Rest) { string name = l.Notes; if (string.IsNullOrEmpty(name)) { name = "#" + (results.Points.Count + 1); } DateTime d = l.StartTime; if (activity.GPSRoute == null || activity.GPSRoute.Count == 0) { results.Points.Add(new TrailResultPoint(new TrailGPSLocation(name, !l.Rest), d, l.TotalTime, l)); } else { IGPSPoint t = Utils.TrackUtil.getGpsLoc(activity, d); if (t != null) { results.Points.Add(new TrailResultPoint(new TrailGPSLocation(t, name, !l.Rest), d, l.TotalTime, l)); } } if (//All swim related have at least one PoolLength for each lap l.PoolLengths != null && (l.PoolLengths.Count > 0)) { TrailResultPoint tp = results.Points[results.Points.Count - 1]; foreach (IPoolLengthInfo p in l.PoolLengths) { DateTime d2 = p.StartTime; IPoolLengthInfo p1 = PoolLengthInfo.GetPoolLength(p); tp.SubPoints.Add(new TrailResultPoint(new TrailGPSLocation(null, !l.Rest), d2, p.TotalTime, p1, subresultIndex++)); } //Need (dummy) last point IPoolLengthInfo p2 = tp.SubPoints[tp.SubPoints.Count - 1].PoolLengthInfo; tp.SubPoints.Add(new TrailResultPoint(new TrailGPSLocation(null, !l.Rest), p2.StartTime + p2.TotalTime, TimeSpan.Zero, p2, subresultIndex)); } } } lastIsRestlap = activity.Laps[activity.Laps.Count - 1].Rest; } //Add end point, except if last is a rest lap (where last already is added) if (!onlyActiveLaps || !lastIsRestlap) { DateTime d = ActivityInfoCache.Instance.GetInfo(activity).ActualTrackEnd; if (activity.GPSRoute == null || activity.GPSRoute.Count == 0) { results.Points.Add(new TrailResultPoint(new TrailGPSLocation(activity.Name, !lastIsRestlap), d)); } else { IGPSPoint t = Utils.TrackUtil.getGpsLoc(activity, d); if (t != null) { results.Points.Add(new TrailResultPoint(new TrailGPSLocation(t, activity.Name, !lastIsRestlap), d)); } } } //Special for activities without any GPS info if (results.Count == 0 && activity.HasStartTime) { results.Points.Add(new TrailResultPoint(new TrailGPSLocation(activity.Name, true), activity.StartTime)); results.Points.Add(new TrailResultPoint(new TrailGPSLocation(activity.Name, true), activity.StartTime + activity.TotalTimeEntered)); } //A trail created from splits should not define elevation points foreach (TrailGPSLocation t in results.Points) { t.SetElevation(float.NaN); } return(results); }
public TrailResultPoint(TrailGPSLocation trailLocation, DateTime time, TimeSpan duration, IPoolLengthInfo lapInfo, int subresultIndex) : this(trailLocation, time, duration) { this.PoolLengthInfo = lapInfo; this.Order = subresultIndex; }