Created
February 14, 2019 00:37
-
-
Save kylebarron/0e206d4500b5f939ade98764d9e1ef66 to your computer and use it in GitHub Desktop.
Combine Halfmile GPX segments into one or a few big GPX files
This file contains hidden or 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
#! /usr/bin/env python3 | |
""" | |
Program: Combine Halfmile GPX tracks into a single GPX track | |
Author: Kyle Barron | |
""" | |
import io | |
import requests | |
import gpxpy | |
import gpxpy.gpx | |
from zipfile import ZipFile | |
def main(): | |
for state in ['ca1', 'ca2', 'or', 'wa']: | |
gpxs = download_gpx_tracks(state[:2]) | |
tracks, waypoints = split_into_tracks_and_waypoints(gpxs) | |
split = int(state[2]) if state.startswith('ca') else None | |
tracks = combine(sort_gpxs(tracks), split) | |
waypoints = combine(sort_gpxs(waypoints), split) | |
with open(f'{state}_pct_tracks.gpx', 'w') as f: | |
f.write(tracks.to_xml()) | |
with open(f'{state}_pct_waypoints.gpx', 'w') as f: | |
f.write(waypoints.to_xml()) | |
def download_gpx_tracks(state): | |
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36'} | |
unzipped_content = {} | |
url = 'https://www.pctmap.net/wp-content/uploads/pct' | |
url += f'/{state}_state_gps.zip' | |
r = requests.get(url, headers=headers) | |
content = io.BytesIO(r.content) | |
with ZipFile(content) as zf: | |
for name in zf.namelist(): | |
if not name.startswith(state): | |
continue | |
if not name.endswith('.gpx'): | |
continue | |
unzipped_content[name] = zf.read(name).decode('utf-8') | |
return unzipped_content | |
def split_into_tracks_and_waypoints(gpxs): | |
tracks = {} | |
waypoints = {} | |
for name, data in gpxs.items(): | |
if name.endswith('tracks.gpx'): | |
tracks[name] = data | |
elif name.endswith('waypoints.gpx'): | |
waypoints[name] = data | |
else: | |
raise Exception() | |
return tracks, waypoints | |
def sort_gpxs(gpx): | |
return dict(sorted(gpx.items())) | |
def combine(gpx, split=None): | |
new_gpx = gpxpy.gpx.GPX() | |
if split is not None: | |
if split == 1: | |
gpx = dict(list(gpx.items())[:len(gpx) // 2]) | |
elif split == 2: | |
gpx = dict(list(gpx.items())[len(gpx) // 2:]) | |
else: | |
raise Exception('split must be 1, 2, or None') | |
for name, g in gpx.items(): | |
g = gpxpy.parse(g) | |
for track in g.tracks: | |
new_gpx.tracks.append(track) | |
for waypoint in g.waypoints: | |
new_gpx.waypoints.append(waypoint) | |
for route in g.routes: | |
new_gpx.routes.append(route) | |
return new_gpx | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment