Skip to content

Instantly share code, notes, and snippets.

@tovrstra
Last active April 4, 2019 09:52
Show Gist options
  • Save tovrstra/8e7c132c7020178594ca28c45389e0a6 to your computer and use it in GitHub Desktop.
Save tovrstra/8e7c132c7020178594ca28c45389e0a6 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
"""Convert Openstreetmap Way to GPX format.
This Python script is derived from the following PERL script:
https://wiki.openstreetmap.org/wiki/Relations/Relations_to_GPX
Usage:
./waytogpx.py <way>
The result is a file way_<way>.gpx
"""
import argparse
from urllib.request import urlopen
import xml.etree.ElementTree as ET
gpx_template = """\
<?xml version="1.0" encoding="UTF-8"?>
<gpx
version="1.0"
creator="GPSBabel - http://www.gpsbabel.org"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/0"
xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
<bounds minlat="{minlat}" minlon="{minlon}" maxlat="{maxlat}" maxlon="{maxlon}"/>
<trk><trkseg>
{waypoints}
</trkseg></trk>
</gpx>
"""
def main():
"""Run the main function."""
# Parse command-line args
parser = argparse.ArgumentParser("Convert OSM way to GPX.")
parser.add_argument("way", type=int, help="Way to convert.")
way = parser.parse_args().way
# Download
url = "https://www.openstreetmap.org/api/0.6/way/{}/full".format(way)
print("Downloading", url)
with urlopen(url) as f:
string = f.read()
root = ET.fromstring(string)
# Build dictionary of nodes
nodes = {}
for el_node in root.findall("node"):
nodes[el_node.attrib["id"]] = [
float(el_node.attrib["lat"]),
float(el_node.attrib["lon"])]
# Build list of waypoints
lats = []
lons = []
el_way = root.find("way")
for el_nd in el_way.findall("nd"):
lat, lon = nodes[el_nd.attrib["ref"]]
lats.append(lat)
lons.append(lon)
# Write the gpx file
fn_gpx = "way_{}.gpx".format(way)
with open(fn_gpx, "w") as f:
f.write(gpx_template.format(
minlat=min(lats),
maxlat=max(lats),
minlon=min(lons),
maxlon=max(lons),
waypoints="\n".join(['<trkpt lat="{}" lon="{}" />'.format(
lat, lon) for lat, lon in zip(lats, lons)])
))
print("Written", fn_gpx)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment