コード例 #1
0
ファイル: UniqueRoutes.cs プロジェクト: tsofron/trails
        public static IList <IActivity> GetSimilarRoutes(IGPSRoute route, IList <IActivity> activities, System.Windows.Forms.ProgressBar progressBar)
        {
            IList <IActivity> results = null;

            try
            {
                if (progressBar == null)
                {
                    progressBar = new System.Windows.Forms.ProgressBar();
                }

                if (GetUniqueRoutes != null)
                {
                    MethodInfo methodInfo         = GetUniqueRoutes.GetMethod(findSimilarRouteSnippets);
                    object     resultFromURPlugIn = methodInfo.Invoke(route, new object[] { route, activities, progressBar });
                    results = (IList <IActivity>)resultFromURPlugIn;
                }
            }
            catch (Exception e)
            {
                // Log error?
                _uniqueRoutes = null;
                throw new Exception(string.Format(IntegrationUtility.OtherPluginExceptionText,
                                                  UniquePlugin + ".dll", UniqueRoutesPluginName) + Environment.NewLine, e);
            }

            if (GetUniqueRoutes == null)
            {
                throw new Exception(string.Format(IntegrationUtility.OtherPluginExceptionText,
                                                  UniquePlugin + ".dll", UniqueRoutesPluginName) + Environment.NewLine);
            }

            return(results);
        }
コード例 #2
0
ファイル: GPSGrid.cs プロジェクト: jcboliveira/gps-running
 public GPSGrid(GPSGrid refGrid, IGPSRoute route, double BWidthFactor, double DistFactor, bool isDist)
 {
     m_Distance = DistFactor * Settings.Radius;
     m_Grid = new Dictionary<int, IDictionary<int, IList<int>>>();
     m_Route = route; //Just copy the reference
     if (refGrid == null)
     {
         //Set grid size from aprox distance for reference
         //See Trails plugin, TrailsGPSLocation.getGPSBounds()
         m_latWidth = BWidthFactor * Settings.Radius / 110574 * 1.005F;
         m_lngWidth = BWidthFactor * Settings.Radius / 111132 / Math.Cos(m_Route[0].Value.LongitudeDegrees * Math.PI / 180);
     }
     else
     {
         m_latWidth = refGrid.m_latWidth;
         m_lngWidth = refGrid.m_lngWidth;
     }
     if (isDist)
     {
         m_Dist = m_Route.GetDistanceMetersTrack();
     }
     else
     {
         m_Dist = null;
     }
     for (int i = 0; i < m_Route.Count; i++ )
     {
         addGrid(i);
     }
 }
コード例 #3
0
        internal static void setCapacity(IGPSRoute t, int v)
        {
#if ST_3_1_5314
            if (t is ZoneFiveSoftware.Common.Data.GPS.GPSRoute2)
            {
                ((ZoneFiveSoftware.Common.Data.GPS.GPSRoute2)t).Capacity = v;
            }
#endif
        }
コード例 #4
0
 public GlobalsatRoute(string name, IGPSRoute route)
 {
     this.Name = name;
     this.wpts = new List <GlobalsatWaypoint>();
     foreach (ZoneFiveSoftware.Common.Data.ITimeValueEntry <IGPSPoint> g in route)
     {
         this.wpts.Add(new GlobalsatWaypoint("", 0, (short)g.Value.ElevationMeters, g.Value.LatitudeDegrees, g.Value.LongitudeDegrees));
     }
 }
