GGRS: Geoscience, GIS, & Remote Sensing

지구과학, GIS, 그리고 원격탐사 블로그입니다.

Python: GPX 파일을 pandas.DataFrame으로 변환하기

댓글 2

IT

2021. 8. 12.

안녕하세요? 이번 글은 Python 'gpxpy(GPX file parser)' 라이브러리를 이용하여 GPX 파일을 pandas.DataFrame으로 변환해 보겠습니다. GPX(https://ko.wikipedia.org/wiki/GPX)는 GPS Exchange Format으로 GPS 트랙용 XML 기반 형식으로 되어 있습니다. gpxpy는 GPX 파일의 파싱(구문 분석)과 조작을 위한 Python 라이브러리로 이해하시면 되겠습니다.

 

gpxpy

GPX file parser and GPS track manipulation library

pypi.org

이 글에서 작성한 코드는 브라질의 물리해양학자/소프트웨어 엔지니어 'Filipe Fernandes(필리페 페르난데스)' 님의 아래 글을 참고하였습니다.

 

Exploring GPX files

I tried to find public run data for Salvador to discover the best places to run here using that kind of plot. First I tried RunKeeper, the app does make their public data available online, but it is not a popular app in Brazil and I could not find any trac

ocefpaf.github.io

실습용 GPX 파일은 '게임 같은 운동앱 트랭글 GPS' 사용자의 트래킹코스 2건(북한산국립공원 일원)을 사용했습니다. 자, 그럼 시작해볼까요?!

 

게임 같은 운동앱 트랭글 GPS

[트랭글]은 여러분이 게임 속 캐릭터가 되어 다양한 운동과 정해진 코스를 따라 12,000 여 종류의 인증배지를 획득하는 운동앱 입니다.

www.tranggle.com

일단 필요한 라이브러리를 호출합니다.

#라이브러리 호출
import gpxpy
import pandas as pd
import os
from glob import glob

GPX 파일의 트랙(track), 세그먼트(segment), 포인트(point)가 각각 몇 건인지 출력해 봅니다.

gpx = gpxpy.parse(open('D:/GEODATA/210117_163033.gpx'))

print("{} 개 트랙".format(len(gpx.tracks)))
track = gpx.tracks[0]

print("{} 개 세그먼트".format(len(track.segments)))
segment = track.segments[0]

print("{} 개 포인트".format(len(segment.points)))
1 개 트랙
1 개 세그먼트
981 개 포인트

GPX 파일의 포인트 정보를 pandas.DataFrame으로 변환해 봅니다.

경도(Lon), 위도(Lat), 고도(Elev), 시간(Time), 속도(Speed: 초속m/s을 시속km/h으로 변환)

data = []
segment_length = segment.length_3d()
for point_idx, point in enumerate(segment.points):
    data.append([point.longitude, # 경도
                 point.latitude, # 위도
                 point.elevation, # 고도
                 point.time, # 시간
                 segment.get_speed(point_idx)*3.6]) # 속도(km/h)

df = pd.DataFrame(data, columns=['Lon', 'Lat', 'Elev', 'Time', 'Speed'])
df.head()

아래와 같이 확인할 수 있습니다.

GPX 파일을 다수 처리할 경우, 아래 함수를 사용합니다. 파일(색인, 이름), 트랙(색인, 이름, 시작시간, 길이, 지속시간, 최)대속도), 세그먼트(색인, 길이), 포인트 정보(위도, 경도, 고도, 시간, 속도)까지 15개 항목을 컬럼 추가하는 내용입니다. 꽤 도움이 되겠죠?!

def load_run_data(gpx_path):
    gpx_files = glob(os.path.join(gpx_path, "*.gpx"))
    run_data = []
    for file_idx, gpx_file in enumerate(gpx_files):
        gpx = gpxpy.parse(open(gpx_file, 'r', encoding='utf-8'))
        # Loop through tracks
        for track_idx, track in enumerate(gpx.tracks):
            track_name = track.name
            track_time = track.get_time_bounds().start_time
            track_length = track.length_3d() / 1000
            track_duration = track.get_duration()
            track_max_speed = track.get_moving_data().max_speed * 3.6
            
            for seg_idx, segment in enumerate(track.segments):
                seg_length = segment.length_3d() / 1000
                for point_idx, point in enumerate(segment.points):
                    run_data.append([file_idx, # 파일 색인
                                     os.path.basename(gpx_file), # 파일 이름
                                     track_idx, # 트랙 색인
                                     track_name, # 트랙 이름
                                     track_time, # 트랙 시작시간
                                     track_length, # 트랙 길이(km)
                                     track_duration, # 트랙 지속시간(s)
                                     track_max_speed, # 트랙 최대속도(km/h)
                                     seg_idx, # 세그먼트 색인
                                     seg_length, # 세그먼트 길이(km)
                                     point.longitude, # 포인트 위도
                                     point.latitude, # 포인트 경도
                                     point.elevation, # 포인트 고도
                                     point.time, # 포인트 시간
                                     segment.get_speed(point_idx)*3.6]) # 포인트 속도(km/h)
    return run_data

자, 이제 GPX 파일이 모여 있는 경로만 지정해 주면 되겠습니다!

data = load_run_data('D:/GEODATA/')
df = pd.DataFrame(data, columns=['f_Idx', 'f_Name',
                                 't_Idx', 't_Name', 't_Time', 't_Length', 't_Duration', 't_Max_Speed',
                                 's_Idx', 's_Length',
                                 'p_Lon', 'p_Lat', 'p_Elev', 'p_Time', 'p_Speed'])
df

여기까지 Python 'gpxpy' 라이브러리를 이용하여 GPX 파일을 pandas.DataFrame으로 변환하는 과정을 정리해 봤습니다.