Ejemplo n.º 1
0
        private ComboUsageInfo GetMostUsedGearValue(RangeInfoCacheWrapper range)
        {
            if (range.ActivityPauselessCadenceTrack.Count > 0)
            {
                ITimeDataSeries <SprocketCombo> rangeSprockets = GetRangeSprocketsTrack(range);
                IList <SprocketComboInfo>       sprocketInfo   = GetSprocketComboInfo(range, rangeSprockets);
                SprocketCombo mostUsedCombo    = null;
                TimeSpan      mostUsedDuration = new TimeSpan(0);

                foreach (SprocketComboInfo comboInfo in sprocketInfo)
                {
                    TimeSpan currentComboDuration = new TimeSpan(0);

                    foreach (IValueRange <DateTime> times in comboInfo.Times)
                    {
                        currentComboDuration += (times.Upper - times.Lower);
                    }

                    if (mostUsedCombo == null || mostUsedDuration < currentComboDuration)
                    {
                        mostUsedCombo    = comboInfo.SprocketCombo;
                        mostUsedDuration = currentComboDuration;
                    }
                }

                return(new ComboUsageInfo(mostUsedCombo, mostUsedDuration));
            }

            return(null);
        }
Ejemplo n.º 2
0
        public IList <SprocketComboInfo> CalculateSprocketComboInfo(IActivity activity)
        {
            if (activity != null)
            {
                bool retrieveInfo = true;
                SprocketComboInfoCacheItem cachedItem = null;

                if (m_InfoCache.ContainsKey(activity) && !m_InfoCache[activity].m_Dirty)
                {
                    retrieveInfo = false;
                }

                if (retrieveInfo)
                {
                    ITimeDataSeries <SprocketCombo> sprocketTrack = ActivityGearTrackCache.Instance.CalculateSprocketTrack(activity);
                    IList <SprocketComboInfo>       sprocketInfo  = Common.Data.Calculate(activity, sprocketTrack);

                    UpdateCachedInfo(activity, sprocketInfo);
                }

                cachedItem = m_InfoCache[activity];

                return(cachedItem.m_ComboInfo);
            }

            return(null);
        }
Ejemplo n.º 3
0
        public ITimeDataSeries <SprocketCombo> CalculateSprocketTrack(IActivity activity)
        {
            if (activity != null)
            {
                bool retrieveInfo = true;
                ActivityGearTrackCacheItem cachedItem = null;

                if (m_InfoCache.ContainsKey(activity) &&
                    m_InfoCache[activity].m_SprocketTrack != null)
                {
                    retrieveInfo = false;
                }

                if (retrieveInfo)
                {
                    ITimeDataSeries <SprocketCombo> sprocketTrack = Common.Data.GetSprocketTrack(activity);

                    UpdateCachedSprocketTrack(activity, sprocketTrack);
                }

                cachedItem = m_InfoCache[activity];

                return(cachedItem.m_SprocketTrack);
            }

            return(null);
        }
Ejemplo n.º 4
0
 private void InsertValue(DateTime atime, ITimeDataSeries <T> track, ITimeDataSeries <T> source)
 {
     if (atime >= this.startTime && atime <= this.endTime &&
         !ZoneFiveSoftware.Common.Data.Algorithm.DateTimeRangeSeries.IsPaused(atime, this.pauses))
     {
         TrackUtil.InsertValue <T>(atime, track, source);
     }
 }