コード例 #5
0
        public static IList <IList <IGPSPoint> > GpsPoints(IGPSRoute gpsRoute, IValueRangeSeries <DateTime> selections)
        {
            IList <IList <IGPSPoint> > result = new List <IList <IGPSPoint> >();

            if (selections != null && selections.Count > 0 && gpsRoute != null && gpsRoute.Count > 1)
            {
                //selection and gps points are sorted without overlap so traverse over gps points only once
                //(previous version had much more complicated version, that also accounted for pauses)
                int i = 0;
                foreach (IValueRange <DateTime> sel in selections)
                {
                    IList <IGPSPoint> track = new List <IGPSPoint>();
                    //Use start/end "with priority", even if extra points are added. Care needed if returning GPSRoute
                    DateTime t = DateTimeRangeSeries.Latest(sel.Lower, gpsRoute.StartTime);
                    ITimeValueEntry <IGPSPoint> pt = gpsRoute.GetInterpolatedValue(t);
                    if (pt != null)
                    {
                        track.Add(pt.Value);
                    }
                    while (i < gpsRoute.Count)
                    {
                        ITimeValueEntry <IGPSPoint> entry = gpsRoute[i];
                        DateTime time = gpsRoute.EntryDateTime(entry);
                        i++;
                        if (sel.Lower > time)
                        {
                            continue;
                        }
                        if (sel.Upper < time)
                        {
                            //Do not increase counter here, it could be needed
                            i--;
                            break;
                        }
                        track.Add(entry.Value);
                    }
                    t  = DateTimeRangeSeries.Earliest(sel.Upper, gpsRoute.StartTime.AddSeconds(gpsRoute.TotalElapsedSeconds));
                    pt = gpsRoute.GetInterpolatedValue(t);
                    if (pt != null)
                    {
                        track.Add(pt.Value);
                    }
                    result.Add(track);
                }
            }

            return(result);
        }
コード例 #6
0
 public static IList<IActivity> findSimilarRouteSnippets(IGPSRoute route, IList<IActivity> activities, System.Windows.Forms.ProgressBar progressBar)
 {
     return GpsRunningPlugin.Source.UniqueRoutes.findSimilarRoutes(route, activities, progressBar);
 }
コード例 #7
0
ファイル: GPSGrid.cs プロジェクト: jcboliveira/gps-running
 public GPSGrid(GPSGrid refGrid, IGPSRoute route)
     : this(refGrid, route, 1, 1, false)
 { }
コード例 #8
0
        /// <summary>
        /// Used to generate the record properties of the supplied activity
        /// </summary>
        /// <param name="activity">The full activity for the record</param>
        /// <param name="category">The Record Category for this record</param>
        /// <param name="gpsTrack">The GPS route of the actual record</param>
        /// <param name="hrTrack">The HR track of the actual record</param>
        /// <param name="pwrTrack">The power track of the actual record</param>
        /// <param name="cadTrack">The cadence track of the actual record</param>
        public Record(IActivity activity, RecordCategory category, IGPSRoute gpsTrack, INumericTimeDataSeries hrTrack, INumericTimeDataSeries pwrTrack, INumericTimeDataSeries cadTrack, IDistanceDataTrack distTrack, INumericTimeDataSeries elevTrack, DateTime activityStartTime)
        {
            // Create new activity from template
            IActivity recActivity = (IActivity)Activator.CreateInstance(activity.GetType());

            // HACK: Manually Clone 'activity' until a better way is found
            recActivity.Category                = activity.Category;
            recActivity.DistanceMetersTrack     = distTrack;
            recActivity.ElevationMetersTrack    = elevTrack;
            recActivity.GPSRoute                = gpsTrack;
            recActivity.HasStartTime            = activity.HasStartTime;
            recActivity.HeartRatePerMinuteTrack = hrTrack;
            recActivity.Intensity               = activity.Intensity;
            recActivity.Location                = activity.Location;
            recActivity.Name                                 = activity.Name;
            recActivity.PowerWattsTrack                      = pwrTrack;
            recActivity.CadencePerMinuteTrack                = cadTrack;
            recActivity.Weather.Conditions                   = activity.Weather.Conditions;
            recActivity.Weather.CurentDirectionDegrees       = activity.Weather.CurentDirectionDegrees;
            recActivity.Weather.CurentSpeedKilometersPerHour = activity.Weather.CurentSpeedKilometersPerHour;
            recActivity.Weather.HumidityPercent              = activity.Weather.HumidityPercent;
            recActivity.Weather.TemperatureCelsius           = activity.Weather.TemperatureCelsius;
            recActivity.Weather.WindDirectionDegrees         = activity.Weather.WindDirectionDegrees;
            recActivity.Weather.WindSpeedKilometersPerHour   = activity.Weather.WindSpeedKilometersPerHour;

            // Set the start time for the record activity
            recActivity.StartTime = activityStartTime;

            // Set up the activity info for pulling summary data
            ActivityInfo info = ActivityInfoCache.Instance.GetInfo(recActivity);

            // Set the record category
            this.category = category;

            // Max and Min elevation seen over the route
            float maxE = float.NegativeInfinity;
            float minE = float.PositiveInfinity;

            if (activity.GPSRoute != null && activity.GPSRoute.Count > 0)
            {
                GPSRoute startRoute = new GPSRoute();
                for (int i = 0; i < activity.GPSRoute.Count; i++)
                {
                    GPSPoint p = (GPSPoint)activity.GPSRoute[i].Value;
                    if (p.ElevationMeters > maxE)
                    {
                        maxE = p.ElevationMeters;
                    }

                    if (p.ElevationMeters < minE)
                    {
                        minE = p.ElevationMeters;
                    }

                    if (gpsTrack.Count == 0)
                    {
                        break;
                    }

                    if (p.Equals((GPSPoint)gpsTrack[0].Value))
                    {
                        break;
                    }
                    else
                    {
                        startRoute.Add(activity.GPSRoute.EntryDateTime(activity.GPSRoute[i]), p);
                    }
                }
                startDistance = startRoute.TotalDistanceMeters;
            }
            else if (activity.ElevationMetersTrack != null)
            {
                for (int i = 0; i < activity.ElevationMetersTrack.Count; i++)
                {
                    if (activity.ElevationMetersTrack[i].Value > maxE)
                    {
                        maxE = activity.ElevationMetersTrack[i].Value;
                    }

                    if (activity.ElevationMetersTrack[i].Value < maxE)
                    {
                        minE = activity.ElevationMetersTrack[i].Value;
                    }
                }
                startDistance = 0;
            }

            this.maxElevation  = maxE;
            this.minElevation  = minE;
            this.trueStartDate = activity.StartTime;
            this.activity      = recActivity;
        }
コード例 #9
0
 public static IDictionary<IActivity, IList<PointInfo[]>> findSimilarPoints(IGPSRoute refRoute, IList<IActivity> activities, System.Windows.Forms.ProgressBar progressBar)
 {
     return findSimilarPoints(refRoute, null, activities, progressBar);
 }
コード例 #10
0
        private static IList<IActivity> findSimilarRoutes(IGPSRoute refRoute, string refId, IList<IActivity> activities, bool activityCompare, System.Windows.Forms.ProgressBar progressBar)
        {
            if (progressBar == null)
            {
                progressBar = new System.Windows.Forms.ProgressBar();
            }
            IList<IActivity> result = new List<IActivity>();
            if (refRoute == null || refRoute.Count == 0)
                return result;
            if (activities == null)
            {
                activities = getBaseActivities();
            }
            progressBar.Value = 0;
            progressBar.Minimum = 0;
            progressBar.Maximum = activities.Count;

            GPSGrid refGrid = new GPSGrid(null, refRoute);
            IDictionary<string, int> beginningPoints = new Dictionary<string, int>();
            IDictionary<string, int> endPoints = new Dictionary<string, int>();

            setBeginningAndEndPoints(refId, refRoute, activityCompare, beginningPoints, endPoints);
            if (!beginningPoints.ContainsKey(refId) ||
                beginningPoints[refId] <= -1 ||
                      endPoints[refId] <= -1)
            {
                //The settings does not include any points
                return result;
            }
            foreach (IActivity otherActivity in activities)
            {
                if (otherActivity.GPSRoute != null && otherActivity.GPSRoute.Count > 0 &&
                    //Simple prune, eliminating routes not possibly common
                        otherActivity.GPSRoute[0].Value.DistanceMetersToPoint(refRoute[0].Value)
                        < otherActivity.GPSRoute.TotalDistanceMeters + refRoute.TotalDistanceMeters)
                {
                    setBeginningAndEndPoints(otherActivity, activityCompare, beginningPoints, endPoints);
                    //int noOfPoints = otherActivity.GPSRoute.Count;
                    if (beginningPoints[otherActivity.ReferenceId] > -1 && endPoints[otherActivity.ReferenceId] > -1)
                    {
                        int pointsOutside = 0;
                        bool inBand = true;
                        int direction = 0;
                        int prevMatch = -1;

                        //IGPSBounds otherBounds = GPSBounds.FromGPSRoute(otherActivity.GPSRoute);
                        GPSGrid otherGrid = new GPSGrid(refGrid, otherActivity);

                        //Check if the reference route fits in the other activity
                        for (int i = beginningPoints[refId]; i <= endPoints[refId]; i++)
                        {
                            IGPSPoint point = refRoute[i].Value;
                            int closests = otherGrid.getClosePoint(point);
                            if (closests < 0)
                            {
                                pointsOutside++;
                                if (pointsOutside / ((double)refRoute.Count) > Settings.ErrorMargin)
                                {
                                    inBand = false;
                                    break;
                                }
                            }
                            else if (Settings.HasDirection)
                            {
                                int currMatch = closests;// grid.getCloseSinglePoint(point);
                                if (currMatch > prevMatch)
                                {
                                    direction++;
                                }
                                else if (currMatch < prevMatch)
                                {
                                    direction--;
                                }
                                prevMatch = currMatch;

                                ////Find direction. Works well when the routes are not overlapping and have similar length
                                ////Use all matching points to get majority decision
                                ////All matching points from grid.getAllClose would be better but is significantly slower
                                //bool inOtherLowerHalf = i < otherActivity.GPSRoute.Count / 2;
                                //bool inLowerHalf = closests < refRoute.Count / 2;

                                //if ((inLowerHalf && inOtherLowerHalf) ||
                                //    (!inLowerHalf && !inOtherLowerHalf))
                                //    direction++;
                                //else
                                //    direction--;

                            }
                        }

                        //Check if the other activity matches the reference route 
                        //Only used when comparing activities
                        if (inBand && activityCompare)
                        {
                            pointsOutside = 0;
                            for (int i = beginningPoints[otherActivity.ReferenceId]; i <= endPoints[otherActivity.ReferenceId]; i++)
                            {
                                IGPSPoint point = otherActivity.GPSRoute[i].Value;
                                int closests = refGrid.getClosePoint(point);
                                if (closests < 0)
                                {
                                    pointsOutside++;
                                    if (pointsOutside / ((double)otherActivity.GPSRoute.Count) > Settings.ErrorMargin)
                                    {
                                        inBand = false;
                                        break;
                                    }
                                }
                            }
                        }
                        if (inBand && direction >= 0)
                        {
                            result.Add(otherActivity);
                        }
                    }
                }
                progressBar.Increment(1);
            }

            return result;
        }
コード例 #11
0
 public static IList<IActivity> findSimilarRoutes(IGPSRoute refRoute, IList<IActivity> activities, bool activityCompare, System.Windows.Forms.ProgressBar progressBar)
 {
     return findSimilarRoutes(refRoute, "", activities, activityCompare, progressBar);
 }
