/******************************************************/ public static DateTime getDateTimeFromTrackDist(IDistanceDataTrack distTrack, float t) { DateTime res = DateTime.MinValue; if (t >= distTrack.Max && distTrack.Count > 0) { res = distTrack.StartTime.AddSeconds(distTrack.TotalElapsedSeconds); } else if (t <= distTrack.Min) { res = distTrack.StartTime; } else { try { res = distTrack.GetTimeAtDistanceMeters(t); } catch { } } return(res); }
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); }
private static IList <IItemTrackSelectionInfo> SetAndAdjustFromSelection (IList <IItemTrackSelectionInfo> selected, IEnumerable <IActivity> activities, bool fromST) { if (selected == null || selected.Count == 0 || activities == null) { //Do not adjust selection return(selected); } bool singleSelection = selected.Count == 0 || selected.Count == 1 && !( selected[0].MarkedDistances != null && selected[0].MarkedDistances.Count > 1 || selected[0].MarkedTimes != null && selected[0].MarkedTimes.Count > 1); IList <IItemTrackSelectionInfo> results = new List <IItemTrackSelectionInfo>(); foreach (IItemTrackSelectionInfo sel in selected) { IActivity activity = null; if (sel is TrailsItemTrackSelectionInfo) { activity = ((TrailsItemTrackSelectionInfo)sel).Activity; } else { if (activities == null) { if (UnitUtil.GetApplication() == null || UnitUtil.GetApplication().Logbook == null) { activities = new List <IActivity>(); } else { activities = UnitUtil.GetApplication().Logbook.Activities; } } foreach (IActivity a in activities) { //In ST3.0.4068 (at least) only one activity is selected if (a != null && sel.ItemReferenceId == a.ReferenceId) { activity = a; break; } } } if (activity != null) { //The distance is in unstopped/unpaused format IDistanceDataTrack activityUnpausedDistanceMetersTrack = ActivityInfoCache.Instance.GetInfo(activity).ActualDistanceMetersTrack; TrailsItemTrackSelectionInfo tmpSel = new TrailsItemTrackSelectionInfo(); tmpSel.SetFromSelection(sel, activity); if (fromST) { //Set MarkedTimes (or SelectedTime), used internally. No need to clear "unused" if (sel.MarkedDistances != null && sel.MarkedDistances.Count > 0 && (sel.MarkedTimes == null || sel.MarkedTimes.Count == 0)) { try { foreach (ValueRange <double> t in sel.MarkedDistances) { DateTime d1 = activityUnpausedDistanceMetersTrack.GetTimeAtDistanceMeters(t.Lower); DateTime d2 = activityUnpausedDistanceMetersTrack.GetTimeAtDistanceMeters(t.Upper); AddMarkedOrSelectedTime(tmpSel, singleSelection, d1, d2); } tmpSel.MarkedDistances = null; } catch { } } if (sel.SelectedTime != null && sel.MarkedTimes == null) { try { AddMarkedOrSelectedTime(tmpSel, singleSelection, sel.SelectedTime.Lower, sel.SelectedTime.Upper); //tmpSel.SelectedTime = null; } catch { } } if (sel.SelectedDistance != null && sel.MarkedTimes == null) { tmpSel.MarkedTimes = new ValueRangeSeries <DateTime>(); try { DateTime d1 = activityUnpausedDistanceMetersTrack.GetTimeAtDistanceMeters(sel.SelectedDistance.Lower); DateTime d2 = activityUnpausedDistanceMetersTrack.GetTimeAtDistanceMeters(sel.SelectedDistance.Upper); AddMarkedOrSelectedTime(tmpSel, singleSelection, d1, d2); tmpSel.SelectedDistance = null; } catch { } } } else { //To ST //The standard in the plugin(time) to standard in ST core and omb's Track Coloring (unpaused distance) if (sel.MarkedDistances == null && sel.MarkedTimes != null && sel.MarkedTimes.Count > 0) { try { tmpSel.MarkedDistances = new ValueRangeSeries <double>(); foreach (ValueRange <DateTime> t in sel.MarkedTimes) { //If real time differs with a couple of seconds, use that const int maxTimeDiff = 2; DateTime start = t.Lower; if (start < activityUnpausedDistanceMetersTrack.StartTime && start > activityUnpausedDistanceMetersTrack.StartTime - TimeSpan.FromSeconds(maxTimeDiff)) { start = activityUnpausedDistanceMetersTrack.StartTime; } DateTime end = t.Upper; if (end > activityUnpausedDistanceMetersTrack.StartTime + TimeSpan.FromSeconds(activityUnpausedDistanceMetersTrack.TotalElapsedSeconds) && end < activityUnpausedDistanceMetersTrack.StartTime + TimeSpan.FromSeconds(activityUnpausedDistanceMetersTrack.TotalElapsedSeconds - maxTimeDiff)) { end = activityUnpausedDistanceMetersTrack.StartTime + TimeSpan.FromSeconds(activityUnpausedDistanceMetersTrack.TotalElapsedSeconds); } double d1 = activityUnpausedDistanceMetersTrack.GetInterpolatedValue(start).Value; double d2 = activityUnpausedDistanceMetersTrack.GetInterpolatedValue(end).Value; AddMarkedOrSelectedDistance(tmpSel, singleSelection, d1, d2); } tmpSel.MarkedTimes = null; } catch { } } if (sel.SelectedDistance == null && sel.SelectedTime != null) { try { tmpSel.SelectedDistance = new ValueRange <double>( activityUnpausedDistanceMetersTrack.GetInterpolatedValue(sel.SelectedTime.Lower).Value, activityUnpausedDistanceMetersTrack.GetInterpolatedValue(sel.SelectedTime.Upper).Value); tmpSel.SelectedTime = null; } catch { } } } results.Add(tmpSel); } } return(results); }