Beispiel #1
0
        private static void ReadRoute(XmlReader reader, GpxReaderSettings settings, GpxVisitorBase visitor)
        {
            var element = (XElement)XNode.ReadFrom(reader);
            var route   = GpxRoute.Load(element, settings);

            visitor.VisitRoute(route);
        }
Beispiel #2
0
        private static void ReadTrack(XmlReader reader, GpxReaderSettings settings, GpxVisitorBase visitor)
        {
            var element = (XElement)XNode.ReadFrom(reader);
            var track   = GpxTrack.Load(element, settings);

            visitor.VisitTrack(track);
        }
Beispiel #3
0
        private static void ReadMetadata(XmlReader reader, GpxReaderSettings settings, string creator, GpxVisitorBase visitor)
        {
            var element  = (XElement)XNode.ReadFrom(reader);
            var metadata = GpxMetadata.Load(element, settings, creator);

            visitor.VisitMetadata(metadata);
        }
Beispiel #4
0
        private static void ReadWaypoint(XmlReader reader, GpxReaderSettings settings, GpxVisitorBase visitor)
        {
            var element  = (XElement)XNode.ReadFrom(reader);
            var waypoint = GpxWaypoint.Load(element, settings, settings.ExtensionReader.ConvertWaypointExtensionElement);

            visitor.VisitWaypoint(waypoint);
        }
Beispiel #5
0
        public void DifferentVersionShouldBeValid_OptIn()
        {
            const string GpxText = @"
<gpx xmlns='http://www.topografix.com/GPX/1/1' version='1.2' creator='someone' />
";

            Assert.ThrowsAny <XmlException>(() => GpxFile.Parse(GpxText, null));

            var settings = new GpxReaderSettings {
                IgnoreVersionAttribute = true
            };
            var file = GpxFile.Parse(GpxText, settings);

            Assert.Equal("someone", file.Metadata.Creator);
        }
Beispiel #6
0
        public void MissingCreatorShouldFillInDefault_OptIn()
        {
            const string GpxText = @"
<gpx xmlns='http://www.topografix.com/GPX/1/1' version='1.1' />
";

            Assert.ThrowsAny <XmlException>(() => GpxFile.Parse(GpxText, null));

            var settings = new GpxReaderSettings {
                DefaultCreatorIfMissing = "Legacy IHM"
            };
            var file = GpxFile.Parse(GpxText, settings);

            Assert.Equal("Legacy IHM", file.Metadata.Creator);
        }
Beispiel #7
0
        public void BadMetadataCreationTimeShouldBeValid_OptIn()
        {
            const string GpxText = @"
<gpx xmlns='http://www.topografix.com/GPX/1/1' version='1.1' creator='airbreather'>
    <metadata>
        <time>0000-00-00T00:00:00Z</time>
    </metadata>
</gpx>
";

            Assert.ThrowsAny <XmlException>(() => GpxFile.Parse(GpxText, null));

            var settings = new GpxReaderSettings {
                IgnoreBadDateTime = true
            };
            var file = GpxFile.Parse(GpxText, settings);

            Assert.Null(file.Metadata.CreationTimeUtc);
        }
