How to extract .gpx data using python

I am a new linux / python user and have .gpx files (output files created from GPS tracking software) and you need to extract the values ​​in csv / txt for use in the GIS program. I was looking for strings and slices, etc. In my python starter book, on this website and on the web. I used the .gpx to .txt converter and can pull the longitude and latitude to a text file. I need to extract height data. The file has six lines of text at the top, and I know how to open this file in emacs (other than uploading to the website). Here is the file starting with line 7.

Optimally, I would like to know how to extract all values ​​through python (or Perl) into a csv or txt file. If anyone knows a website tutorial or sample script, this will be appreciated.

<metadata> <time>2012-06-13T01:51:08Z</time> </metadata> <trk> <name>Track 2012-06-12 19:51</name> <trkseg> <trkpt lat="43.49670697" lon="-112.03380961"> <ele>1403.0</ele> <time>2012-06-13T01:53:44Z</time> <extensions> <ogt10:accuracy>34.0</ogt10:accuracy></extensions> </trkpt> <trkpt lat="43.49796612" lon="-112.03970968"> <ele>1410.9000244140625</ele> <time>2012-06-13T01:57:10Z</time> <extensions> <gpx10:speed>3.75</gpx10:speed> <ogt10:accuracy>13.0</ogt10:accuracy> <gpx10:course>293.20001220703125</gpx10:course></extensions> </trkpt> <trkpt lat="43.49450857" lon="-112.04477274"> <ele>1406.5</ele> <time>2012-06-13T02:02:24Z</time> <extensions> <ogt10:accuracy>12.0</ogt10:accuracy></extensions> </trkpt> </trkseg> <trkseg> <trkpt lat="43.49451057" lon="-112.04480354"> <ele>1398.9000244140625</ele> <time>2012-06-13T02:54:55Z</time> <extensions> <ogt10:accuracy>10.0</ogt10:accuracy></extensions> </trkpt> <trkpt lat="43.49464813" lon="-112.04472215"> <ele>1414.9000244140625</ele> <time>2012-06-13T02:56:06Z</time> <extensions> <ogt10:accuracy>7.0</ogt10:accuracy></extensions> </trkpt> <trkpt lat="43.49432573" lon="-112.04489684"> <ele>1410.9000244140625</ele> <time>2012-06-13T02:57:27Z</time> <extensions> <gpx10:speed>3.288236618041992</gpx10:speed> <ogt10:accuracy>21.0</ogt10:accuracy> <gpx10:course>196.1999969482422</gpx10:course></extensions> </trkpt> <trkpt lat="43.49397445" lon="-112.04505216"> <ele>1421.699951171875</ele> <time>2012-06-13T02:57:30Z</time> <extensions> <gpx10:speed>3.0</gpx10:speed> <ogt10:accuracy>17.0</ogt10:accuracy> <gpx10:course>192.89999389648438</gpx10:course></extensions> </trkpt> <trkpt lat="43.49428702" lon="-112.04265923"> <ele>1433.0</ele> <time>2012-06-13T02:58:46Z</time> <extensions> <gpx10:speed>4.5</gpx10:speed> <ogt10:accuracy>18.0</ogt10:accuracy> <gpx10:course>32.400001525878906</gpx10:course></extensions> </trkpt> <trkpt lat="43.49444603" lon="-112.04263691"> <ele>1430.199951171875</ele> <time>2012-06-13T02:58:50Z</time> <extensions> <gpx10:speed>4.5</gpx10:speed> <ogt10:accuracy>11.0</ogt10:accuracy> <gpx10:course>29.299999237060547</gpx10:course></extensions> </trkpt> <trkpt lat="43.49456961" lon="-112.04260058"> <ele>1430.4000244140625</ele> <time>2012-06-13T02:58:52Z</time> <extensions> <gpx10:speed>4.5</gpx10:speed> <ogt10:accuracy>8.0</ogt10:accuracy> <gpx10:course>28.600000381469727</gpx10:course></extensions> </trkpt> <trkpt lat="43.49570131" lon="-112.04001132"> <ele>1418.199951171875</ele> <time>2012-06-13T03:00:08Z</time> <extensions> 
+6
source share
3 answers

GPX is an XML format , so use a suitable module like lxml or the included ElementTree XML API for data analysis, then output to CSV using python csv .

Textbooks covering these concepts:

I also found a python GPX parsing library called gpxpy which possibly gives a higher level interface for the data contained in GPX files.

+7
source

Since Martijn posted a response in Python and said that Perl would address linear noise, I felt the need for a response to Perl.

In CPAN , in the Perl modules directory, there is a module called Geo :: Gpx . As Martijn already said, GPX is an XML format. But, fortunately, someone has already turned it into a module that processes parsing for us. All we need to do is download this module.

Several modules are available for CSV processing, but the data in this XML file is quite simple, so we really don't need it. We can do it ourselves with built-in functionality.

