Ejemplo n.º 1
0
        /// <summary>
        /// Exports <see cref="MSHealthAPI.MSHealthActivity"/> instance to GPX <see cref="System.Xml.Linq.XDocument"/>.
        /// </summary>
        /// <param name="activity"><see cref="MSHealthAPI.MSHealthActivity"/> instance to export.</param>
        /// <param name="creator">Creator name for activity.</param>
        /// <param name="name">Name for activity.</param>
        /// <param name="ignoreEmptyMapPoints">Flag to not throw exception if <paramref name="activity"/> has no MapPoints.</param>
        /// <returns><see cref="System.Xml.Linq.XDocument"/> with GPX information.</returns>
        public static XDocument ToGPX(this MSHealthActivity activity, string creator = null, string name = null, bool ignoreEmptyMapPoints = false)
        {
            XDocument  loDocument         = null;
            XElement   loRoot             = null;
            XNamespace loNamespaceDefault = "http://www.topografix.com/GPX/1/1";
            XNamespace loNamespaceXsi     = "http://www.w3.org/2001/XMLSchema-instance";
            XNamespace loNamespaceGpxTpx  = "http://www.garmin.com/xmlschemas/TrackPointExtension/v1";
            XNamespace loNamespaceGpxx    = "http://www.garmin.com/xmlschemas/GpxExtensions/v3";
            XNamespace loNamespaceSchema  = "http://www.topografix.com/GPX/1/1 " +
                                            "http://www.topografix.com/GPX/1/1/gpx.xsd " +
                                            "http://www.garmin.com/xmlschemas/GpxExtensions/v3 " +
                                            "http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd " +
                                            "http://www.garmin.com/xmlschemas/TrackPointExtension/v1 " +
                                            "http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd";
            XElement loMetadata = null;
            XElement loTrack    = null;
            XElement loSegment  = null;
            XElement loPoint    = null;
            string   lsCreator  = creator;
            string   lsName     = name;
            DateTime ldtTime    = DateTime.Now;

            // Validate MSHealthActivity instance
            if (activity != null)
            {
                // Check for MapPoints flag
                if (!ignoreEmptyMapPoints)
                {
                    // Check activity MapPoints
                    if (activity.MapPoints != null &&
                        activity.MapPoints.Any())
                    {
                        // Get valid MapPoints (with Location Latitude and Longitude)
                        IEnumerable <MSHealthMapPoint> loMPs = activity.MapPoints.Where(loMP => loMP.Location != null &&
                                                                                        loMP.Location.Latitude != null &&
                                                                                        loMP.Location.Longitude != null);
                        // No valid MapPoints... throw exception
                        if (loMPs == null ||
                            !loMPs.Any())
                        {
                            throw new ArgumentNullException("MapPoints");
                        }
                    }
                    else
                    {
                        // No MapPoints... throw exception
                        throw new ArgumentNullException("MapPoints");
                    }
                }
                // Validate Activity Properties (Start Time, Creator, Name)
                if (activity.StartTime != null &&
                    activity.StartTime.HasValue)
                {
                    ldtTime = activity.StartTime.Value;
                }
                if (string.IsNullOrEmpty(lsCreator))
                {
                    lsCreator = "MSHealthAPI";
                }
                if (string.IsNullOrEmpty(lsName))
                {
                    lsName = string.Format("{0} {1:yyyy-MM-dd HH:mm:ss}", activity.Type, ldtTime);
                }
                // Initialize GPX (XML Document), root with namespaces
                loRoot = new XElement(loNamespaceDefault + "gpx",
                                      new XAttribute("xmlns", loNamespaceDefault.NamespaceName),
                                      new XAttribute(XNamespace.Xmlns + "xsi", loNamespaceXsi.NamespaceName),
                                      new XAttribute(XNamespace.Xmlns + "gpxtpx", loNamespaceGpxTpx.NamespaceName),
                                      new XAttribute(XNamespace.Xmlns + "gpxx", loNamespaceGpxx.NamespaceName),
                                      new XAttribute(loNamespaceXsi + "schemaLocation", loNamespaceSchema.NamespaceName),
                                      new XAttribute("creator", lsCreator),
                                      new XAttribute("version", "1.1"));
                // Set GPX Metadata information
                loMetadata = new XElement(loNamespaceDefault + "metadata",
                                          new XElement(loNamespaceDefault + "name", lsName),
                                          new XElement(loNamespaceDefault + "time", string.Format("{0:O}", ldtTime.ToUniversalTime())));
                loRoot.Add(loMetadata);
                // Validate Activity MapPoints
                if (activity.MapPoints != null &&
                    activity.MapPoints.Any())
                {
                    // Initialize GPX Track/Segment node
                    loTrack   = new XElement(loNamespaceDefault + "trk");
                    loSegment = new XElement(loNamespaceDefault + "trkseg");
                    List <MSHealthMapPoint> loMapPoints = new List <MSHealthMapPoint>();
                    if (ignoreEmptyMapPoints)
                    {
                        loMapPoints = activity.MapPoints.OrderBy(loMP => loMP.Ordinal).ToList();
                    }
                    else
                    {
                        loMapPoints = activity.MapPoints.Where(loMP => loMP.Location != null &&
                                                               loMP.Location.Latitude != null &&
                                                               loMP.Location.Longitude != null)
                                      .OrderBy(loMP => loMP.Ordinal).ToList();
                    }
                    // Process Activity MapPoints
                    foreach (MSHealthMapPoint loMapPoint in loMapPoints)
                    {
                        // Append GPX TrackPoint
                        loPoint = new XElement(loNamespaceDefault + "trkpt");
                        if (loMapPoint.Location != null)
                        {
                            // TrackPoint Longitude
                            if (loMapPoint.Location.Latitude != null)
                            {
                                loPoint.Add(new XAttribute("lon", ((double)loMapPoint.Location.Longitude / MSHealthGPSPoint.LONGITUDE_FACTOR)));
                            }
                            // TrackPoint Latitude
                            if (loMapPoint.Location.Latitude != null)
                            {
                                loPoint.Add(new XAttribute("lat", ((double)loMapPoint.Location.Latitude / MSHealthGPSPoint.LATITUDE_FACTOR)));
                            }
                            // TrackPoint Elevation
                            if (loMapPoint.Location.ElevationFromMeanSeaLevel != null)
                            {
                                loPoint.Add(new XElement(loNamespaceDefault + "ele", (double)loMapPoint.Location.ElevationFromMeanSeaLevel / MSHealthGPSPoint.ELEVATION_FACTOR));
                            }
                        }
                        // TrackPoint Time
                        if (loMapPoint.SecondsSinceStart != null)
                        {
                            loPoint.Add(new XElement(loNamespaceDefault + "time", ldtTime.AddSeconds(loMapPoint.SecondsSinceStart.Value).ToUniversalTime()));
                        }
                        else
                        {
                            loPoint.Add(new XElement(loNamespaceDefault + "time", ldtTime.ToUniversalTime()));
                        }
                        // TrackPoint Extension HeartRate
                        if (loMapPoint.HeartRate != null)
                        {
                            loPoint.Add(new XElement(loNamespaceDefault + "extensions",
                                                     new XElement(loNamespaceGpxTpx + "TrackPointExtension",
                                                                  new XElement(loNamespaceGpxTpx + "hr", loMapPoint.HeartRate.Value))));
                        }
                        loSegment.Add(loPoint);
                    }
                    loTrack.Add(loSegment);
                    loRoot.Add(loTrack);
                }
                loDocument = new XDocument(new XDeclaration("1.0", "utf-8", null), loRoot);
            }
            // Return GPX (XML Document)
            return(loDocument);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Exports <see cref="MSHealthAPI.MSHealthActivity"/> instance to TCX <see cref="System.Xml.Linq.XDocument"/>.
        /// </summary>
        /// <param name="activity"><see cref="MSHealthAPI.MSHealthActivity"/> instance to export.</param>
        /// <param name="creator">Creator name for activity.</param>
        /// <param name="ignoreEmptyMapPoints">Flag to not throw exception if <paramref name="activity"/> has no MapPoints.</param>
        /// <returns><see cref="System.Xml.Linq.XDocument"/> with TCX information.</returns>
        public static XDocument ToTCX(this MSHealthActivity activity, string creator = null, bool ignoreEmptyMapPoints = false)
        {
            XDocument  loDocument         = null;
            XElement   loRoot             = null;
            XNamespace loNamespaceDefault = "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2";
            XNamespace loNamespaceXsi     = "http://www.w3.org/2001/XMLSchema-instance";
            XNamespace loNamespaceSchema  = "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 " +
                                            "http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd";
            XNamespace loNamespace2       = "http://www.garmin.com/xmlschemas/UserProfile/v2";
            XNamespace loNamespace3       = "http://www.garmin.com/xmlschemas/ActivityExtension/v2";
            XNamespace loNamespace4       = "http://www.garmin.com/xmlschemas/ProfileExtension/v1";
            XNamespace loNamespace5       = "http://www.garmin.com/xmlschemas/ActivityGoals/v1";
            XElement   loActivities       = null;
            XElement   loActivity         = null;
            XElement   loLap              = null;
            XElement   loTrack            = null;
            XElement   loTrackpoint       = null;
            string     lsCreator          = creator;
            DateTime   ldtTime            = DateTime.Now;
            double     ldDistanceInMeters = 0;

            // Validate MSHealthActivity instance
            if (activity != null)
            {
                // Check for MapPoints flag
                if (!ignoreEmptyMapPoints)
                {
                    // Check activity MapPoints
                    if (activity.MapPoints != null &&
                        activity.MapPoints.Any())
                    {
                        // Get valid MapPoints (with Location Latitude and Longitude)
                        IEnumerable <MSHealthMapPoint> loMPs = activity.MapPoints.Where(loMP => loMP.Location != null &&
                                                                                        loMP.Location.Latitude != null &&
                                                                                        loMP.Location.Longitude != null);
                        // No valid MapPoints... throw exception
                        if (loMPs == null ||
                            !loMPs.Any())
                        {
                            throw new ArgumentNullException("MapPoints");
                        }
                    }
                    else
                    {
                        // No MapPoints... throw exception
                        throw new ArgumentNullException("MapPoints");
                    }
                }
                // Validate Activity Properties (Start Time, Creator, Name)
                if (activity.StartTime != null &&
                    activity.StartTime.HasValue)
                {
                    ldtTime = activity.StartTime.Value;
                }
                if (string.IsNullOrEmpty(lsCreator))
                {
                    lsCreator = "MSHealthAPI";
                }
                // Initialize TCX (XML Document), root with namespaces
                loRoot = new XElement(loNamespaceDefault + "TrainingCenterDatabase",
                                      new XAttribute("xmlns", loNamespaceDefault.NamespaceName),
                                      new XAttribute(XNamespace.Xmlns + "xsi", loNamespaceXsi.NamespaceName),
                                      new XAttribute(XNamespace.Xmlns + "ns2", loNamespace2.NamespaceName),
                                      new XAttribute(XNamespace.Xmlns + "ns3", loNamespace3.NamespaceName),
                                      new XAttribute(XNamespace.Xmlns + "ns4", loNamespace4.NamespaceName),
                                      new XAttribute(XNamespace.Xmlns + "ns5", loNamespace5.NamespaceName),
                                      new XAttribute(loNamespaceXsi + "schemaLocation", loNamespaceSchema.NamespaceName),
                                      new XAttribute("creator", lsCreator),
                                      new XAttribute("version", "1.0"));
                // Lap (summary)
                loLap = new XElement(loNamespaceDefault + "Lap",
                                     new XAttribute("StartTime", ldtTime.ToUniversalTime()));
                // Lap duration
                if (activity.Duration != null)
                {
                    loLap.Add(new XElement(loNamespaceDefault + "TotalTimeSeconds",
                                           activity.Duration.Value.TotalSeconds));
                }
                // Lab distance
                if (activity.DistanceSummary != null &&
                    activity.DistanceSummary.TotalDistance != null &&
                    activity.SplitDistance != null)
                {
                    ldDistanceInMeters = activity.DistanceSummary.TotalDistance.Value / activity.SplitDistance.Value;
                    if (activity.SplitDistance.Value == MSHealthActivity.SPLIT_DISTANCE_KILOMETER)
                    {
                        ldDistanceInMeters = ldDistanceInMeters * 1000;
                    }
                    else if (activity.SplitDistance.Value == MSHealthActivity.SPLIT_DISTANCE_MILE)
                    {
                        ldDistanceInMeters = ldDistanceInMeters * 1609.344;
                    }
                    loLap.Add(new XElement(loNamespaceDefault + "DistanceMeters", ldDistanceInMeters));
                }
                // Lap calories
                if (activity.CaloriesBurnedSummary != null &&
                    activity.CaloriesBurnedSummary.TotalCalories != null)
                {
                    loLap.Add(new XElement(loNamespaceDefault + "Calories", activity.CaloriesBurnedSummary.TotalCalories.Value));
                }
                // Lap Heart Rate
                if (activity.HeartRateSummary != null)
                {
                    // Lap Heart Rate Average
                    if (activity.HeartRateSummary.AverageHeartRate != null)
                    {
                        loLap.Add(new XElement(loNamespaceDefault + "AverageHeartRateBpm",
                                               new XElement(loNamespaceDefault + "Value", activity.HeartRateSummary.AverageHeartRate.Value)));
                    }
                    // Lap Heart Rate Maximum
                    if (activity.HeartRateSummary.PeakHeartRate != null)
                    {
                        loLap.Add(new XElement(loNamespaceDefault + "MaximumHeartRateBpm",
                                               new XElement(loNamespaceDefault + "Value", activity.HeartRateSummary.PeakHeartRate.Value)));
                    }
                }
                loLap.Add(new XElement(loNamespaceDefault + "TriggerMethod", "Manual"));
                // Validate Activity MapPoints
                if (activity.MapPoints != null &&
                    activity.MapPoints.Any())
                {
                    // Initialize TCX Track
                    loTrack = new XElement(loNamespaceDefault + "Track");
                    List <MSHealthMapPoint> loMapPoints = new List <MSHealthMapPoint>();
                    if (ignoreEmptyMapPoints)
                    {
                        loMapPoints = activity.MapPoints.OrderBy(loMP => loMP.Ordinal).ToList();
                    }
                    else
                    {
                        loMapPoints = activity.MapPoints.Where(loMP => loMP.Location != null &&
                                                               loMP.Location.Latitude != null &&
                                                               loMP.Location.Longitude != null)
                                      .OrderBy(loMP => loMP.Ordinal).ToList();
                    }
                    // Process Activity MapPoints
                    foreach (MSHealthMapPoint loMapPoint in loMapPoints)
                    {
                        loTrackpoint = new XElement(loNamespaceDefault + "Trackpoint");
                        // TrackPoint Time
                        if (loMapPoint.SecondsSinceStart != null)
                        {
                            loTrackpoint.Add(new XElement(loNamespaceDefault + "Time", ldtTime.AddSeconds(loMapPoint.SecondsSinceStart.Value).ToUniversalTime()));
                        }
                        else
                        {
                            loTrackpoint.Add(new XElement(loNamespaceDefault + "Time", ldtTime.ToUniversalTime()));
                        }
                        // TrackPoint Extension HeartRate
                        if (loMapPoint.HeartRate != null)
                        {
                            loTrackpoint.Add(new XElement(loNamespaceDefault + "HeartRateBpm",
                                                          new XElement(loNamespaceDefault + "Value", loMapPoint.HeartRate.Value)));
                        }
                        // Trackpoint Location
                        if (loMapPoint.Location != null)
                        {
                            // TrackPoint Elevation
                            if (loMapPoint.Location.ElevationFromMeanSeaLevel != null)
                            {
                                loTrackpoint.Add(new XElement(loNamespaceDefault + "AltitudeMeters", loMapPoint.Location.ElevationFromMeanSeaLevel / MSHealthGPSPoint.ELEVATION_FACTOR));
                            }
                            // TrackPoint Latitude/Longitude
                            if (loMapPoint.Location.Latitude != null &&
                                loMapPoint.Location.Latitude != null)
                            {
                                loTrackpoint.Add(new XElement(loNamespaceDefault + "Position",
                                                              new XElement(loNamespaceDefault + "LatitudeDegrees",
                                                                           loMapPoint.Location.Latitude / MSHealthGPSPoint.LATITUDE_FACTOR),
                                                              new XElement(loNamespaceDefault + "LongitudeDegrees",
                                                                           loMapPoint.Location.Longitude / MSHealthGPSPoint.LONGITUDE_FACTOR)));
                            }
                        }
                        // Trackpoint Distance
                        if (loMapPoint.TotalDistance != null)
                        {
                            ldDistanceInMeters = loMapPoint.TotalDistance.Value / activity.SplitDistance.Value;
                            if (activity.SplitDistance.Value == MSHealthActivity.SPLIT_DISTANCE_KILOMETER)
                            {
                                ldDistanceInMeters = ldDistanceInMeters * 1000;
                            }
                            else if (activity.SplitDistance.Value == MSHealthActivity.SPLIT_DISTANCE_MILE)
                            {
                                ldDistanceInMeters = ldDistanceInMeters * 1609.344;
                            }
                            loTrackpoint.Add(new XElement(loNamespaceDefault + "DistanceMeters", ldDistanceInMeters));
                        }
                        else
                        {
                            ldDistanceInMeters = 0;
                            loTrackpoint.Add(new XElement(loNamespaceDefault + "DistanceMeters", ldDistanceInMeters));
                        }
                        loTrack.Add(loTrackpoint);
                    }
                    loLap.Add(loTrack);
                }
                // Activity
                loActivity = new XElement(loNamespaceDefault + "Activity",
                                          new XAttribute("Sport", activity.Type == MSHealthActivityType.Run ? "Running" :
                                                         activity.Type == MSHealthActivityType.Bike ? "Biking" : "Other"),
                                          new XElement(loNamespaceDefault + "Id", ldtTime.ToUniversalTime()),
                                          loLap);
                loActivities = new XElement(loNamespaceDefault + "Activities",
                                            loActivity);
                loRoot.Add(loActivities);
                loDocument = new XDocument(new XDeclaration("1.0", "utf-8", null), loRoot);
            }
            // Return TCX (XML Document)
            return(loDocument);
        }