Beispiel #8
0
        public void BadWaypointTimestampShouldBeValid_OptIn()
        {
            const string GpxText = @"
<gpx xmlns='http://www.topografix.com/GPX/1/1' version='1.1' creator='airbreather'>
    <metadata />
    <wpt lat='0.1' lon='2.3'>
        <time>HELLO</time>
    </wpt>
</gpx>
";

            Assert.ThrowsAny <XmlException>(() => GpxFile.Parse(GpxText, null));

            var settings = new GpxReaderSettings {
                IgnoreBadDateTime = true
            };
            var file = GpxFile.Parse(GpxText, settings);

            Assert.Null(file.Waypoints[0].TimestampUtc);
        }
        public void OverlongDataUrisShouldBeAccepted_OptIn(int totalUriLength)
        {
            var sb = new StringBuilder(totalUriLength, totalUriLength);

            sb.Append("data:application/octet-stream;base64,");
            if ((sb.Capacity - sb.Length) % 4 != 0)
            {
                // it wouldn't be valid base64, so try again.
                sb.Clear();
                sb.Append("data:text/plain;charset=US-ASCII;foo=bar;x=y,");
            }

            sb.Append('A', sb.Capacity - sb.Length);

            string uriText = sb.ToString();

            Debug.Assert(uriText.Length == totalUriLength);

            string gpxText  = $@"
<gpx xmlns='http://www.topografix.com/GPX/1/1' version='1.1' creator='airbreather'>
    <metadata>
        <link href='{uriText}' />
    </metadata>
</gpx>
";
            var    settings = new GpxReaderSettings {
                BuildWebLinksForVeryLongUriValues = true
            };
            var file = GpxFile.Parse(gpxText, settings);

            Assert.Equal(uriText, file.Metadata.Links[0].HrefString);

            // don't assert this: we *want* it to be non-null, and a later version of .NET Core may
            // or may not relax this restriction (dotnet/runtime#1857).
            ////Assert.Null(file.Metadata.Links[0].Href);

            string text = file.BuildString(null);

            Assert.Contains(uriText, text);
        }
Beispiel #10
0
        public void TimestampsShouldBeInterpretedInGivenTimeZone()
        {
            const string GpxText       = @"
<gpx xmlns='http://www.topografix.com/GPX/1/1' version='1.1' creator='airbreather'>
    <metadata>
        <time>1234-05-06T07:08:09</time>
    </metadata>
    <wpt lat='0.1' lon='2.3'>
        <time>5432-10-10T11:22:33</time>
    </wpt>
</gpx>
";
            var          inputTimeZone = TimeZoneInfo.CreateCustomTimeZone("meh", TimeSpan.FromHours(3.5), "meh", "meh");
            var          settings      = new GpxReaderSettings {
                TimeZoneInfo = inputTimeZone
            };
            var file = GpxFile.Parse(GpxText, settings);

            // we told it that our times are in a time zone that's at +3.5 hours from UTC, and the
            // data is stored UTC, so we should see -3.5 from what's written.
            Assert.Equal(new DateTime(1234, 05, 06, 03, 38, 09), file.Metadata.CreationTimeUtc.GetValueOrDefault());
            Assert.Equal(new DateTime(5432, 10, 10, 07, 52, 33), file.Waypoints[0].TimestampUtc.GetValueOrDefault());
        }
