2012-06-19 32 views
6

私は新しいlinux/pythonユーザーです.gpxファイル(GPS追跡ソフトウェアからの出力ファイル)を持っており、GISプログラムで使用するために値をcsv/txtに抽出する必要があります。私は、私の最初のpythonの本、このウェブサイト、オンラインで文字列やスライスなどを見てきました。私は.gpxから.txtへのコンバータを使用して、経度と緯度をテキストファイルに取り出すことができます。標高データを抽出する必要があります。このファイルは先頭に6行のテキストがあり、私はこのファイルをemacsで開く方法を知っています。(Webサイトでのアップロードを除いて)ここでは7行目からファイルがあります。pythonで.gpxデータを抽出する方法

最適なのは、 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> 
+0

:あなたはこれを考え出しありでる? – simbabque

答えて

7

GPX is an XML formatので、CSVへ出力パイソンcsv moduleを使用して、その後、データを解析するlxml又は含まElementTree XML APIようフィッティングモジュールを使用します。これらの概念をカバーする

チュートリアル:

私はまた、おそらくhigher-を与えるgpxpyと呼ばれるのpython GPX解析するライブラリを見つけましたレベルGPXファイルに含まれるデータへのインタフェース。

+0

これを試してみます。誰かが、Perlがこれらを抽出する方法かもしれないと私に示唆しました。私は同じように両方の初心者であるので、私はあなたの言及したチュートリアルを最初に見ていきます。ありがとうMartijn! –

+0

Perlはタスクにも同様に適しています。 Pythonの場合と同じように、Perl XMLパーサとCSVライブラリがあります。しかし、Pythonを学ぶ方が簡単かもしれません。私の個人的な意見では、Perlはラインノイズになりすぎてしまいます。 –

+0

私はあなたの言葉を、感謝します! –

6

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

CPANでは、Perlモジュールディレクトリには、Geo::Gpxというモジュールがあります。 Martijnは既に言っているように、GPXはXML形式です。しかし、幸いなことに、誰かが既にそれを私たちの解析を処理するモジュールにしています。私たちがしなければならないのは、そのモジュールをロードすることだけです。

CSV処理に使用できるモジュールがいくつかありますが、このXMLファイルのデータはかなりシンプルなので、実際には必要ありません。組み込み機能を使用して独自に実行できます。

次のスクリプトを考慮してください。私は1分後に説明をします。

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 strictuse warnings変数の宣言のようなルールを適用して見つけることが一番難しいです一般的な間違いをご紹介。
  • use Geo::Gpxおよびuse DateTimeは、私たちが使用するモジュールです。 Geo::Gpxが私たちの解析を処理する予定です。 UNIXのタイムスタンプを読み取り可能な日時にするには、DateTimeが必要です。
  • open関数がファイルを開きます。 $fh_inは、ファイルハンドルを保持する変数です。読みたいGPXファイルはfells_loopです。gpx私はtopografix.comから借り入れの自由を取った。 openの詳細はperlopentutにあります。
  • $gpxという名前の新しいオブジェクトGeo::Gpxを作成し、ファイルハンドル$fh_inを使用して、XMLデータの読み取り先を指定します。 newメソッドは、オブジェクト指向のインターフェイスを持つすべてのPerlモジュールによって提供されます。
  • closeはファイルハンドルを閉じます。
  • 次のopenには、このファイルハンドルに書きたいことをPerlに伝えるために>があります。
  • printの最初の引数としてファイルハンドルを指定して、printをファイルハンドルに追加します。ファイルハンドルの後にカンマがないことに注意してください。 \nは改行文字です。
  • foreach loopGeo::Gpxオブジェクトのwaypointsのメソッドの戻り値をとります。この値は配列参照です。これを配列を保持する配列と考えてください(参考文献について詳しく知りたい場合は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があるので、これらの欠損値の1つにアクセスしようとすると警告が表示されます。これらのキーを作成し、空の文字列''をそこに入れなければなりません。

    foreachforは、Perlで完全に互換性があり、両者は、単一の式の後ろ後置構文で使用することができます。 qwオペレータを使用して、forが繰り返すリストを作成します。 qwは、の引用語であり、引用された語句の略で、それだけです。それは引用符で囲まれた文字列のリストを返します。 ('time', 'lat', 'long'...)と言ってもいいかもしれません。

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

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

    これはチェーンと呼ばれます。いくつかのモジュールがそれを行うことができます。これは、jQueryのJavaScriptオブジェクトと同様です。ハッシュリファレンスのUNIXタイムスタンプは、DateTime操作の結果に置き換えられます。

  • 今すぐもう一度printにお送りください。 joinは、値の間にカンマを挿入するために使用されます。最後に改行も入れています。
  • ループが終了すると、ファイルハンドルcloseが返されます。
  • これで完成です! :)

私はこれがかなりシンプルであり、またかなり読みやすいと言うでしょうか?私は_Perl_ishフレーバーで過度に冗長な構文を健全に組み合わせようとしました。

+0

あなたのスクリプトをありがとう!私はCPANに行き、@ readmeを見てエラーが発生しました。オプションのExtUtils :: MakeMaker :: Coverage not available 引数 "6.57_05"はMakefile.PL行の数値ge(> =)の数値ではありません。キットが完成しているかどうかを確認してください。 ..良く見える 警告:前提条件DateTime :: Format :: ISO8601 0が見つかりません。 警告:前提条件HTML ::エンティティ0が見つかりません。 警告:前提条件XML :: Descent 1.01が見つかりません。 Geo :: GpxのMakefileを書き込む MYMETA.ymlを書く w/makeテストと8/10テストと3/3サブテストに失敗しました。 lat、lon、elev、w/noluckを実行しようとしました –

+0

私はmakeテストから4ページの間違いがありましたが、latとlonとelevからテキストと時間と他のフィールドを削除しようとしましたが、運がない。私は昨日の最初のperlの本の最初の3章を読んでいたので、私はtheresと簡単な修正を望んでいる、私も運がないsudoの下に再インストールしようとしました。スクリプトは理にかなっており、私は説明部分にも感謝しています。初心者である私は今、頭を傷つけています。 –

+0

[cpanモジュールのインストール方法](http://www.cpan.org/modules/INSTALL.html)のマニュアルをお読みになりましたか?それともCPANのウェブサイトからダウンロードしようとしましたか?コマンドラインツールを使用すると、すべての依存関係がインストールされます。 – simbabque

3

あなたがそれからちょうどライブラリを使用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

よろしく

関連する問題