12

私は新しい linux/python ユーザーで、.gpx ファイル (GPS 追跡ソフトウェアから作成された出力ファイル) を持っており、GIS プログラムで使用するために csv/txt に値を抽出する必要があります。私は、最初のpythonの本、このWebサイト、およびオンラインで、文字列やスライスなどを調べました。.gpx から .txt へのコンバーターを使用して、経度と緯度をテキスト ファイルに取り出すことができます。標高データを抽出する必要があります。ファイルの上部には 6 行のテキストがあり、このファイルを emacs で開く方法しか知りません (Web サイトへのアップロードは別として)。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>
4

5 に答える 5

14

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

詳細情報: https://pypi.python.org/pypi/gpxpy

よろしく

于 2016-06-18T20:20:17.590 に答える
9

GPX は XML 形式なので、 lxmlなどの適切なモジュールまたは付属のElementTree XML APIを使用してデータを解析し、pythoncsvモジュールを使用して CSV に出力します。

これらの概念をカバーするチュートリアル:

また、 gpxpyという名前の Python GPX 解析ライブラリも見つけました。これは、おそらく GPX ファイルに含まれるデータへのより高いレベルのインターフェイスを提供します。

于 2012-06-19T16:54:23.967 に答える
8

Martijn が Python の回答を投稿し、Perl はライン ノイズに変わると言ったので、Perl の回答も必要だと感じました。

Perl モジュール ディレクトリであるCPANには、 Geo::Gpxというモジュールがあります。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;

これを段階的に見てみましょう:

  • use strict変数の宣言などのルールをuse warnings適用し、最も見つけにくい一般的な間違いを教えてくれます。
  • use Geo::Gpxuse DateTimeは私たちが使用するモジュールです。Geo::Gpxが解析を処理します。DateTimeUNIX タイムスタンプを読み取り可能な日付と時刻にする必要があります。
  • 関数はopenファイルを開きます。$fh_inファイルハンドルを保持する変数です。読み込みたいGPXファイルはfels_loop.gpxで、これはtopografix.comから自由に借りてきました。詳細についてopenperlopentutを参照してください。
  • という新しいGeo::Gpxオブジェクトを作成し、$gpxファイルハンドルを使用し$fh_inて XML データの読み取り元を指定します。-method は、newオブジェクト指向インターフェースを持つすべての Perl モジュールによって提供されます。
  • closeファイルハンドルを閉じます。
  • openは、>このファイルハンドルに書き込みたいことを Perl に伝えるためのものです。
  • printprintの最初の引数としてファイルハンドルを指定します。ファイルハンドルの後にコンマがないことに注意してください。は改行文字です。\n
  • foreachループは、オブジェクトのwaypoints-method の戻り値を取ります。Geo::Gpxこの値は配列参照です。これは、配列を保持する配列と考えてください (参照について詳しく知りたい場合は、 perlrefを参照してください)。ループの各反復で、その配列 ref の次の要素 (GPX データのウェイポイントを表す) が に入れられ$wpます。それを印刷するとData::Dumper、次のようになります。

    $VAR1 = {
          'ele' => '64.008000',
          'lat' => '42.455956',
          'time' => 991452424,
          'name' => 'SOAPBOX',
          'sym' => 'Cemetery',
          'desc' => 'Soap Box Derby Track',
          'lon' => '-71.107483',
          'type' => 'Intersection'
        };
    
  • ここで、後置 forは少しトリッキーです。先ほど見たように、hashref には 8 つのキーがあります。残念ながら、それらのいくつかは時々欠落しています。があるためuse warnings、これらの欠損値のいずれかにアクセスしようとすると警告が表示されます。これらのキーを作成し、そこに空の文字列を配置する必要''があります。

    foreachforPerl では完全に互換性があり、どちらも単一の式の後置構文で使用できます。qw-operatorを使用して、for反復するリストを作成します。は引用された単語qwの略で、まさにそれを行います: 引用されている文字列のリストを返します。とも言えます。('time', 'lat', 'long'... )

    式では、 の各キーにアクセスします$wp$_ループ変数です。最初の反復では、「時間」、次に「緯度」などを保持します。$wpは hashref なので、そのキーにアクセスするには が必要です->。中括弧は、それがハッシュリファレンスであることを示しています。||=演算子は、真の値でない場合にのみ、ハッシュ ref 要素に値を割り当てます。

  • ここで、時間値がある場合 (日付が設定されていない場合に割り当てた空の文字列は「何もない」と見なされます)、UNIX タイムスタンプを適切な日付に置き換えます。DateTimeはそれを行うのに役立ちます。このfrom_epochメソッドは、UNIX タイムスタンプを引数として取得します。関数DateTimeを呼び出すために直接使用できるオブジェクトを返します。iso8601

    これをチェーニングと呼びます。一部のモジュールはそれを実行できます。これは、jQuery の JavaScript オブジェクトが行うことと似ています。ハッシュリファレンスの UNIX タイムスタンプは、DateTime操作の結果に置き換えられます。

  • ここでprint、再びファイルハンドルに戻ります。join値の間にカンマを挿入するために使用されます。また、最後に改行を入れます。
  • ループが終わったらclose、ファイルハンドルです。
  • これで完了です。:)

全体として、これは非常にシンプルで読みやすいと言えますね。私は、過度に冗長な構文と _Perl っぽいフレーバーを健全に組み合わせたものにしようとしました。

于 2012-06-19T21:18:55.657 に答える