airport-update/aptupd.py

112 lines
3.9 KiB
Python
Raw Permalink Normal View History

#! /usr/bin/env python3
import sys
import os
import re
import json
import fnmatch
from subprocess import run
from multiprocessing import Pool, cpu_count
if not os.path.isfile("data/nav.dat"):
print("ERROR: no data/nav.dat file")
sys.exit(1)
def find(pattern, path):
result = []
for root, dirs, files in os.walk(path):
for name in files:
if fnmatch.fnmatch(name, pattern):
result.append(os.path.join(root, name))
return result
def unique(it):
s = set()
for el in it:
if el not in s:
s.add(el)
yield el
def bash(cmd):
run(cmd, shell=True)
def buildApt(apt):
aptId = changed[apt]["id"]
path = "tmp/" + apt + "/"
bash("mkdir -p " + path + "/work")
bash("ln -sf $(pwd)/work/SRTM-3 " + path + "/work")
bash("wget https://gateway.x-plane.com/apiv1/scenery/" + str(aptId) + " -O " + path + apt + ".json > logs/" + apt + ".log 2>&1")
try:
with open(path + apt + ".json") as json_data:
source = json.load(json_data)
with open(path + apt + ".tmp", "w") as tmp:
tmp.write(source["scenery"]["masterZipBlob"])
bash("cat " + path + apt + ".tmp | base64 -d -- > " + path + apt + ".zip")
bash("cd " + path + " && unzip -o " + apt + ".zip >> ../../logs/" + apt + ".log 2>&1")
bash("cd " + path + " && ../../dsf2aptdat.py -i " + apt + ">> ../../logs/" + apt + ".log 2>&1")
bash("mv -f " + path + apt + ".dat data/airports/")
bash("/terragear/run_genapts.sh --input=$(pwd)/data/airports/" + apt + ".dat --work=$(pwd)/" + path + "work --clear-dem-path --dem-path=SRTM-3 >> logs/" + apt + ".log 2>&1")
ind = find("*.ind", path + "work/AirportObj/")
if len(ind) > 0:
match = re.match(".*Obj/([we]\d{3}[sn]\d{2}/[we]\d{3}[sn]\d{2})/(\d+)\.ind", ind[0])
if match != None:
bash("mkdir -p output/Terrain/" + match.group(1))
bash("mv " + path + "work/AirportObj/" + match.group(1) + "/" + apt + ".btg.gz output/Terrain/" + match.group(1))
bash("mkdir -p stg/" + match.group(1) + "/" + match.group(2))
bash("mv " + ind[0] + " stg/" + match.group(1) + "/" + match.group(2) + "/" + apt + ".stg")
bash("rm -rf " + path)
bash("aptdat2airportsxml --overwrite -n data/nav.dat -o output/ -d /terragear/install/flightgear/fgdata/ -e /terragear/install/flightgear/bin/fgelev -i data/airports/" + apt + ".dat >> logs/" + apt + ".log 2>&1")
return match.group(1) + "/" + match.group(2)
except (ValueError, json.decoder.JSONDecodeError):
print("ERROR: Invalid responce for " + apt + " recieved")
bash("wget https://gateway.x-plane.com/apiv1/airports -O tmp/airports.json")
try:
with open("tmp/airports.json") as json_data:
source = json.load(json_data)
except ValueError:
print("ERROR: Invalid airports file recieved")
sys.exit(1)
airports = {}
if os.path.isfile("data/airports-done.json"):
try:
with open("data/airports-done.json") as json_data:
airports = json.load(json_data)
except ValueError:
print("ERROR: Invalid airports-done.json file")
sys.exit(1)
changed = {}
for apt in source["airports"]:
airport = {}
airport["id"] = apt["RecommendedSceneryId"]
if (not apt["AirportCode"] in airports or airports[apt["AirportCode"]]["id"] != apt["RecommendedSceneryId"]) and apt["ApprovedSceneryCount"] > 0:
airports[apt["AirportCode"]] = airport
changed[apt["AirportCode"]] = airport
print("Added " + apt["AirportCode"])
with Pool(processes=cpu_count()) as pool:
tiles = set(pool.map(buildApt, changed))
print("INFO: Updating .stg files...")
if changed != {}:
for tile in tiles:
if tile != None:
bash("cat stg/" + tile + "/*.stg > output/Terrain/" + tile + ".stg")
print("INFO: Generating new apt.dat.gz...")
bash("mkdir -p output/NavData/apt")
bash("rm -f output/NavData/apt/apt.dat.gz")
bash('''echo "I
1130 Generated by aptupd
" > output/NavData/apt/apt.dat''')
bash("ls data/airports/|parallel -j 1 ./append-apt.sh data/airports/{}")
bash("gzip output/NavData/apt/apt.dat")
bash("rm -rf tmp/*")
with open("data/airports-done.json", "w") as f:
json.dump(airports, f)