Pay attention to the following script. I will give an explanation in a minute.

 use strict; use warnings; use Geo::Gpx; use DateTime; # Open the GPX file open my $fh_in, '<', 'fells_loop.gpx'; # Parse GPX my $gpx = Geo::Gpx->new( input => $fh_in ); # Close the GPX file close $fh_in; # Open an output file open my $fh_out, '>', 'fells_loop.csv'; # Print the header line to the file print $fh_out "time,lat,lon,ele,name,sym,type,desc\n"; # The waypoints-method of the GEO::GPX-Object returns an array-ref # which we can iterate in a foreach loop foreach my $wp ( @{ $gpx->waypoints() } ) { # Some fields seem to be optional so they are missing in the hash. # We have to add an empty string by iterating over all the possible # hash keys to put '' in them. $wp->{$_} ||= '' for qw( time lat lon ele name sym type desc ); # The time is a unix timestamp, which is hard to read. # We can make it an ISO8601 date with the DateTime module. # We only do it if there already is a time, though. if ($wp->{'time'}) { $wp->{'time'} = DateTime->from_epoch( epoch => $wp->{'time'} ) ->iso8601(); } # Join the fields with a comma and print them to the output file print $fh_out join(',', ( $wp->{'time'}, $wp->{'lat'}, $wp->{'lon'}, $wp->{'ele'}, $wp->{'name'}, $wp->{'sym'}, $wp->{'type'}, $wp->{'desc'}, )), "\n"; # Add a newline at the end } # Close the output file close $fh_out; 

Let's do it step by step:

  • use strict and use warnings apply rules, such as declaring variables, and talk about the most common errors that are most difficult to find.
  • use Geo::Gpx and use DateTime are the modules we use. Geo::Gpx will handle the parsing for us. We need a DateTime to make unix timestamps in a matter of date and time.
  • The open function opens a file. $fh_in is a variable containing a file descriptor. The GPX file we want to read is fells_loop.gpx , which I took out a loan from topografix.com . You can find more information on open at perlopentut .
  • We create a new Geo::Gpx object named $gpx and use our $fh_in file descriptor to tell it where to read the XML data. new method is provided by all Perl modules that have an object-oriented interface.
  • close closes the file descriptor.
  • The following open has > to tell Perl what we want to write to this file descriptor.
  • We print to the file descriptor, setting it as the first argument to print . Note that there is no comma after the file descriptor. \n is a newline character.
  • foreach loop accepts the return value of the waypoints method of the Geo::Gpx . This value is an array reference. Think of it as an array that contains arrays (see perlref for more information on links). In each iteration of the loop, the next element of this ref array (which is a waypoint in the GPX data) will be placed in $wp . If printed with Data::Dumper , it looks like this:

     $VAR1 = { 'ele' => '64.008000', 'lat' => '42.455956', 'time' => 991452424, 'name' => 'SOAPBOX', 'sym' => 'Cemetery', 'desc' => 'Soap Box Derby Track', 'lon' => '-71.107483', 'type' => 'Intersection' }; 
  • The for postfix is ​​now a little more complicated. As we just saw, hashref has 8 keys. Unfortunately, some of them are sometimes missing. Since we have use warnings , we will get a warning if we try to access one of these missing values. We must create these keys and put an empty string there. ''

    foreach and for completely interchangeable in Perl, and both of them can also be used in postfix syntax with a single expression. We use the qw operator to create a list that for will iterate over. qw not suitable for quoted words , and it does just that: it returns a list of lines in it, but is quoted. We could also say ('time', 'lat', 'long'... ) .

    In the expression, we get access to each key $wp . $_ is a loop variable. At the first iteration, it will contain "time", then "lat", etc. Since $wp is hashref, we need a -> to access them. Curly braces say it hashref. The ||= operator assigns a value to our ref hash element only if it is not a true value.

  • Now, if there is a time value (the empty line that we just assigned, if the date has not been set, is considered β€œno”), we replace the unix timestamp with the corresponding date. DateTime helps us do this. The from_epoch method takes a unix timestamp as an argument. It returns a DateTime object that we can directly use to call the iso8601 function on it.

    This is called a chain. Some modules can do this. This is similar to what jQuery JavaScript objects do. The unix timestamp in our hashref is replaced with the result of the DateTime operation.

  • Now we print will add our file descriptor again. join used to put commas between values. We also added a new line at the end.
  • As soon as we finish the loop, we close the file.
  • Now everything is ready! :)

In general, I would say that it is quite simple and also quite readable, right? I tried to make it a healthy mix of overly detailed syntax with _Perl_ish flavor.

+6
source

You can install GPXpy

 sudo pip install gpxpy 

Then just use the library:

 import gpxpy import gpxpy.gpx gpx_file = open('input_file.gpx', 'r') gpx = gpxpy.parse(gpx_file) \ for track in gpx.tracks: for segment in track.segments: for point in segment.points: print 'Point at ({0},{1}) -> {2}'.format(point.latitude, point.longitude, point.elevation) for waypoint in gpx.waypoints: print 'waypoint {0} -> ({1},{2})'.format(waypoint.name, waypoint.latitude, waypoint.longitude) for route in gpx.routes: print 'Route:' 

For more information: https://pypi.python.org/pypi/gpxpy

Hi

+3
source

Source: https://habr.com/ru/post/918500/


All Articles