Created
July 12, 2022 11:31
-
-
Save andrewmichaelsmith/9ac3624ae3279c01c057550d3708a946 to your computer and use it in GitHub Desktop.
GPX analysis, including gpx to elevation profile chart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"id": "76a8bc7b", | |
"metadata": {}, | |
"source": [ | |
"# Some notes on some GPX tinkering and analysis for a blog post\n", | |
"\n", | |
"Compared to some other notebooks out there I think this simplifies the charting of an elevation profile from a GPX file a fair bit. Though I had a slightly odd use case (charting gaps when there were large jumps in distance) that might not be suitable for everyone.\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "f157fe84", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"!pip install gpxpy\n", | |
"!pip install geopy\n", | |
"!pip install plotly\n", | |
"!pip install kaleido" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "060968f3", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Pre-work was to use GPSBabel to merge all of the gpx files in to 1\n", | |
"# https://stackoverflow.com/questions/38554131/merge-all-gpx-files-within-a-folder-into-one-file-with-gpsbabel\n", | |
"# This produces All.gpx\n", | |
"# As an optimisation for graphing I grep'd out the time/speed elements and produced `All-notimeorspeed.gpx`" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "b00abf84", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# Produce high level stats\n", | |
"#sudo apt-get install -y gpxinfo\n", | |
"#gpxinfo -m All.gpx > stats" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "06f8684e", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import gpxpy\n", | |
"import gpxpy.gpx\n", | |
"import math\n", | |
"import geopy.distance\n", | |
"import matplotlib.pyplot as plt\n", | |
"\n", | |
"import pandas as pd\n", | |
"\n", | |
"with open('All.gpx', 'r') as gpx_file:\n", | |
" gpx = gpxpy.parse(gpx_file)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "230574b1", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"elevation = []\n", | |
"is_real = []\n", | |
"distance = []\n", | |
"\n", | |
"prev_lat = None\n", | |
"prev_lon = None\n", | |
"\n", | |
"new_track = False\n", | |
"\n", | |
"for track in gpx.tracks:\n", | |
" \n", | |
"\n", | |
" for segment in track.segments:\n", | |
" for point in segment.points:\n", | |
" if point.elevation:\n", | |
" \n", | |
" if(prev_lat is not None):\n", | |
" diff = geopy.distance.geodesic((prev_lat, prev_lon), (point.latitude, point.longitude)).km\n", | |
" prev_distance = distance[-1]\n", | |
" else:\n", | |
" diff = 0\n", | |
" prev_distance = 0\n", | |
" \n", | |
" # I want to add NaN values for the chart below so that it shows when I jumped (e.g. taking a bus),\n", | |
" # this is the hack to do that.\n", | |
" if new_track:\n", | |
" if diff > 5:\n", | |
" elevation.append(point.elevation)\n", | |
" distance.append(prev_distance + 2) \n", | |
" is_real.append(False)\n", | |
" \n", | |
" elevation.append(point.elevation)\n", | |
" distance.append(prev_distance + diff)\n", | |
" is_real.append(True) \n", | |
" \n", | |
" prev_lat = point.latitude\n", | |
" prev_lon = point.longitude\n", | |
"\n", | |
" \n", | |
" new_track = True\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "3b429505", | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [], | |
"source": [ | |
"df = pd.DataFrame({\n", | |
" 'distance': distance,\n", | |
" 'elevation': elevation,\n", | |
" 'is_real': is_real\n", | |
"})\n", | |
"\n", | |
"df = df.set_index('distance')\n", | |
"\n", | |
"df['elevation'][df.is_real == False] = pd.NA\n" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"id": "69efac43", | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import plotly.express as px\n", | |
"\n", | |
"fig = px.line(\n", | |
" df,\n", | |
" y=\"elevation\",\n", | |
" labels={\"elevation\": \"Elevation (m)\", \"distance\": \"Distance (km)\"},\n", | |
")\n", | |
"\n", | |
"fig.write_image('/home/andy/git/blog/content/images/vancouver-to-tijuana-elevation-main.png', format=\"png\", width=4000, height=450, scale=1)\n", | |
"fig.write_image('/home/andy/git/blog/content/images/vancouver-to-tijuana-elevation-thumb.png', format=\"png\", width=700, height=250, scale=1)\n", | |
"\n" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3 (ipykernel)", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.9.7" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 5 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment