Esempio n. 1
0
        private static void ParseTrack(GPXLib gpx, JsonValue elem, int trackNum)
        {
            Trkseg segment = new Trkseg();

            foreach (JsonValue node in elem["nodes"])
            {
                Wpt wpt = new Wpt
                {
                    Lat           = node["x"],
                    Lon           = node["y"],
                    Ele           = node["z"],
                    EleSpecified  = node.ContainsKey("z") && node["z"] != 0,
                    Sat           = Convert.ToString((int)node["sat_qty"]),
                    Time          = Date.DateTimeFromUnixTimestampSeconds(node["t"]),
                    TimeSpecified = node.ContainsKey("t")
                };

                segment.TrkptList.Add(wpt);
                TrackMinMax(wpt.Lat, wpt.Lon);
            }

            Trk track = new Trk(String.Format("Track {0}", trackNum))
            {
                Number = trackNum.ToString()
            };

            track.TrksegList.Add(segment);

            gpx.TrkList.Add(track);
        }
Esempio n. 2
0
        /// <summary>
        /// Aligns the Trk UniqueDefs whose indices are given in the argument.
        /// The argument.Count must be equal to the number of trks in the Seq, and in order of the trks in the seq's _trks list.
        /// Each alignmentPosition must be a valid UniqueDef index in its trk.
        /// The Seq is normalized at the end of this function by adding rests at the beginnings and ends of trks as necessary.
        /// The seq's msDuration changes automatically.
        /// </summary>
        public void AlignTrkUniqueDefs(List <int> indicesToAlign)
        {
            M.Assert(indicesToAlign.Count == this._trks.Count);
            List <int> newMsPositionsReContainer = new List <int>();
            int        minMsPositionReContainer  = int.MaxValue;

            for (int i = 0; i < _trks.Count; ++i)
            {
                newMsPositionsReContainer.Add(0); // default value
                Trk trk   = _trks[i];
                int index = indicesToAlign[i];
                M.Assert(index >= 0);

                if (index < trk.UniqueDefs.Count)
                {
                    int alignmentMsPositionReFirstUD = 0;
                    for (int j = 0; j < index; ++j)
                    {
                        alignmentMsPositionReFirstUD += trk.UniqueDefs[j].MsDuration;
                    }

                    int newMsPositionReContainer = trk.MsPositionReContainer - alignmentMsPositionReFirstUD;
                    newMsPositionsReContainer[i] = newMsPositionReContainer;
                    minMsPositionReContainer     = (minMsPositionReContainer < newMsPositionReContainer) ? minMsPositionReContainer : newMsPositionReContainer;
                }
            }
            for (int i = 0; i < _trks.Count; ++i)
            {
                Trk trk = _trks[i];
                trk.MsPositionReContainer = newMsPositionsReContainer[i] - minMsPositionReContainer;
            }

            AssertConsistency();
        }
Esempio n. 3
0
        /// <summary>
        /// Shifts each track by adding the corresponding millisecond argument to its MsPositionReContainer attribute.
        /// The argument.Count must be equal to the number of trks in the Seq, and in order of the trks in the seq's _trks list.
        /// The Seq is normalized at the end of this function. Its msDuration changes automatically.
        /// </summary>
        /// <param name="msShifts">The number of milliseconds to shift each trk. (May be negative.)</param>
        public void ShiftTrks(List <int> msShifts)
        {
            M.Assert(msShifts.Count == this._trks.Count);
            for (int i = 0; i < msShifts.Count; ++i)
            {
                Trk trk = _trks[i];
                trk.MsPositionReContainer += msShifts[i];
            }

            AssertConsistency();
        }
Esempio n. 4
0
        /// <summary>
        /// Concatenates seq2 to the caller (seq1). Returns a pointer to the caller.
        /// Both Seqs must be normalized before calling this function.
        /// When this function is called, seq2.AbsMsPosition is the earliest position, relative to seq1, at which it can be concatenated.
        /// When it returns, seq2's Trks will have been concatenated to Seq1, and seq1 is consistent.
        /// If Seq2 is needed after calling this function, then it should be cloned first.
        /// For example:
        /// If seq2.MsPosition==0, it will be concatenated such that there will be at least one trk concatenation without an
        /// intervening rest.
        /// If seq2.MsPosition == seq1.MsDuration, the seqs will be juxtaposed.
        /// If seq2.MsPosition > seq1.MsDuration, the seqs will be concatenated with an intervening rest.
        /// Redundant clef changes are silently removed.
        /// </summary>
        public Seq Concat(Seq seq2)
        {
            #region assertions
            M.Assert(_trks.Count == seq2.Trks.Count);
            M.Assert(this.IsNormalized);
            M.Assert(seq2.IsNormalized);
            AssertChannelConsistency(seq2.MidiChannelPerOutputVoice);
            #endregion

            int nTrks = _trks.Count;

            #region find concatMsPos
            int absConcatMsPos = seq2.AbsMsPosition;
            if (seq2.AbsMsPosition < (AbsMsPosition + MsDuration))
            {
                for (int i = 0; i < nTrks; ++i)
                {
                    Trk trk1 = _trks[i];
                    Trk trk2 = seq2.Trks[i];
                    int earliestAbsConcatPos = trk1.MsPositionReContainer + trk1.EndMsPositionReFirstIUD - trk2.MsPositionReContainer;
                    absConcatMsPos = (earliestAbsConcatPos > absConcatMsPos) ? earliestAbsConcatPos : absConcatMsPos;
                }
            }
            #endregion

            #region concatenation
            for (int i = 0; i < nTrks; ++i)
            {
                Trk trk2 = seq2.Trks[i];
                if (trk2.UniqueDefs.Count > 0)
                {
                    Trk trk1 = _trks[i];
                    int trk1AbsEndMsPosition   = AbsMsPosition + trk1.MsPositionReContainer + trk1.EndMsPositionReFirstIUD;
                    int trk2AbsStartMsPosition = absConcatMsPos + trk2.MsPositionReContainer;
                    if (trk1AbsEndMsPosition < trk2AbsStartMsPosition)
                    {
                        trk1.Add(new MidiRestDef(trk1.EndMsPositionReFirstIUD, trk2AbsStartMsPosition - trk1AbsEndMsPosition));
                    }
                    trk1.AddRange(trk2);
                }
            }
            #endregion

            foreach (Trk trk in Trks)
            {
                trk.AgglomerateRests();
            }

            AssertConsistency();

            return(this);
        }
Esempio n. 5
0
        /// <summary>
        /// trks.Count must be less than or equal to midiChannelIndexPerOutputVoice.Count. (See trks parameter comment.)
        /// </summary>
        /// <param name="absSeqMsPosition">Must be greater than or equal to zero.</param>
        /// <param name="trks">Each Trk must have a constructed UniqueDefs list which is either empty, or contains any
        /// combination of MidiRestDef or MidiChordDef. Each trk.MidiChannel must be unique and present in the
        /// midiChannelIndexPerOutputVoice list. Each trk.MsPositionReContainer must be 0. All trk.UniqueDef.MsPositionReFirstUD
        /// values must be set correctly.
        /// <para>Not all the Seq's channels need to be given an explicit Trk in the trks argument. The seq will be given empty
        /// (default) Trks for the channels that are missing.</para>
        /// </param>
        /// <param name="barlineMsPositionsReSeq">Can be null or empty. All barlineMsPositions must be unique, in ascending order, and less than or equal to the final msDuration of the Seq.</param>
        /// <param name="midiChannelIndexPerOutputVoice">The Seq will contain one trk for each channel in this list.</param>
        public Seq(int absSeqMsPosition, List <Trk> trks, IReadOnlyList <int> midiChannelIndexPerOutputVoice)
        {
            #region conditions
            M.Assert(absSeqMsPosition >= 0);
            for (int i = 0; i < trks.Count - 1; ++i)
            {
                Trk trk = trks[i];
                for (int j = i + 1; j < trks.Count; ++j)
                {
                    M.Assert(trk.MidiChannel != trks[j].MidiChannel);
                }
                bool trkChannelFound = false;
                foreach (int ovChannel in midiChannelIndexPerOutputVoice)
                {
                    if (trk.MidiChannel == ovChannel)
                    {
                        trkChannelFound = true;
                        break;
                    }
                }
                M.Assert(trkChannelFound);
                M.Assert(trk.MsPositionReContainer == 0);
                trk.AssertConsistency();
            }
            #endregion conditions

            _absMsPosition = absSeqMsPosition;

            foreach (int channel in midiChannelIndexPerOutputVoice)
            {
                Trk newTrk = null;
                foreach (Trk trk in trks)
                {
                    if (trk.MidiChannel == channel)
                    {
                        newTrk = trk;
                        break;
                    }
                }
                if (newTrk == null)
                {
                    newTrk = new Trk(channel);
                }
                newTrk.Container = this;
                _trks.Add(newTrk);
            }

            AssertConsistency();
        }
Esempio n. 6
0
        public Gpx Parse(string activity, string workoutId)
        {
            var result = new Gpx
            {
                version = "1.1",
                creator = "https://github.com/tmk-w/Endomondo.Export",
            };

            var lines = activity.Split('\n');

            string[] info = lines[1].Split(';');
            if (info.Length >= 9)
            {
                var metaData = new Metadata
                {
                    time = DateTime.ParseExact(info[6], "yyyy-MM-dd HH:mm:ss UTC", System.Globalization.CultureInfo.InvariantCulture),
                };

                var trk = new Trk
                {
                    name   = $"{Enum.GetName(typeof(Constants.SportType), int.Parse(info[5]))}_{workoutId}",
                    type   = Enum.GetName(typeof(Constants.SportType), int.Parse(info[5])),
                    trkseg = new Trkseg {
                        trkpt = new List <Trkpt>()
                    }
                };

                for (int i = 2; i < lines.Length; i++)
                {
                    string[] values = lines[i].Split(';');
                    if (values.Length >= 9)
                    {
                        trk.trkseg.trkpt.Add(new Trkpt
                        {
                            time = DateTime.ParseExact(values[0], "yyyy-MM-dd HH:mm:ss UTC", System.Globalization.CultureInfo.InvariantCulture),
                            lat  = values[2],
                            lon  = values[3],
                            ele  = values[6],
                        });
                    }
                }

                result.metadata = metaData;
                result.trk      = trk;
            }

            return(result);
        }
Esempio n. 7
0
        /// <summary>
        /// Replaces (or updates) a trk having the same channel in the seq. trk.Container is set to the Seq.
        /// An exception is thrown if the trk to replace is not found.
        /// trk.MsPositionReContainer can have any value, but this function normalizes the seq.
        /// </summary>
        /// <param name="trk"></param>
        public void SetTrk(Trk trk)
        {
            bool found = false;

            for (int i = 0; i < _trks.Count; ++i)
            {
                if (trk.MidiChannel == _trks[i].MidiChannel)
                {
                    trk.Container = this;
                    _trks[i]      = trk;
                    found         = true;
                    break;
                }
            }

            M.Assert(found == true, "Illegal channel");
        }
        private MapPolyline MakePolyline(Trk trk)
        {
            if (trk == null) return null;

            MapPolyline polyline = new MapPolyline();
            polyline.StrokeColor = Colors.Red;
            polyline.StrokeThickness = 2;
            List<BasicGeoposition> pos = new List<BasicGeoposition>();
            BasicGeoposition bpos;

            foreach (TrkPt pt in trk.TrkPts)
            {
                bpos = new BasicGeoposition();
                bpos.Latitude = pt.Latitude;
                bpos.Longitude = pt.Longitude;
                pos.Add(bpos);
            }

            Geopath p = new Geopath(pos);
            polyline.Path = p;

            return polyline;
        }
