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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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()); }
/// <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)); } }
/// <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)) :