Created
July 11, 2020 16:14
-
-
Save cefn/a11249a487d481ccf0519d49f2cc988c to your computer and use it in GitHub Desktop.
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
#! /home/linuxbrew/.linuxbrew/opt/[email protected]/bin/python3.8 | |
import os | |
import math | |
import shutil | |
import requests | |
from xml.etree import ElementTree | |
def decimalMinuteString(decimalDegreeString, paddegrees): | |
degrees = float(decimalDegreeString) | |
wholeDegrees = math.floor(degrees) | |
remainderDegrees = degrees % 1.0 | |
minutes = remainderDegrees * 60 | |
return f"{wholeDegrees:0{paddegrees}d}{minutes:06.3f}" | |
xcsoar_local_dir = "/home/cefn/Documents/kobo/xcsoar_emulator_root" | |
xcsoar_remote_dir = "http://download.xcsoar.org/maps/" | |
opendem_remote_dir = ( | |
"http://www.muaythaiclinch.info/opendem_europe_download/eu_4326/contours/" | |
) | |
map_filenames = ["UK_HighRes.xcm", "UK.xcm", "UK_Altair.xcm"] | |
contour_filenames = { | |
"dales_west": "N54W003.zip", | |
"lakes": "N54W004.zip", | |
"dales_east": "N54W002.zip", | |
"pennines": "N53W003.zip", | |
"peaks": "N53W002.zip", | |
} | |
waypoint_urls = { | |
# lake district tumps and minor prominences from http://www.haroldstreet.org.uk/waypoints/download/?list=tumps&list2=lamps&area=ldnp | |
"lakes": "http://www.haroldstreet.org.uk/waypoints/download/satmap-gpx.php?list=tumps&area=ldnp&list2=lamps", | |
"dales": "http://www.haroldstreet.org.uk/waypoints/download/satmap-gpx.php?list=tumps&area=35&list2=lamps", | |
"pennines": "http://www.haroldstreet.org.uk/waypoints/download/satmap-gpx.php?list=tumps&area=36&list2=lamps", | |
} | |
for dirname in ["originals", "extracted", "augmented", "contours"]: | |
os.makedirs(dirname, exist_ok=True) | |
def lazy_download_url(remote_url, download_path): | |
if not os.path.exists(download_path): | |
r = requests.get(remote_url) | |
open(download_path, "wb").write(r.content) | |
return download_path | |
def lazy_download_filename(remote_dir, local_dir, file_name): | |
return lazy_download_url( | |
f"{remote_dir}{file_name}", os.path.join(local_dir, file_name) | |
) | |
def lazy_download_all(): | |
for map_filename in map_filenames: | |
lazy_download_filename(xcsoar_remote_dir, "originals", map_filename) | |
for contour_file in contour_filenames.values(): | |
lazy_download_filename(opendem_remote_dir, "contours", contour_file) | |
for (alias, url) in waypoint_urls.items(): | |
download_path = f"{alias}.gpx" | |
lazy_download_url(url, download_path) | |
def make_files(): | |
lazy_download_all() | |
for map_filename in map_filenames: | |
# unpack the map | |
short_name = os.path.splitext(map_filename)[0] | |
original_map_path = f"originals/{map_filename}" | |
extracted_map_path = f"extracted/{short_name}" | |
augmented_map_path = f"augmented/{map_filename}" | |
# unpack the .xcm filesystem | |
shutil.unpack_archive( | |
original_map_path, extract_dir=extracted_map_path, format="zip" | |
) | |
# add contours to extracted files | |
for (contour_alias, contour_filename) in contour_filenames.items(): | |
contour_short_name = os.path.splitext(contour_filename)[0] | |
original_contour_path = f"contours/{contour_filename}" | |
extracted_contour_path = f"extracted/{contour_alias}" | |
# extract shapefile parts | |
shutil.unpack_archive( | |
original_contour_path, extract_dir=extracted_contour_path, format="zip" | |
) | |
# copy shapefile parts into unpacked .xcm filesystem | |
for extension in ["dbf", "prj", "shx", "shp"]: | |
shutil.copyfile( | |
f"{extracted_contour_path}/{contour_short_name}/{contour_short_name}.{extension}", | |
f"{extracted_map_path}/{contour_alias}_line.{extension}", | |
) | |
# read topology entry, add a line for the new contour | |
with open(f"{extracted_map_path}/topology.tpl", "r") as f: | |
lines = list(f.readlines()) | |
with open(f"{extracted_map_path}/topology.tpl", "w") as f: | |
f.writelines(lines) | |
f.write(f"{contour_alias}_line,3,,,0,0,0,1,3,0\n") | |
# pack the .xcm filesystem again | |
shutil.make_archive( | |
augmented_map_path, root_dir=extracted_map_path, format="zip" | |
) | |
# reverse stupid shutil.make_archive suffix default | |
os.rename(f"{augmented_map_path}.zip", augmented_map_path) | |
# copy to test directory | |
shutil.copyfile( | |
augmented_map_path, f"{xcsoar_local_dir}/{short_name}_augmented.xcm" | |
) | |
for waypoint_alias in waypoint_urls.keys(): | |
waypoint_import_filename = f"{waypoint_alias}.gpx" | |
waypoint_export_filename = f"{waypoint_alias}.cup" | |
tree = ElementTree.parse(waypoint_import_filename) | |
root = tree.getroot() | |
with open(waypoint_export_filename, "w") as f: | |
for childpos, child in enumerate(root): | |
name = child[1].text | |
code = name[:3].upper() + "{:03d}".format(childpos) | |
country = "UK" | |
lat = float(child.attrib["lat"]) | |
lon = float(child.attrib["lon"]) | |
lat = ( | |
f"{decimalMinuteString(lat, 2)}N" | |
if lat > 0 | |
else f"{decimalMinuteString(-lat, 2)}S" | |
) | |
lon = ( | |
f"{decimalMinuteString(lon, 3)}E" | |
if lon > 0 | |
else f"{decimalMinuteString(-lon, 3)}W" | |
) | |
height = child[0].text + "m" # in metres | |
pointtype = 7 # MntTop | |
desc = "" | |
f.write( | |
f""""{name}","{code}",{country},{lat},{lon},{height},{pointtype},,,,"{desc}"\n""" | |
) | |
shutil.copyfile( | |
waypoint_export_filename, | |
os.path.join(xcsoar_local_dir, waypoint_export_filename), | |
) | |
if __name__ == "__main__": | |
make_files() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment