-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added KML generation, Refactored scripts, Updated readme & actions (#2)
- Loading branch information
1 parent
e3a085f
commit 38cb4ad
Showing
8 changed files
with
229 additions
and
114 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
name: Make & release GeoJSON | ||
name: Make & release KML & GeoJSON | ||
|
||
on: | ||
push: | ||
|
@@ -23,13 +23,16 @@ jobs: | |
with: | ||
python-version: '3.10' | ||
|
||
- name: Run "make_geojson.py" | ||
run: python make_geojson.py | ||
- name: Installing dependencies | ||
run: pip install -r requirements.txt | ||
|
||
- name: Run "make_all.py" | ||
run: python make_all.py | ||
|
||
- name: Check output existence | ||
uses: thebinaryfelix/[email protected] | ||
with: | ||
files: 'output/airports_full_all_feet.geojson, output/airports_full_all_meter.geojson' | ||
files: 'output/airports_full_all_feet.geojson, output/airports_full_all_meter.geojson, output/airports_full.kml' | ||
|
||
- name: Create release | ||
id: create_release | ||
|
@@ -44,7 +47,7 @@ jobs: | |
draft: true | ||
prerelease: false | ||
|
||
- name: Upload asset `full_all_feet` | ||
- name: Upload asset `airports_full_all_feet.geojson` | ||
uses: actions/upload-release-asset@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
|
@@ -54,7 +57,7 @@ jobs: | |
asset_name: airports_full_all_feet.geojson | ||
asset_content_type: application/geo+json | ||
|
||
- name: Upload asset `full_all_meter` | ||
- name: Upload asset `airports_full_all_meter.geojson` | ||
uses: actions/upload-release-asset@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
|
@@ -63,3 +66,13 @@ jobs: | |
asset_path: ./output/airports_full_all_meter.geojson | ||
asset_name: airports_full_all_meter.geojson | ||
asset_content_type: application/geo+json | ||
|
||
- name: Upload asset `airports_full.kml` | ||
uses: actions/upload-release-asset@v1 | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
upload_url: ${{ steps.create_release.outputs.upload_url }} | ||
asset_path: ./output/airports_full.kml | ||
asset_name: airports_full.kml | ||
asset_content_type: application/vnd.google-earth.kml+xml |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import json | ||
import os | ||
import shutil | ||
import sys | ||
|
||
|
||
# Data adapted from ISO 3166-1 | ||
# Source: https://en.m.wikipedia.org/wiki/List_of_sovereign_states_and_dependent_territories_by_continent_(data_file) | ||
COUNTRY_IN_CONTINENT = { | ||
# Africa | ||
"AF": ["AO", "BF", "BI", "BJ", "BW", "CD", "CF", "CG", "CI", "CM", "CV", "DJ", "DZ", "EG", "EH", "ER", "ET", "GA", | ||
"GH", "GM", "GN", "GQ", "GW", "IO", "KE", "KM", "LR", "LS", "LY", "MA", "MG", "ML", "MR", "MU", "MW", "MZ", | ||
"NA", "NE", "NG", "RE", "RW", "SC", "SD", "SH", "SL", "SN", "SO", "SS", "ST", "SZ", "TD", "TF", "TG", "TN", | ||
"TZ", "UG", "YT", "ZA", "ZM", "ZW"], | ||
|
||
# Antarctica | ||
"AN": ["AQ", "BV", "GS", "HM"], | ||
|
||
# Asia | ||
"AS": ["AE", "AF", "AM", "AZ", "BD", "BH", "BN", "BT", "CC", "CN", "CX", "CY", "EG", "GE", "HK", "ID", "IL", "IN", | ||
"IQ", "IR", "JO", "JP", "KG", "KH", "KP", "KR", "KW", "KZ", "LA", "LB", "LK", "MM", "MN", "MO", "MV", "MY", | ||
"NP", "OM", "PH", "PK", "PS", "QA", "RU", "SA", "SG", "SY", "TH", "TJ", "TL", "TM", "TR", "TW", "UZ", "VN", | ||
"XD", "XS", "YE"], | ||
|
||
# Europe | ||
"EU": ["AD", "AL", "AM", "AT", "AX", "AZ", "BA", "BE", "BG", "BY", "CH", "CY", "CZ", "DE", "DK", "EE", "ES", "FI", | ||
"FO", "FR", "GB", "GE", "GG", "GI", "GR", "HR", "HU", "IE", "IM", "IS", "IT", "JE", "KZ", "LI", "LT", "LU", | ||
"LV", "MC", "MD", "ME", "MK", "MT", "NL", "NO", "PL", "PT", "RO", "RS", "RU", "SE", "SI", "SJ", "SK", "SM", | ||
"TR", "UA", "VA", "XK"], | ||
|
||
# North America | ||
"NA": ["AG", "AI", "AW", "BB", "BL", "BM", "BQ", "BS", "BZ", "CA", "CR", "CU", "CW", "DM", "DO", "GD", "GL", "GP", | ||
"GT", "HN", "HT", "JM", "KN", "KY", "LC", "MF", "MQ", "MS", "MX", "NI", "PA", "PM", "PR", "SV", "SX", "TC", | ||
"TT", "UM", "US", "VC", "VG", "VI"], | ||
|
||
# Oceania | ||
"OC": ["AS", "AU", "CK", "FJ", "FM", "GU", "KI", "MH", "MP", "NC", "NF", "NR", "NU", "NZ", "PF", "PG", "PN", "PW", | ||
"SB", "TK", "TO", "TV", "UM", "VU", "WF", "WS", "XX"], | ||
|
||
# South America | ||
"SA": ["AR", "BO", "BR", "CL", "CO", "EC", "FK", "GF", "GY", "PE", "PY", "SR", "UY", "VE"] | ||
} | ||
|
||
|
||
def prepare_output(output_path: str) -> None: | ||
# Removing old output directory | ||
if os.path.exists(output_path): | ||
print(f"Removing old build folder...") | ||
if os.path.isdir(output_path): | ||
shutil.rmtree(output_path) | ||
else: | ||
raise IOError(f"The output location '{output_path}'is a file !") | ||
|
||
# Creating new output directory | ||
print(f"Preparing '{output_path}'...") | ||
os.mkdir(output_path) | ||
|
||
|
||
def get_clean_data(input_file: str) -> dict: | ||
print(f"Loading '{input_file}'...") | ||
with open(input_file, "rb") as f: | ||
raw_data = json.loads(f.read().decode("utf-8")) | ||
print(f"Loaded '{len(raw_data)}' airport(s) !") | ||
|
||
# Validating the data | ||
print(f"Validating & fixing the data...") | ||
was_data_valid = True | ||
for raw_airport_key, raw_airport_data in raw_data.items(): | ||
for required_field in ["icao", "iata", "name", "city", "state", "country", "elevation", "lat", "lon", "tz"]: | ||
if not (required_field in raw_airport_data): | ||
print(f"ERROR: Airport '{raw_airport_key}' is missing the '{required_field}' field !") | ||
was_data_valid = False | ||
if type(raw_airport_data[required_field]) is str: | ||
if len(raw_airport_data[required_field]) == 0: | ||
raw_airport_data[required_field] = None | ||
if raw_airport_data["icao"] is None and raw_airport_data["iata"] is None: | ||
print(f"ERROR: Airport '{raw_airport_key}' is missing its ICAO and IATA codes !") | ||
was_data_valid = False | ||
if raw_airport_data["name"] is None: | ||
print(f"ERROR: Airport '{raw_airport_key}' is missing its name !") | ||
was_data_valid = False | ||
if raw_airport_data["country"] is None: | ||
print(f"ERROR: Airport '{raw_airport_key}' is missing its country code !") | ||
was_data_valid = False | ||
if not was_data_valid: | ||
print_footer("Cannot continue, we have invalid data !", True) | ||
sys.exit(1) | ||
|
||
return raw_data | ||
|
||
|
||
def print_header(app_name: str, space_count: int = 0) -> None: | ||
print(" \033[36m_ \033[94m__ \033[36m_\033[39m") | ||
print(" \033[96m_ \033[36m_// \033[94m/\\\\ \\ \033[36m\\\\_ \033[96m_\033[39m") | ||
print(" \033[96m_// \033[36m/ / \033[94m/ /_\\ \\ \033[36m\\ \\ \033[96m\\\\_\033[39m") | ||
print(" \033[96m/ / \033[36m/ / \033[94m/ ___\\\\ \\ \033[36m\\ \\ \033[96m\\ \\\033[39m") | ||
print(" \033[96m/_/ \033[36m/_/ \033[94m/_/ \033[94m\\_\\ \033[36m\\_\\ \033[96m\\_\\\033[39m") | ||
print("\033[36m-\033[94m===========================\033[36m-\033[39m") | ||
print(f"{' '*space_count}\033[36m{app_name}\033[39m") | ||
print("\033[36m-\033[94m===========================\033[36m-\033[39m") | ||
|
||
|
||
def print_footer(message: str = "Goodbye :)", is_error: bool = False) -> None: | ||
print("\033[36m-\033[94m===========================\033[36m-\033[39m") | ||
if is_error: | ||
print(f"\033[31m{message}\033[39m") | ||
else: | ||
print(message) | ||
print("\033[36m-\033[94m===========================\033[36m-\033[39m") | ||
print(" \033[96m\\_\\ \033[36m\\_\\ \033[36m/_/ \033[96m/_/\033[39m") |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import commons | ||
import config | ||
|
||
from make_geojson import make_geojson | ||
from make_kml import make_kml | ||
|
||
|
||
if __name__ == "__main__": | ||
# > Printing the logs header | ||
commons.print_header("Data File Maker", 7) | ||
|
||
# Preparing the output directory | ||
commons.prepare_output(config.OUTPUT_DIR) | ||
|
||
# Loading the JSON raw data file. | ||
_raw_data = commons.get_clean_data(config.INPUT_FILE) | ||
|
||
# Running the actual logic | ||
print("\033[36m-\033[94m===========================\033[36m-\033[39m") | ||
make_geojson(_raw_data) | ||
print("\033[36m-\033[94m===========================\033[36m-\033[39m") | ||
make_kml(_raw_data) | ||
|
||
# Printing the logs footer | ||
commons.print_footer() |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import copy | ||
import gc | ||
import json | ||
import os | ||
|
||
import commons | ||
import config | ||
|
||
import simplekml | ||
|
||
|
||
def make_kml(raw_data: dict): | ||
# Preparing the output data structure | ||
print("Preparing the output KML structure...") | ||
kml_main = simplekml.Kml() | ||
|
||
# Converting to KML | ||
print(f"Converting data to KML points...") | ||
for raw_airport_key, raw_airport_data in raw_data.items(): | ||
pnt = kml_main.newpoint( | ||
name=f"{raw_airport_data['icao']} - {raw_airport_data['name']}", | ||
coords=[(raw_airport_data['lon'], raw_airport_data['lat'], )], | ||
) | ||
pnt.name = raw_airport_key | ||
pass | ||
|
||
print("Saving 'airports_full.kml'...") | ||
kml_main.save(os.path.join(config.OUTPUT_DIR, "airports_full.kml")) | ||
|
||
# Helping the GC along | ||
del kml_main | ||
gc.collect() | ||
|
||
|
||
if __name__ == "__main__": | ||
# > Printing the logs header | ||
commons.print_header("KML File Maker", 7) | ||
|
||
# Preparing the output directory | ||
commons.prepare_output(config.OUTPUT_DIR) | ||
|
||
# Loading the JSON raw data file. | ||
_raw_data = commons.get_clean_data(config.INPUT_FILE) | ||
|
||
# Running the actual logic | ||
print("\033[36m-\033[94m===========================\033[36m-\033[39m") | ||
make_kml(_raw_data) | ||
|
||
# Printing the logs footer | ||
commons.print_footer() |
Oops, something went wrong.