Esempio n. 9
0
        public GpxReader(string xml)
        {
            if (xml.Equals(""))
            {
                return;
            }
            _gpx.LoadXml(xml);
            if (_gpx.DocumentElement == null || !_gpx.DocumentElement.Name.Equals("gpx"))
            {
                return;
            }
            var gpxNodes = _gpx.GetElementsByTagName("gpx")[0].ChildNodes;

            foreach (XmlNode node in gpxNodes)
            {
                switch (node.Name)
                {
                case "name":
                    Name = node.InnerText;
                    break;

                case "desc":
                    Description = node.InnerText;
                    break;

                case "author":
                    Author = node.InnerText;
                    break;

                case "email":
                    EMail = node.InnerText;
                    break;

                case "time":
                    Time = node.InnerText;
                    break;

                case "keywords":
                    KeyWords = node.InnerText;
                    break;

                case "bounds":
                    Bounds = new GpsBoundary();
                    if (node.Attributes != null)
                    {
                        foreach (XmlAttribute att in node.Attributes)
                        {
                            switch (att.Name)
                            {
                            case "minlat":
                                Bounds.Min.Lat = att.Value;
                                break;

                            case "minlon":
                                Bounds.Min.Lon = att.Value;
                                break;

                            case "maxlat":
                                Bounds.Max.Lat = att.Value;
                                break;

                            case "maxlon":
                                Bounds.Max.Lon = att.Value;
                                break;
                            }
                        }
                    }
                    break;

                case "wpt":
                    var newWayPoint = new Wpt(node);
                    WayPoints.Add(newWayPoint);
                    break;

                case "rte":
                    var newRoute = new Rte(node);
                    Routes.Add(newRoute);
                    break;

                case "trk":
                    var track = new Trk(node);
                    Tracks.Add(track);
                    break;

                case "url":
                    Url = node.InnerText;
                    break;

                case "urlname":
                    UrlName = node.InnerText;
                    break;

                case "topografix:active_point":
                case "topografix:map":
                    break;

                default:
                    Logger.Write("Unhandled data in GPX file, attempting to skip.", LogLevel.Info);
                    break;
                }
            }
        }
Esempio n. 10
0
        public GpxReader(string xml, ISession session)
        {
            _ctx = session;
            if (xml.Equals(""))
            {
                return;
            }
            _gpx.LoadXml(xml);
            if (_gpx.DocumentElement == null || !_gpx.DocumentElement.Name.Equals("gpx"))
            {
                return;
            }
            var gpxNodes = _gpx.GetElementsByTagName("gpx")[0].ChildNodes;

            foreach (XmlNode node in gpxNodes)
            {
                switch (node.Name)
                {
                case "name":
                    Name = node.InnerText;
                    break;

                case "desc":
                    Description = node.InnerText;
                    break;

                case "author":
                    Author = node.InnerText;
                    break;

                case "email":
                    EMail = node.InnerText;
                    break;

                case "time":
                    Time = node.InnerText;
                    break;

                case "keywords":
                    KeyWords = node.InnerText;
                    break;

                case "bounds":
                    Bounds = new GpsBoundary();
                    if (node.Attributes != null)
                    {
                        foreach (XmlAttribute att in node.Attributes)
                        {
                            switch (att.Name)
                            {
                            case "minlat":
                                Bounds.Min.Lat = att.Value;
                                break;

                            case "minlon":
                                Bounds.Min.Lon = att.Value;
                                break;

                            case "maxlat":
                                Bounds.Max.Lat = att.Value;
                                break;

                            case "maxlon":
                                Bounds.Max.Lon = att.Value;
                                break;
                            }
                        }
                    }
                    break;

                case "wpt":
                    var newWayPoint = new Wpt(node);
                    WayPoints.Add(newWayPoint);
                    break;

                case "rte":
                    var newRoute = new Rte(node);
                    Routes.Add(newRoute);
                    break;

                case "trk":
                    var track = new Trk(node);
                    Tracks.Add(track);
                    break;

                case "url":
                    Url = node.InnerText;
                    break;

                case "urlname":
                    UrlName = node.InnerText;
                    break;

                case "topografix:active_point":
                case "topografix:map":
                    break;

                default:
                    session.EventDispatcher.Send(new WarnEvent()
                    {
                        Message = session.Translation.GetTranslation(TranslationString.UnhandledGpxData)
                    });
                    break;
                }
            }
        }