private static double? GetGarminHeartRateFromWaypoint(wptType wpt)
 {
     if (wpt.extensions != null && wpt.extensions.Any != null)
       {
     foreach (var element in wpt.extensions.Any)
     {
       if (element.NamespaceURI == garminTrackPointExtensionsURI && element.LocalName == "TrackPointExtension")
       {
     foreach (XmlNode subElement in element.GetElementsByTagName("hr", garminTrackPointExtensionsURI))
     {
       double hr;
       if (double.TryParse(subElement.InnerText, out hr)) return hr;
     }
       }
     }
       }
       return null;
 }
Example #2
0
        public void Export()
        {
            var writerSettings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true, IndentChars = "  " };
              var writer = XmlWriter.Create(OutputStream, writerSettings);
              var xmlSerializer = new XmlSerializer(typeof(gpx11Type));
              var stNs = "urn:uuid:D0EB2ED5-49B6-44e3-B13C-CF15BE7DD7DD";
              var mrNs = "http://www.matstroeng.se/quickroute/map-reading";
              var ns = new XmlSerializerNamespaces();
              ns.Add("st", stNs);
              if(Session.Route.ContainsWaypointAttribute(WaypointAttribute.MapReadingDuration)) ns.Add("mr", mrNs);
              var xml = new XmlDocument();
              var nfi = new NumberFormatInfo();
              nfi.NumberDecimalSeparator = ".";

              var gpx11 = new gpx11Type();
              gpx11.creator = "QuickRoute";
              gpx11.trk = new trkType[] { new trkType() };

              gpx11.extensions = new extensionsType();
              var extensionElements = new List<XmlElement>();
              // TODO: add map-reading elements if exists
              XmlElement activityElement = xml.CreateElement("st", "activity", stNs);
              extensionElements.Add(activityElement);
              XmlElement heartRateTrackElement = xml.CreateElement("st", "heartRateTrack", stNs);
              activityElement.AppendChild(heartRateTrackElement);

              var trksegs = new List<trksegType>();
              foreach (var rs in Session.Route.Segments)
              {
            var wpts = new List<wptType>();
            foreach (var w in rs.Waypoints)
            {
              var wpt = new wptType();
              wpt.eleSpecified = (w.Altitude != null);
              if (wpt.eleSpecified)
              {
            wpt.ele = (decimal)w.Altitude;
              }
              wpt.lon = (decimal)w.LongLat.Longitude;
              wpt.lat = (decimal)w.LongLat.Latitude;
              wpt.time = w.Time.ToUniversalTime(); // use ToUniversalTime for backwards compatibility, QR <= v2.2 used local time internally
              wpt.timeSpecified = true;
              wpts.Add(wpt);

              if (w.HeartRate.HasValue)
              {
            // add heartrate
            var heartRateElement = xml.CreateElement("st", "heartRate", stNs);
            var timeAttribute = xml.CreateAttribute("time");
            timeAttribute.Value = w.Time.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"); // use ToUniversalTime for backwards compatibility, QR <= v2.2 used local time internally
            var bpmAttribute = xml.CreateAttribute("bpm");
            bpmAttribute.Value = w.HeartRate.Value.ToString(nfi);
            heartRateElement.Attributes.Append(timeAttribute);
            heartRateElement.Attributes.Append(bpmAttribute);
            heartRateTrackElement.AppendChild(heartRateElement);
              }
            }
            var trkseg = new trksegType {trkpt = wpts.ToArray()};
            trksegs.Add(trkseg);
              }
              gpx11.trk[0].trkseg = trksegs.ToArray();

              // add laps as GPX st:split
              var splitsElement = xml.CreateElement("st", "splits", stNs);
              // first distances
              foreach (var lap in Session.Laps)
              {
            if (lap.LapType == LapType.Lap)
            {
              var splitElement = xml.CreateElement("st", "split", stNs);
              var distanceAttribute = xml.CreateAttribute("distance");
              distanceAttribute.Value = Session.Route.GetAttributeFromParameterizedLocation(WaypointAttribute.Distance, Session.Route.GetParameterizedLocationFromTime(lap.Time)).Value.ToString(nfi);
              splitElement.Attributes.Append(distanceAttribute);
              splitsElement.AppendChild(splitElement);
            }
              }
              // then times
              foreach (var lap in Session.Laps)
              {
            if (lap.LapType == LapType.Lap)
            {
              var splitElement = xml.CreateElement("st", "split", stNs);
              var timeAttribute = xml.CreateAttribute("time");
              timeAttribute.Value = lap.Time.Subtract(Session.Route.FirstWaypoint.Time).TotalSeconds.ToString(nfi);
              splitElement.Attributes.Append(timeAttribute);
              splitsElement.AppendChild(splitElement);
            }
              }
              if (splitsElement.ChildNodes.Count > 0) activityElement.AppendChild(splitsElement);

              // add laps as GPX waypoint elements
              var lapWaypoints = new List<wptType>();
              foreach (var lap in Session.Laps)
              {
            if (lap.LapType == LapType.Lap)
            {
              var wpt = new wptType();
              wpt.time = lap.Time;
              wpt.timeSpecified = true;
              var qrWaypoint = session.Route.CreateWaypointFromTime(lap.Time);
              wpt.lat = (decimal)qrWaypoint.LongLat.Latitude;
              wpt.lon = (decimal)qrWaypoint.LongLat.Longitude;
              if(qrWaypoint.Altitude.HasValue)
              {
            wpt.ele = (decimal)qrWaypoint.Altitude.Value;
            wpt.eleSpecified = true;
              }
              wpt.name = string.Format(Strings.LapX, lapWaypoints.Count + 1);
              lapWaypoints.Add(wpt);
            }
              }
              if(lapWaypoints.Count > 0) gpx11.wpt = lapWaypoints.ToArray();

              // map reading
              if(Session.Route.ContainsWaypointAttribute(WaypointAttribute.MapReadingDuration))
              {
            var mapReadingsList = Session.Route.GetMapReadingsList();
            for(var i=0; i<mapReadingsList.Count; i+=2)
            {
              var mapReadingElement = xml.CreateElement("mr", "map-reading", mrNs);
              mapReadingElement.SetAttribute("start", mapReadingsList[i].ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
              mapReadingElement.SetAttribute("end", mapReadingsList[i+1].ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
              extensionElements.Add(mapReadingElement);
            }
              }
              gpx11.extensions.Any = extensionElements.ToArray();

              xmlSerializer.Serialize(writer, gpx11, ns);
              writer.Close();
        }