Beispiel #11
0
        /// <summary>
        /// Processes a GPX file, invoking callbacks on a <see cref="GpxVisitorBase"/> instance as
        /// elements are observed.
        /// </summary>
        /// <param name="reader">
        /// The <see cref="XmlReader"/> to read from.
        /// </param>
        /// <param name="settings">
        /// The <see cref="GpxReaderSettings"/> instance to use to control how GPX instances get
        /// read in, or <c>null</c> to use a general-purpose default.
        /// </param>
        /// <param name="visitor">
        /// The <see cref="GpxVisitorBase"/> instance that will receive callbacks.
        /// </param>
        /// <remarks>
        /// This method is the "core" reading method; everything else builds off of this.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// Thrown when <paramref name="reader"/> or <paramref name="visitor"/> is
        /// <see langword="null"/>.
        /// </exception>
        /// <exception cref="XmlException">
        /// Thrown when <paramref name="reader"/> does not specify a valid GPX file (i.e., cases
        /// where XSD schema validation would fail, and/or some values are <b>well</b> outside of
        /// the slightly stricter, but still completely reasonable, limits imposed by the idiomatic
        /// .NET data types above and beyond the XSD limits).
        /// </exception>
        public static void Read(XmlReader reader, GpxReaderSettings settings, GpxVisitorBase visitor)
        {
            if (reader is null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            if (visitor is null)
            {
                throw new ArgumentNullException(nameof(visitor));
            }

            settings = settings ?? new GpxReaderSettings();
            while (reader.ReadToFollowing("gpx", Helpers.GpxNamespace))
            {
                string version = null;
                string creator = settings.DefaultCreatorIfMissing;
                for (bool hasAttribute = reader.MoveToFirstAttribute(); hasAttribute; hasAttribute = reader.MoveToNextAttribute())
                {
                    switch (reader.Name)
                    {
                    case "version":
                        version = reader.Value;
                        break;

                    case "creator":
                        creator = reader.Value;
                        break;
                    }
                }

                if (version != "1.1" && !settings.IgnoreVersionAttribute)
                {
                    throw new XmlException("'version' must be '1.1'");
                }

                if (creator is null)
                {
                    throw new XmlException("'creator' must be specified");
                }

                if (!ReadTo(reader, XmlNodeType.Element, XmlNodeType.EndElement))
                {
                    visitor.VisitMetadata(new GpxMetadata(creator));
                    break;
                }

                bool expectingMetadata   = true;
                bool expectingExtensions = true;
                do
                {
                    if (expectingMetadata)
                    {
                        expectingMetadata = false;
                        if (reader.Name == "metadata")
                        {
                            ReadMetadata(reader, settings, creator, visitor);
                        }
                        else
                        {
                            visitor.VisitMetadata(new GpxMetadata(creator));
                        }
                    }

                    switch (reader.Name)
                    {
                    // ideally, it should all be in this order, since the XSD validation
                    // would fail otherwise, but whatever.
                    case "wpt":
                        ReadWaypoint(reader, settings, visitor);
                        break;

                    case "rte":
                        ReadRoute(reader, settings, visitor);
                        break;

                    case "trk":
                        ReadTrack(reader, settings, visitor);
                        break;

                    case "extensions" when expectingExtensions:
                        expectingExtensions = false;
                        var    extensionElement = (XElement)XNode.ReadFrom(reader);
                        object extensions       = settings.ExtensionReader.ConvertGpxExtensionElement(extensionElement.Elements());
                        if (!(extensions is null))
                        {
                            visitor.VisitExtensions(extensions);
                        }

                        break;
                    }
                }while (ReadTo(reader, XmlNodeType.Element, XmlNodeType.EndElement));
            }
        }
Beispiel #12
0
        /// <summary>
        /// Reads in NTS <see cref="Feature"/>s and GPX metadata from an <see cref="XmlReader"/>.
        /// </summary>
        /// <param name="reader">
        /// The <see cref="XmlReader"/> to read from.
        /// </param>
        /// <param name="settings">
        /// The <see cref="GpxReaderSettings"/> instance to use to control how GPX instances get
        /// read in, or <c>null</c> to use a general-purpose default.
        /// </param>
        /// <param name="geometryFactory">
        /// The <see cref="IGeometryFactory"/> instance to use when creating the individual
        /// <see cref="Feature.Geometry"/> elements.
        /// </param>
        /// <returns>
        /// The <see cref="Feature"/> instances that represent the top-level GPX data elements, as
        /// well as the <see cref="GpxMetadata"/> for the GPX file and the top-level extension
        /// content from the file.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// Thrown when <paramref name="reader"/> or <paramref name="geometryFactory"/> is
        /// <see langword="null"/>.
        /// </exception>
        /// <exception cref="XmlException">
        /// Thrown when <paramref name="reader"/> does not specify a valid GPX file (i.e., cases
        /// where XSD schema validation would fail, and/or some values are <b>well</b> outside of
        /// the slightly stricter, but still completely reasonable, limits imposed by the idiomatic
        /// .NET data types above and beyond the XSD limits).
        /// </exception>
        public static (GpxMetadata metadata, Feature[] features, object extensions) ReadFeatures(XmlReader reader, GpxReaderSettings settings, IGeometryFactory geometryFactory)
        {
            if (reader is null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            if (geometryFactory is null)
            {
                throw new ArgumentNullException(nameof(geometryFactory));
            }

            var visitor = new NetTopologySuiteFeatureBuilderGpxVisitor(geometryFactory);

            Read(reader, settings, visitor);
            return(visitor.Terminate());
        }
 internal ImmutableGpxWaypointTable(IEnumerable <XElement> elements, GpxReaderSettings settings, Func <IEnumerable <XElement>, object> extensionCallback)
     : this(elements is null ? throw new ArgumentNullException(nameof(elements)) :