Ejemplo n.º 5
0
        //ST interpolate is not handling subseconds, interpolate better if possible
        internal static T getValFromDateTimeIndex <T>(ITimeDataSeries <T> track, DateTime time, int i)
        {
            T dist;

            if (i < 0 || i >= track.Count || track.Count <= 1)
            {
                //index out of bound
                //Note that the distance track may not start at result StartTime, then this will report result at 0 sec
                Debug.Assert(true, "index out of bounds");
                i    = Math.Max(i, 0);
                i    = Math.Min(i, track.Count - 1);
                dist = track[i].Value;
            }
            else if (time == track.EntryDateTime(track[i]))
            {
                //Exact time, no interpolation
                dist = track[i].Value;
            }
            else
            {
                if (i == 0)
                {
                    i = 1;
                }
                float elapsed = (float)((time - track.StartTime).TotalSeconds);
                float f       = (elapsed - track[i - 1].ElapsedSeconds) / (float)(track[i].ElapsedSeconds - track[i - 1].ElapsedSeconds);
                dist = track[i - 1].Value; //assignment for compiler
                if (dist is float)
                {
                    float v0 = (float)(object)(track[i - 1].Value);
                    float v1 = (float)(object)(track[i].Value);
                    dist = (T)(object)(v0 + (v1 - v0) * f);
                }
                else if (dist is IGPSPoint)
                {
                    IGPSPoint v0  = (IGPSPoint)(object)(track[i - 1].Value);
                    IGPSPoint v1  = (IGPSPoint)(object)(track[i].Value);
                    float     lat = (v0.LatitudeDegrees + (v1.LatitudeDegrees - v0.LatitudeDegrees) * f);
                    float     lon = (v0.LongitudeDegrees + (v1.LongitudeDegrees - v0.LongitudeDegrees) * f);
                    float     ele = (v0.ElevationMeters + (v1.ElevationMeters - v0.ElevationMeters) * f);
                    dist = (T)(object)(new GPSPoint(lat, lon, ele));
                }
                else
                {
                    //Added to satisfy compiler - not possible to configure
                    Debug.Assert(true, "Unexpected ITimeDataSeries");
                    dist = default(T);
                }
            }
            return(dist);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Caculate basic stats for each sprocket.  This mostly allows to know the times during which we used a given gear
        /// </summary>
        /// <param name="activity"></param>
        /// <param name="sprocketTrack"></param>
        /// <returns>Returns an IList<SprocketComboInfo> of the sprocket combo info</returns>
        public static IList <SprocketComboInfo> Calculate(IActivity activity, ITimeDataSeries <SprocketCombo> sprocketTrack)
        {
            List <SprocketCombo>     sprockets        = GetSprocketCombos(activity);
            List <SprocketComboInfo> result           = new List <SprocketComboInfo>(sprockets.Count + 1);
            SprocketCombo            lastItemSprocket = null;
            DateTime sectionStartTime = sprocketTrack.StartTime;

            // Create the results for each zone
            foreach (SprocketCombo combo in sprockets)
            {
                result.Add(new SprocketComboInfo(combo));
            }

            // Go through and find the corresponding sprocket combo for each point
            foreach (ITimeValueEntry <SprocketCombo> item in sprocketTrack)
            {
                // We found a change in gear, add section to times
                if (lastItemSprocket != item.Value)
                {
                    DateTime currentItemTime = sprocketTrack.EntryDateTime(item);

                    // First item, ignore it
                    if (lastItemSprocket != null)
                    {
                        int index = sprockets.IndexOf(lastItemSprocket);

                        result[index].Times.Add(new ValueRange <DateTime>(sectionStartTime, currentItemTime));
                    }

                    sectionStartTime = currentItemTime;
                    lastItemSprocket = item.Value;
                }
            }

            // Add last section
            if (lastItemSprocket != null && sprocketTrack.Count > 0)
            {
                int      index   = sprockets.IndexOf(lastItemSprocket);
                DateTime endTime = sprocketTrack.EntryDateTime(sprocketTrack[sprocketTrack.Count - 1]);

                result[index].Times.Add(new ValueRange <DateTime>(sectionStartTime, endTime));

                // There is also a "totals" when Calculate is used in ST, add it although it's a bit useless for now
                SprocketComboInfo totals = new SprocketComboInfo(null);

                totals.Times.Add(new ValueRange <DateTime>(sprocketTrack.StartTime, endTime));
                result.Add(totals);
            }

            return(result);
        }
Ejemplo n.º 7
0
        private void UpdateCachedSprocketTrack(IActivity activity, ITimeDataSeries <SprocketCombo> sprocketTrack)
        {
            ActivityGearTrackCacheItem newCacheItem = new ActivityGearTrackCacheItem(activity);

            if (!m_InfoCache.ContainsKey(activity))
            {
                m_InfoCache.Add(activity, null);

                activity.PropertyChanged += new PropertyChangedEventHandler(OnActivityDataChanged);
            }

            m_InfoCache[activity] = newCacheItem;
            m_InfoCache[activity].m_SprocketTrack = sprocketTrack;
        }
Ejemplo n.º 8
0
        private ComboUsageInfo GetMostUsedGearValue(List <RangeInfoCacheWrapper> allRanges)
        {
            if (allRanges.Count > 0 &&
                allRanges[0].ActivityPauselessCadenceTrack.Count > 0)
            {
                List <ComboUsageInfo> allRangesUsageInfo = new List <ComboUsageInfo>();

                foreach (RangeInfoCacheWrapper range in allRanges)
                {
                    ITimeDataSeries <SprocketCombo> rangeSprockets = GetRangeSprocketsTrack(range);
                    IList <SprocketComboInfo>       sprocketInfo   = GetSprocketComboInfo(range, rangeSprockets);

                    for (int i = 0; i < sprocketInfo.Count; ++i)
                    {
                        TimeSpan currentComboDuration = new TimeSpan(0);

                        foreach (IValueRange <DateTime> times in sprocketInfo[i].Times)
                        {
                            currentComboDuration += (times.Upper - times.Lower);
                        }

                        if (allRangesUsageInfo.Count <= i)
                        {
                            allRangesUsageInfo.Add(new ComboUsageInfo(sprocketInfo[i].SprocketCombo, currentComboDuration));
                        }
                        else
                        {
                            allRangesUsageInfo[i].m_UsageDuration += currentComboDuration;
                        }
                    }
                }

                SprocketCombo mostUsedCombo    = null;
                TimeSpan      mostUsedDuration = new TimeSpan(0);

                foreach (ComboUsageInfo comboInfo in allRangesUsageInfo)
                {
                    if (mostUsedCombo == null || mostUsedDuration < comboInfo.m_UsageDuration)
                    {
                        mostUsedCombo    = comboInfo.m_Combo;
                        mostUsedDuration = comboInfo.m_UsageDuration;
                    }
                }

                return(new ComboUsageInfo(mostUsedCombo, mostUsedDuration));
            }

            return(null);
        }
Ejemplo n.º 9
0
        public static void InsertValue <T>(DateTime atime, ITimeDataSeries <T> track, ITimeDataSeries <T> source)
        {
            //Interpolation is down to seconds
            //TBD: Inefficient, source.IndexOf often fails
#if ST_3_1_5314_BUG
            //http://www.zonefivesoftware.com/sporttracks/forums/viewtopic.php?p=84638#p84638
            //System.Exception: FindPosOnOrBefore: Didn't find element properly.
            try
            {
#endif
            ITimeValueEntry <T> interpolatedP = source.GetInterpolatedValue(atime);
            if (interpolatedP != null)
            {
                int index = source.IndexOf(interpolatedP);
                T   val   = interpolatedP.Value;
                if (index >= 0)
                {
                    val = TrackUtil.getValFromDateTimeIndex(source, atime, index);
                }
                else
                {
                }
                try
                {
#if !NO_ST_INSERT_START_TIME
                    //ST bug: not inserted in order if ms differs for start
                    if (Math.Abs((atime - track.StartTime).TotalSeconds) < 1)
                    {
                        track.RemoveAt(0);
                    }
#endif
                    track.Add(atime, val);
                    //T val2 = track.GetInterpolatedValue(atime).Value;
                }
                catch { }
            }
#if ST_3_1_5314_BUG
        }

        catch (Exception e)
        {
        }
#endif
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Create gear guess selection chart based on gear ratios
        /// </summary>
        /// <param name="input">Pre-calculated raw data to estimate from.  This should already be smoothed or filtered if desired.</param>
        /// <returns>Gear guess NumericTimeDataSeries</returns>
        public static NumericTimeDataSeries GuessGears(INumericTimeDataSeries input, List <SprocketCombo> sprockets)
        {
            ITimeDataSeries <SprocketCombo> guessSprockets = GuessSprockets(input, sprockets);
            NumericTimeDataSeries           guessSeries    = new NumericTimeDataSeries();
            DateTime lastTime = input.StartTime;

            // Iterate through entire data series, recreating the result
            foreach (ITimeValueEntry <SprocketCombo> item in guessSprockets)
            {
                float ratio = 0;

                if (item.Value != null)
                {
                    ratio = item.Value.GearRatio;
                }

                guessSeries.Add(guessSprockets.EntryDateTime(item), ratio);
            }

            return(guessSeries);
        }
Ejemplo n.º 11
0
        /****************************************************/
        //Before ST 3_0_4205 points was not always inserted in order
        //For some reason this occasionally occurs in Trails 1.2.821 too
        public static bool ResortTrack <T>(ITimeDataSeries <T> track)
        {
            bool reSort = false;

#if !NO_ST_RESORT_TRACKS
            if (track.Count > 0)
            {
                for (int i = 1; i < track.Count; i++)
                {
                    if (track[i - 1].ElapsedSeconds > track[i].ElapsedSeconds)
                    {
                        reSort = true;
                        break;
                    }
                }
                if (reSort)
                {
                    SortedDictionary <uint, ITimeValueEntry <T> > dic = new SortedDictionary <uint, ITimeValueEntry <T> >();
                    foreach (ITimeValueEntry <T> g in track)
                    {
                        if (!dic.ContainsKey(g.ElapsedSeconds))
                        {
                            dic.Add(g.ElapsedSeconds, g);
                        }
                    }
                    DateTime startTimeTrack = track.StartTime;
                    track.Clear();
                    foreach (KeyValuePair <uint, ITimeValueEntry <T> > g in dic)
                    {
                        track.Add(startTimeTrack.AddSeconds(g.Value.ElapsedSeconds), g.Value.Value);
                    }
                }
            }
#endif
            return(reSort);
        }
Ejemplo n.º 12
0
        public ITimeDataSeries <SprocketCombo> GetRangeSprocketsTrack(RangeInfoCacheWrapper range)
        {
            ITimeDataSeries <SprocketCombo> result = null;

            if (range.ContainsStoredInfo(m_SprocketTrackStoredInfoId) &&
                range.RetrieveStoredInfo(m_SprocketTrackStoredInfoId) != null)
            {
                result = range.RetrieveStoredInfo(m_SprocketTrackStoredInfoId) as ITimeDataSeries <SprocketCombo>;
            }
            else
            {
                INumericTimeDataSeries gears = ActivityGearTrackCache.Instance.CalculateGearTrack(range.Activity);

                gears = Utils.Utils.RemovePausedTimesInTrack(gears, range.Activity);

                NumericTimeDataSeries tempResult = new NumericTimeDataSeries();
                Utils.Utils.ExtractRangeFromDataTrack(gears, range.PauselessRange, tempResult);
                result = GearChart.UI.GearUtils.GuessSprockets(tempResult, Common.Data.GetSprocketCombos(range.Activity));

                range.SaveStoredInfo(m_SprocketTrackStoredInfoId, result);
            }

            return(result);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Insert values at borders: Start, stop, pauses, trailpoints
        /// </summary>
        /// <param name="track"></param>
        /// <param name="source"></param>
        public void insertValues(ITimeDataSeries <T> track, ITimeDataSeries <T> source)
        {
            //Insert points around pauses and points
            //This is needed to get the track match the cut-up activity
            //(otherwise for instance start point need to be added)

            IList <DateTime> dates = new List <DateTime>();

            //start/end should be included from points, but prepare for changes...
            InsertValue(startTime, track, source);
            InsertValue(endTime, track, source);
            dates.Add(startTime);
            dates.Add(endTime);

            foreach (IValueRange <DateTime> p in pauses)
            {
                if (p.Lower > startTime)
                {
                    InsertValue(p.Lower.AddSeconds(-1), track, source);
                    dates.Add(p.Lower.AddSeconds(-1));
                }
                if (p.Upper < endTime)
                {
                    InsertValue(p.Upper.AddSeconds(1), track, source);
                    dates.Add(p.Upper.AddSeconds(1));
                }
            }

            if (this.points != null)
            {
                foreach (TrailResultPoint t in points)
                {
                    DateTime dateTime = t.Time;
                    if (dateTime > startTime && dateTime < endTime)
                    {
                        //Adding an extra point will change averages etc
                        //InsertValue(dateTime.AddSeconds(-1), track, source);
                        InsertValue(dateTime, track, source);
                        dates.Add(dateTime);
                    }
                }
            }
            //((List<DateTime>)dates).Sort();
            //kolla avrundning av elapsed både då starttime.ms och entry.ms
            //int j = 0;
            //double elapsedDate = (dates[j] - source.StartTime).TotalSeconds;
            //for (int i = 0; i < source.Count - 1; i++)
            //{
            //    uint elapsedSrc = source[i].ElapsedSeconds;
            //    while (j < dates.Count && (dates[j] < source.StartTime ||
            //        elapsedDate < elapsedSrc))
            //    {
            //        j++;
            //        if (j < dates.Count)
            //        {
            //            elapsedDate = (dates[j] - source.StartTime).TotalSeconds;
            //        }
            //    }
            //    if (j >= dates.Count || elapsedDate > source.TotalElapsedSeconds)
            //    {
            //        //No more dates
            //        break;
            //    }
            //    if (elapsedDate >= elapsedSrc)
            //    {
            //
            //    }
            //}
            //ST bug: track could be out of order (due to insert at least)
            TrackUtil.ResortTrack(track);
        }
Ejemplo n.º 14
0
        public IList <SprocketComboInfo> GetSprocketComboInfo(RangeInfoCacheWrapper range, ITimeDataSeries <SprocketCombo> sprocketTrack)
        {
            IList <SprocketComboInfo> result;

            if (range.ContainsStoredInfo(m_SprocketStoredInfoId) &&
                range.RetrieveStoredInfo(m_SprocketStoredInfoId) != null)
            {
                result = range.RetrieveStoredInfo(m_SprocketStoredInfoId) as IList <SprocketComboInfo>;
            }
            else
            {
                result = Common.Data.Calculate(range.Activity, sprocketTrack);

                // Remove totals row
                result.RemoveAt(result.Count - 1);

                range.SaveStoredInfo(m_SprocketStoredInfoId, result);
            }

            return(result);
        }