コード例 #12
0
 private static void setBeginningAndEndPoints(string activity, IGPSRoute gpsroute, bool beginEndCheck,
     IDictionary<string, int> beginningPoints,
     IDictionary<string, int> endPoints)
 {
     double length = 0;
     //prune with some searches
     beginningPoints[activity] = 0;
     endPoints[activity] = gpsroute.Count - 1;
     if (beginEndCheck)
     {
         length = Settings.IgnoreBeginning + Settings.IgnoreEnd;
         if (length > gpsroute.TotalDistanceMeters)
         {
             //not used at all
             beginningPoints[activity] = -1;
             endPoints[activity] = -1;
             return;
         }
         if (length > 0)
         {
             //Note: As we normally cover few points, this is faster than activity.GPSRoute.GetDistanceMetersTrack()
             //(and the distance track must be scanned, there is no simple way to get the index for a distance)
             //If the algoritm to calc dist is changed, this should be changed too
             IGPSPoint previous;
             if (Settings.IgnoreBeginning > 0)
             {
                 length = 0;
                 previous = null;
                 for (int i = 0; i < gpsroute.Count; i++)
                 {
                     if (length >= Settings.IgnoreBeginning)
                     {
                         beginningPoints[activity] = i;
                         break;
                     }
                     IGPSPoint point = gpsroute[i].Value;
                     if (previous != null)
                         length += point.DistanceMetersToPoint(previous);
                     previous = point;
                 }
             }
             if (Settings.IgnoreEnd > 0)
             {
                 length = 0;
                 previous = null;
                 for (int i = gpsroute.Count - 1; i >= 0; i--)
                 {
                     IGPSPoint current = gpsroute[i].Value;
                     if (length >= Settings.IgnoreEnd)
                     {
                         endPoints[activity] = i;
                         break;
                     }
                     if (previous != null)
                         length += previous.DistanceMetersToPoint(current);
                     previous = current;
                 }
             }
         }
     }
 }
コード例 #13
0
        public static IList<IList<IGPSPoint>> GpsPoints(IGPSRoute gpsRoute, IValueRangeSeries<DateTime> selections)
        {
            IList<IList<IGPSPoint>> result = new List<IList<IGPSPoint>>();

            if (selections != null && selections.Count > 0 && gpsRoute != null && gpsRoute.Count > 1)
            {
                //selection and gps points are sorted without overlap so traverse over gps points only once
                //(previous version had much more complicated version, that also accounted for pauses)
                int i = 0;
                foreach (IValueRange<DateTime> sel in selections)
                {
                    IList<IGPSPoint> track = new List<IGPSPoint>();
                    //Use start/end "with priority", even if extra points are added. Care needed if returning GPSRoute
                    DateTime t =  DateTimeRangeSeries.Latest(sel.Lower, gpsRoute.StartTime);
                    ITimeValueEntry<IGPSPoint> pt = gpsRoute.GetInterpolatedValue(t);
                    if (pt != null)
                    {
                        track.Add(pt.Value);
                    }
                    while (i < gpsRoute.Count)
                    {
                        ITimeValueEntry<IGPSPoint> entry = gpsRoute[i];
                        DateTime time = gpsRoute.EntryDateTime(entry);
                        i++;
                        if (sel.Lower > time)
                        {
                            continue;
                        }
                        if (sel.Upper < time)
                        {
                            //Do not increase counter here, it could be needed
                            i--;
                            break;
                        }
                        track.Add(entry.Value);
                    }
                    t = DateTimeRangeSeries.Earliest(sel.Upper, gpsRoute.StartTime.AddSeconds(gpsRoute.TotalElapsedSeconds));
                    pt = gpsRoute.GetInterpolatedValue(t);
                    if (pt != null)
                    {
                        track.Add(pt.Value);
                    }
                    result.Add(track);
                }
            }

            return result;
        }
コード例 #14
0
 static bool getRestLap(int index, IGPSRoute route, IActivityLaps laps)
 {
     bool restLap = false;
     if (laps != null && laps.Count > 1)
     {
         restLap = laps[laps.Count - 1].Rest;
         for (int i = 0; i < laps.Count - 1; i++)
         {
             //End time is starttime for next lap
             //Go from first to second last to find where it fits (default is last, no end time there)
             if (0 > route.EntryDateTime(route[index]).CompareTo(laps[i + 1].StartTime))
             {
                 //time was in previous lap
                 restLap = laps[i].Rest;
                 break;
             }
         }
     }
     return restLap;
 }
