如何使用python提取.gpx数据

如何使用python提取.gpx数据,python,perl,extract,gpx,Python,Perl,Extract,Gpx,我是一名新的linux/python用户,拥有.gpx文件(由GPS跟踪软件生成的输出文件),需要将值提取到csv/txt中,以便在GIS程序中使用。我已经在我开始的python书籍、本网站和在线中查找了字符串和切片等。我使用了一个.gpx到.txt的转换器,可以将经度和纬度提取到一个文本文件中。我需要提取高程数据。该文件顶部有六行文本,我只知道如何在emacs中打开该文件(除了在网站上上载),这是从第7行开始的文件 最理想的情况是,我想知道如何通过python(或Perl)将所有值提取到csv

我是一名新的linux/python用户,拥有.gpx文件(由GPS跟踪软件生成的输出文件),需要将值提取到csv/txt中,以便在GIS程序中使用。我已经在我开始的python书籍、本网站和在线中查找了字符串和切片等。我使用了一个.gpx到.txt的转换器,可以将经度和纬度提取到一个文本文件中。我需要提取高程数据。该文件顶部有六行文本,我只知道如何在emacs中打开该文件(除了在网站上上载),这是从第7行开始的文件

最理想的情况是,我想知道如何通过python(或Perl)将所有值提取到csv或txt文件中。如果有人知道一个网站教程或脚本样本,将不胜感激

<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>

2012-06-13T01:51:08Z
赛道2012-06-12 19:51
1403
2012-06-13T01:53:44Z
34
1410.9000244140625
2012-06-13T01:57:10Z
3.75
13
293.20001220703125
1406.5
2012-06-13T02:02:24Z
12
1398.9000244140625
2012-06-13T02:54:55Z
10
1414.9000244140625
2012-06-13T02:56:06Z
7
1410.9000244140625
2012-06-13T02:57:27Z
3.288236618041992
21
196.1999969482422
1421.699951171875
2012-06-13T02:57:30Z
3
17
192.89999389648438
1433
2012-06-13T02:58:46Z
4.5
18
32.400001525878906
1430.199951171875
2012-06-13T02:58:50Z
4.5
11
29.299999237060547
1430.4000244140625
2012-06-13T02:58:52Z
4.5
8
28.600000381469727
1418.199951171875
2012-06-13T03:00:08Z
,因此使用类似或包含的拟合模块来解析数据,然后使用python输出到CSV

涵盖这些概念的教程:


我还发现了一个名为的python GPX解析库,它可能为GPX文件中包含的数据提供了一个更高级别的接口。

因为Martijn发布了一个python答案,并说Perl将转向行噪声,我觉得也需要一个Perl答案

在Perl模块目录中,有一个名为的模块。正如Martijn已经说过的,GPX是一种XML格式。但幸运的是,有人已经将它制作成一个模块,为我们处理解析。我们所要做的就是加载那个模块

有几个模块可用于CSV处理,但此XML文件中的数据相当简单,因此我们并不真正需要。我们可以通过内置功能自行完成

请考虑下面的脚本。我马上解释

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;
  • 现在后缀有点棘手。正如我们刚才看到的,hashref中有8个键。不幸的是,有些人有时会失踪。因为我们有
    使用警告
    ,如果我们试图访问其中一个缺少的值,就会收到警告。我们必须创建这些键并在其中放入一个空字符串
    '

    foreach
    for
    在Perl中是完全可互换的,它们也可以在单个表达式后面的后缀语法中使用。我们使用
    qw
    -操作符创建
    for
    将迭代的列表。是被引用的单词的缩写,它的作用就是:返回一个字符串列表,但被引用。我们也可以说
    ('time','lat','long'…)

    在表达式中,我们访问
    $wp
    的每个键
    $\uu0
    是循环变量。在第一次迭代中,它将保存“time”,然后保存“lat”,以此类推。由于
    $wp
    是一个hashref,我们需要
    ->
    来访问它的键。花括号表明这是一个hashref。仅当hash ref元素不是真值时,才为其赋值

  • 现在,如果有一个时间值(如果没有设置日期,我们刚才分配的空字符串被视为“没有”),我们将用一个正确的日期替换unix时间戳。帮助我们做到这一点。from_epoch方法获取unix时间戳作为参数。它返回一个
    DateTime
    对象,我们可以直接使用它调用
    iso8601
    函数

    这就是所谓的链接。有些模块可以做到这一点。它类似于jQuery的JavaScript对象的功能。hashref中的unix时间戳将替换为
    DateTime
    操作的结果

  • 现在我们再次将
    打印到文件句柄。用于在值之间放置逗号。我们还在结尾处又加了一条新线
  • 完成循环后,我们将关闭文件句柄
  • 现在我们完成了!:) 总而言之,我想说这很简单,也很可读,不是吗?我试图让它成为一个健康的混合体,将过于冗长的语法与Perl风格结合起来。

    您可以安装GPXpy

    sudo pip install gpxpy
    
    然后只需使用库:

    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:' 
    
    有关更多信息:


    关于

    每次尝试这样做时,我都会在互联网上搜索解决方案,最后编写自己的正则表达式解析器

    重新导入
    将numpy作为np导入
    GPXfile='午餐\'u Walk.gpx'
    数据=打开(GPXfile).read()
    lat=np.array(re.findall(r'lat=“([^”]+)”,数据),dtype=float)
    lon=np.array(re.findall(r'lon=“([^”]+)”,数据),dtype=float)
    
    时间=re.findall(r'([^\n我将尝试一下。有人还向我建议,Perl可能是提取这些内容的一种方法。由于我对两者都是新手,我将首先看一下您提到的教程。谢谢您,Martijn!Perl同样适合这项任务;有Perl XML解析器和CSV库,就像python一样。不过,您可能会发现python更容易理解earn;在我个人看来,Perl太容易退化为行噪声。谢谢你的脚本!我去了CPAN,查看了@readme并发现了错误。Perl Makefile.PL命令导致:可选ExtUtils::MakeMaker::Coverage not available参数“6.57_05”在数字ge中不是数字(>=)在Makefile.PL第34行。检查工具包是否完整…看起来不错警告:未找到必备的DateTime::Format::ISO8601 0。警告:未找到必备的HTML::Entities 0。警告:未找到必备的XML::Descent 1.01。正在为Ge编写Makefile
    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:' 
    
    array([['51.504613', '-0.141894', '2020-12-26T12:43:14Z'],
           ['51.504624', '-0.141901', '2020-12-26T13:10:26Z'],
           ['51.504633', '-0.141906', '2020-12-26T13:10:28Z'],
           ...)