I will be grateful i someone tells me whether there's a way to import a GPX file into a C# datatable. I googled it many times but in vain.
2 Answers
One way to approach this would be to deserialise the XML into an object that you could then navigate and use as you wish.
Using the XML data generated from a Garmin Oregon 400T as an example:
<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" creator="Oregon 400t" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="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">
<metadata>
<link href="http://www.garmin.com">
<text>Garmin International</text>
</link>
<time>2009-10-17T22:58:43Z</time>
</metadata>
<trk>
<name>Example GPX Document</name>
<trkseg>
<trkpt lat="47.644548" lon="-122.326897">
<ele>4.46</ele>
<time>2009-10-17T18:37:26Z</time>
</trkpt>
<trkpt lat="47.644548" lon="-122.326897">
<ele>4.94</ele>
<time>2009-10-17T18:37:31Z</time>
</trkpt>
<trkpt lat="47.644548" lon="-122.326897">
<ele>6.87</ele>
<time>2009-10-17T18:37:34Z</time>
</trkpt>
</trkseg>
</trk>
</gpx>
You could create a few custom classes that could be used for deserialisation of the XML:
[Serializable()]
[System.Xml.Serialization.XmlRoot("gpx")]
public class gpx {
[System.Xml.Serialization.XmlElement("metadata")]
public Metadata mData { get; set; }
[System.Xml.Serialization.XmlElement("trk")]
public TrackCollection tCollection { get; set; }
}
[Serializable()]
public class Metadata {
/// Fill in metadata elements here
}
[Serializable()]
public class TrackCollection {
[System.Xml.Serialization.XmlElement("name")]
public string name { get; set; }
[XmlArray("trkseg")]
[XmlArrayItem("trkpt", typeof(TrackPart))]
public TrackPart[] tPart { get; set; }
}
[Serializable()]
public class TrackPart {
[System.Xml.Serialization.XmlElementAttribute("lat")]
public double lattitude { get; set; }
[System.Xml.Serialization.XmlElementAttribute("lon")]
public double longitude { get; set; }
[System.Xml.Serialization.XmlElement("ele")]
public int elapsed { get; set; }
[System.Xml.Serialization.XmlElement("time")]
public DateTime dateTime { get; set; }
}
I haven't double checked this example so please use it with caution. You could alternatively make use of the .NET XML Reader libraries and manually set each of the object properties.
You can also read more about deserialisation of XML here and here.
Then it is just a case of using your newly created object to populate your DataTable
. It's up you how you populate your DataTable
, but you could for example do:
gpx myObject = deserialseGPXFile(); // example
DataTable table = new DataTable();
table.Columns.Add("lat", typeof(double));
table.Columns.Add("lon", typeof(double));
foreach (TrackPart tPart in myObject.TrackCollection)
{
table.Rows.Add(tPart.lattitude, tPart.longitude);
}
-
Thanks, but i still don't understand how to populate a datatable using the extracted data. – geocoder Jun 19 '16 at 19:00
-
-
-
I'm afraid that you will have to be more specific, code samples would help as well. – Jake Jun 19 '16 at 20:36
-
`gpx myObject = deserialseGPXFile();` the name 'deserialseGPXFile' does not exist in the current context – geocoder Jun 19 '16 at 21:32
-
@geocoder `deserialiseGPXFile()` was an example of how to call a method (http://www.tutorialspoint.com/csharp/csharp_methods.htm). For example, you could to write the code for a method called `deserialiseGPXFile` that would return a `gpx` object. More information on classes and objects here: http://www.tutorialspoint.com/csharp/csharp_classes.htm – Jake Jun 20 '16 at 07:11
-
Thank you so much :) I used XPath to decode the gpx file and get the needed information. thanks again – geocoder Jun 22 '16 at 03:23
-
@geocoder Yes XPath is another way of doing things, glad it all worked out! – Jake Jun 22 '16 at 05:33
this function will help you. you can modify code according to project need.
internal static DataTable ReadGpxFile(string gpxfile)
{
AFolderFiles.AFolderFilesPermission.AddFolderSecurity(gpxfile);
DataTable table = new DataTable("gpxfile");
table.Columns.Add("ident", typeof(string));
table.Columns.Add("lat", typeof(string));
table.Columns.Add("long", typeof(string));
table.Columns.Add("time", typeof(string));
XmlDocument gpxDoc = new XmlDocument();
gpxDoc.Load(gpxfile);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(gpxDoc.NameTable);
nsmgr.AddNamespace("x", "http://www.topografix.com/GPX/1/1");
XmlNodeList nl = gpxDoc.SelectNodes("//x:trkpt", nsmgr);
foreach (XmlElement xelement in nl)
{
DataRow dataRow = table.NewRow();
dataRow[0] = string.IsNullOrEmpty(xelement.GetAttribute("ident")) == true ? "GPXFILE" : xelement.GetAttribute("ident");
dataRow[1] = xelement.GetAttribute("lat");
dataRow[2] = xelement.GetAttribute("lon");
dataRow[3] = xelement.GetAttribute("time");
table.Rows.Add(dataRow);
}
return table;
}

- 1
- 1