コード例 #15
0
        public static IDictionary<IActivity, IList<PointInfo[]>> findSimilarPoints(IGPSRoute refRoute, IActivityLaps refLaps, IList<IActivity> activities, System.Windows.Forms.ProgressBar progressBar)
        {
            GPSGrid refGrid = new GPSGrid(null, refRoute, 1F, 0.5F, true);
            IDictionary<IActivity, IList<PointInfo[]>> result = new Dictionary<IActivity, IList<PointInfo[]>>();
            double cumulativeAverageDist = 0;
            int noCumAv = 0;
            if (activities != null)
            {
                if (progressBar != null)
                {
                    progressBar.Value = 0;
                    progressBar.Minimum = 0;
                    progressBar.Maximum = activities.Count;
                }
                foreach (IActivity otherActivity in activities)
                {
                    const int ExtraGridIndex = 2;
                    const float MaxDistDiffFactor = 0.1F;
                    double minDistStretch = Settings.Radius * 2;

                    result.Add(otherActivity, new List<PointInfo[]>());
                    IDistanceDataTrack distTrack = otherActivity.GPSRoute.GetDistanceMetersTrack();
                    int lastMatch = -1; //index of previous match
                    int startMatch = -1;
                    IndexDiffDist lastMatchRef = null;
                    IndexDiffDist startMatchRef = null;
                    IndexDiffDist lastIndex = null;
                    for (int i = 0; i < otherActivity.GPSRoute.Count; i++)
                    {
                        IList<IndexDiffDist> currIndex = new List<IndexDiffDist>();
                        IndexDiffDist closeIndex = null; //Closest to current point
                        IndexDiffDist nextIndex = null; //The best match in this stretch
                        bool isEnd = true; //This is the end of a stretch, unless a matching point is found
                        currIndex = refGrid.getAllCloseStretch(otherActivity.GPSRoute[i].Value);
                        if (currIndex.Count > 0)
                        {
                            int prio = int.MaxValue;
                            foreach (IndexDiffDist IndDist in currIndex)
                            {
                                if (IndDist.Index > -1)
                                {
                                    //Get the closest good enough point - used at start and could restart current stretch
                                    if (closeIndex == null ||
                                        //Close match in distance
                                        (Math.Abs(IndDist.Dist - distTrack[i].Value) < 3 * Settings.Radius) ||
                                        //Close to other matches
                                        (Math.Abs(IndDist.Dist - distTrack[i].Value - cumulativeAverageDist) <
                                    Math.Abs(closeIndex.Dist - distTrack[i].Value - cumulativeAverageDist)))
                                    {
                                        closeIndex = IndDist;
                                    }

                                    //next in relation to previous match
                                    if (lastMatch > -1 && lastIndex != null)
                                    {
                                        //Only check forward, i.e follow the same direction
                                        //Use a close enough stretch
                                        //This is the iffiest part of the algorithm matching stretches...
                                        if ((IndDist.low >= lastIndex.low && IndDist.low <= lastIndex.high ||
                                             IndDist.Index >= lastIndex.low && IndDist.Index <= lastIndex.high) &&
                                            IndDist.Index >= lastIndex.Index)
                                        {
                                            //The grid overlaps the old grid
                                            //The matching index may be lower then this is a restart (this or prev match should then be dropped)
                                            if ((prio > 0 && (nextIndex == null || IndDist.Diff < nextIndex.Diff) && IndDist.Index >= lastIndex.Index))
                                            {
                                                nextIndex = IndDist;
                                                prio = 0;
                                            }
                                            else if (prio >= 0 && (IndDist.Index > lastIndex.Index && (nextIndex == null || nextIndex.Index <= lastIndex.Index)))
                                            {
                                                nextIndex = IndDist;
                                                prio = 0;
                                            }
                                            else if (IndDist.Index == lastIndex.Index && (nextIndex == null || nextIndex.Index < lastIndex.Index))
                                            {
                                                nextIndex = IndDist;
                                                prio = 0;
                                            }
                                            else if (prio > 10)
                                            {
                                                nextIndex = IndDist;
                                                prio = 10;
                                            }
                                            else if (nextIndex == null)
                                            {
                                                nextIndex = IndDist;
                                                prio = 10;
                                            }
                                            //else - not better
                                        }
                                        else if ((
                                             IndDist.low >= lastIndex.low && IndDist.low <= lastIndex.high + ExtraGridIndex ||
                                             IndDist.Index >= lastIndex.low && IndDist.Index <= lastIndex.high + ExtraGridIndex))
                                        {
                                            //Grids are not overlapping, but adjacent points match forward
                                            if (prio > 20 && IndDist.Index > lastIndex.Index)
                                            {
                                                nextIndex = IndDist;
                                                prio = 20;
                                            }
                                            else if (prio >= 20)
                                            {
                                                nextIndex = IndDist;
                                                prio = 20;
                                            }
                                        }
                                        else if ((
                                              Math.Abs(IndDist.Dist / lastIndex.Dist - 1) < MaxDistDiffFactor) &&
                                            (prio > 20))
                                        {
                                            nextIndex = IndDist;
                                            prio = 30;
                                        }
                                    }
                                }
                            }

                            //Update if close enough
                            if (closeIndex != null)
                            {
                                //TODO: This algorithm needs to prio correct direction better
                                //nextInd is best match for the stretch, but closeIndex could be better 
                                if (nextIndex == null ||
                                    (!nextIndex.Equals(closeIndex)) && (
                                    //back match - prefer closer
                                    lastIndex.Index > nextIndex.Index ||
                                    prio > 10 && (minDistStretch < distTrack[i].Value - distTrack[startMatch].Value ||
                                            (Math.Abs(nextIndex.Dist - distTrack[i].Value) > Settings.Radius) ||
                                            (Math.Abs(nextIndex.Dist - distTrack[i].Value - cumulativeAverageDist) >
                                        Math.Abs(closeIndex.Dist - distTrack[i].Value - cumulativeAverageDist)))))
                                {
                                    //switch to closeIndex and ignore nextIndex
                                    nextIndex = closeIndex;
                                    //start of new stretch - use best match to reference activity
                                    startMatch = i;
                                    lastIndex = closeIndex;
                                    startMatchRef = closeIndex;
                                }
                                else
                                {
                                    //The stretch continues
                                    isEnd = false;
                                    cumulativeAverageDist += (lastIndex.Diff - distTrack[i].Value - cumulativeAverageDist) / ++noCumAv;
                                }
                            }
                        }
                        if (isEnd && lastMatch >= 0)
                        {
                            // end match
                            PointInfo[] s = new PointInfo[2];
                            s[0] = new PointInfo(-i - 1);
                            s[1] = new PointInfo(-lastMatchRef.Index - 1);
                            result[otherActivity].Add(s);
                        }
                        if (nextIndex != null)
                        {
                            lastIndex = nextIndex;
                            lastMatchRef = lastIndex;
                            lastMatch = i;

                            PointInfo[] s = new PointInfo[2];
                            s[0] = new PointInfo(i, distTrack[i].Value, otherActivity.GPSRoute[i].ElapsedSeconds,
                                getRestLap(i, otherActivity),
                                startMatch + " " + lastMatch + " " + startMatchRef + " " + lastMatchRef);
                            s[1] = new PointInfo(lastIndex.Index, lastIndex.Dist, refRoute[lastIndex.Index].ElapsedSeconds,
                                getRestLap(lastIndex.Index, refRoute, refLaps));
                            result[otherActivity].Add(s);
                        }
                        else
                        {
                            lastMatch = -1;
                        }
                    }
                    //add end marker if needed
                    if (lastMatch > -1)
                    {
                        PointInfo[] s = new PointInfo[2];
                        s[0] = new PointInfo(-otherActivity.GPSRoute.Count);
                        s[1] = new PointInfo(-1);
                        result[otherActivity].Add(s);
                    }
                    if (progressBar != null)
                    {
                        progressBar.Increment(1);
                    }
                }
            }

            return result;
        }
