11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PythonでGPXファイルの値を取得する

Last updated at Posted at 2014-01-20

GPXファイルは、Garmin社製のGPSデバイスやEPSONのGPSリストウォッチに採用されている位置情報を取り扱うためのファイル形式の1種です。XML形式のテキストなので頑張ればそのまま目で読めないこともないですが、プログラム的に扱うなら何かしらの別の形式になっていたほうが便利です。

PythonのSAXモジュールを使ってGPXファイルの中身を読み取ってみます。

GPXファイルはいくつか種類があるのですが、代表的な2つ、トラックポイント形式とウェイポイント形式を読み出してみます。

parser.py
import xml
from xml.sax.handler import ContentHandler


class WayPointHandler(ContentHandler):
    """ウェイポイント形式のハンドラ
    """

    def __init__(self, buf):
        self.buf = buf

        self.results = []
        self.lon = None
        self.lat = None
        self.ele = None
        self.inEle = False

    def startElement(self, name, attrs):
        if name == 'wpt':  # wptエレメントだったらlon, latを取得
            self.ele = None
            self.lon = attrs['lon']
            self.lat = attrs['lat']
        elif name == 'ele':  # eleエレメントだったらフラグを立てる
            self.inEle = True

    def endElement(self, name):
        # 配列に追加してフラグを初期化
        if name == 'wpt':
            self.results.append([self.lon, self.lat, self.ele])
        elif name == 'ele':
            self.inEle = False

    def characters(self, content):
        if self.inEle:  # エレメント内の文字列を取得する
            self.ele = content.strip()

    def parse(self):
        """指定されたファイルの緯度経度および標高を返す。

        @return: [[longitude, latitude, altitude], ... ]
        @rtype: list
        """
        parser = xml.sax.make_parser()
        parser.setContentHandler(self)
        parser.parse(self.buf)

        return self.results


class TrackPointHandler(ContentHandler):
    """トラックポイント形式GPXのハンドラ
    """

    def __init__(self, buf):
        self.buf = buf

        self.results = []
        self.lon = None
        self.lat = None
        self.ele = None
        self.inEle = False

    def startElement(self, name, attrs):
        if name == 'trkpt':  # trkptエレメントだったらlon, latを取得
            self.ele = None
            self.lon = attrs['lon']
            self.lat = attrs['lat']
        elif name == 'ele':  # eleエレメントだったらフラグを立てる
            self.inEle = True

    def endElement(self, name):
        # 取得した値を配列に追加、フラグを初期化
        if name == 'trkpt':
            self.results.append([self.lon, self.lat, self.ele])
        elif name == 'ele':
            self.inEle = False

    def characters(self, content):
        if self.inEle:  # フラグが立っていたらエレメント内の文字列を取得する
            self.ele = content.strip()

    def parse(self):
        """指定されたファイルの緯度経度および標高を返す。

        @return: [[longitude, latitude, altitude], ... ]
        @rtype: list
        """
        parser = xml.sax.make_parser()
        parser.setContentHandler(self)
        parser.parse(self.buf)

        return self.results

使い方。

ウェイポイント形式のGPXファイルはYahoo! Japanルートラボ辺りから拾ってきてください。

>>> f = open('waypoints.gpx', 'rt')
>>> handler = parser.WayPointHandler(f)
>>> handler.parse()
[[u'141.6223275', u'39.0208238888889', u'4.8'],
 [u'141.622242777778', u'39.0208955555556', u'4.9'],
 [u'141.62209', u'39.0210269444444', u'5.5']]
 ...

トラックポイント形式のファイルはサンプルが見当たらなかったので適当にググって拾ってきてください(汗

>>> f = open('trackponits.gpx', 'rt')
>>> handler = parser.TrackPointHandler(f)
>>> handler.parse()
[[u'141.622163611111', u'39.0209638888889', u'4.9'],
 [u'141.622242777778', u'39.0208955555556', u'4.9'],
 [u'141.6223275', u'39.0208238888889', u'4.8'],
 [u'141.623074722222', u'39.0201783333333', u'4.4'],
 ...

あわせて読みたい

11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?