コード例 #16
0
        //Get the data in a generic Globalsat format, to separate ST
        public static IList <GhPacketBase.Train> ToGlobTrack(GlobalsatProtocol device, IList <IActivity> activities)
        {
            IList <GhPacketBase.Train> result = new List <GhPacketBase.Train>();

            foreach (IActivity activity in activities)
            {
                IGPSRoute          gpsRoute = activity.GPSRoute;
                GhPacketBase.Train train    = new GhPacketBase.Train();
                train.StartTime           = activity.StartTime;
                train.TotalTime           = TimeSpan.FromSeconds(gpsRoute.TotalElapsedSeconds);
                train.TotalDistanceMeters = (Int32)Math.Round(gpsRoute.TotalDistanceMeters);
                train.LapCount            = 1;

                train.TotalCalories = (Int16)activity.TotalCalories;
                if (train.MaximumSpeed == 0 && train.TotalTime.TotalSeconds >= 1)
                {
                    //Better than 0(?) - Info() could be used
                    train.MaximumSpeed = train.TotalDistanceMeters / train.TotalTime.TotalSeconds;
                }
                train.MaximumHeartRate = (byte)activity.MaximumHeartRatePerMinuteEntered;
                train.AverageHeartRate = (byte)activity.AverageHeartRatePerMinuteEntered;
                train.TotalAscend      = (Int16)activity.TotalAscendMetersEntered;
                train.TotalDescend     = (Int16)activity.TotalDescendMetersEntered;
                train.AverageCadence   = (Int16)activity.AverageCadencePerMinuteEntered;
                train.MaximumCadence   = (Int16)activity.MaximumCadencePerMinuteEntered;
                train.AveragePower     = (Int16)activity.AveragePowerWattsEntered;
                train.MaximumPower     = (Int16)activity.MaximumPowerWattsEntered;
                //Some protocols send laps in separate header
                //Use common code instead of overiding this method

                //Laps are not implemented when sending, one lap hardcoded

                for (int j = 0; j < gpsRoute.Count; j++)
                {
                    IGPSPoint point = gpsRoute[j].Value;
                    GhPacketBase.TrackPoint trackpoint = new GhPacketBase.TrackPoint();
                    trackpoint.Latitude  = point.LatitudeDegrees;
                    trackpoint.Longitude = point.LongitudeDegrees;
                    trackpoint.Altitude  = (Int32)point.ElevationMeters;
                    if (j == 0)
                    {
                        trackpoint.IntervalTime = 0;
                    }
                    else
                    {
#if ST_2_1
                        int intTime = gpsRoute[j].ElapsedSeconds - gpsRoute[j - 1].ElapsedSeconds;
#else
                        uint intTime = gpsRoute[j].ElapsedSeconds - gpsRoute[j - 1].ElapsedSeconds;
#endif
                        float dist = gpsRoute[j].Value.DistanceMetersToPoint(gpsRoute[j - 1].Value);
                        if (intTime > 0)
                        {
                            trackpoint.IntervalTime = intTime;
                            trackpoint.Speed        = dist / intTime;
                        }
                        else
                        {
                            //Time is not really used - could probably be empty
                            //The alternative would be to drop the points
                            trackpoint.IntervalTime = 1;
                        }
                    }
                    train.TrackPoints.Add(trackpoint);
                }
                train.TrackPointCount = (short)train.TrackPoints.Count;

                result.Add(train);
            }

            return(result);
        }
コード例 #17
0
 public static IDictionary<IActivity, PointInfo[]> getCommonSpeed(IGPSRoute refRoute, IList<IActivity> activities, bool useActive)
 {
     IDictionary<IActivity, IList<PointInfo[]>> points = new Dictionary<IActivity, IList<PointInfo[]>>();
     points = findSimilarPoints(refRoute, activities, null);
     return getCommonSpeed(points, activities, useActive, null);
 }