Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/update-ourairports.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby

name: Update Airports and Frequencies

on:
pull_request:
paths:
- .github/workflows/update-ourairports.yml
- scripts/ourairports
schedule:
- cron: '0 13 * * *'
workflow_dispatch:

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
- name: Install dependencies
run: gem install countries
- name: Retrieve Airports and Frequencies and save output as JSON
run: ruby scripts/ourairports
- name: Commit changes
uses: EndBug/add-and-commit@v9
if: github.event_name != 'pull_request'
with:
author_name: Airframes.io
author_email: code@airframes.io
message: "Update Airports and Frequencies"
add: "json/*.json"
fetch: false
env:
GITHUB_TOKEN: ${{ github.token }}
94 changes: 94 additions & 0 deletions scripts/ourairports
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env ruby

require 'net/http'
require 'csv'
require 'json'
require 'uri'
require 'countries'

# URLs for CSV data
AIRPORTS_CSV_URL = 'https://davidmegginson.github.io/ourairports-data/airports.csv'
FREQUENCIES_CSV_URL = 'https://davidmegginson.github.io/ourairports-data/airport-frequencies.csv'

# Local JSON file paths
AIRPORTS_JSON_PATH = 'json/airports.json'
AIRPORTS_PRETTY_PATH = 'json/airports-pretty.json'
FREQUENCIES_JSON_PATH = 'json/airport-frequencies.json'
FREQUENCIES_PRETTY_PATH = 'json/airport-frequencies-pretty.json'

def download_csv(url)
uri = URI(url)
response = Net::HTTP.get(uri)
response
end

def map_airports_to_json(rows)
airports = rows.map do |row|
country_data = ISO3166::Country[row['iso_country']]
country_name = country_data ? country_data.common_name : row['iso_country']
region_code = row['iso_region']&.split('-')&.last
subdivision = country_data&.subdivisions&.dig(region_code)
region_name = subdivision ? subdivision['name'] : row['iso_region']

{
:region => region_name,
:faa_lid => row['local_code'] || row['ident'],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks right from what i can tell

:name => row['name'],
:location => "#{row['municipality']}, #{region_name}, #{country_name}",
:type => row['type'],
:elevation_ft => row['elevation_ft'].to_i,
:ourairport_id => row['id'].to_i,
:coordinates => {
:longitude => row['longitude_deg'].to_f,
:latitude => row['latitude_deg'].to_f
},
:ident => row['ident'],
:municipality => row['municipality'],
:icao_code => row['icao_code'] || row['local_code'] || row['ident'],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if this is right

:country => country_name
}.to_h
end
{ :airports => airports }.to_h
end

def map_frequencies_to_json(rows)
frequencies = rows.map do |row|
{
:description => row['description'],
:frequency_mhz => row['frequency_mhz'],
:ident => row['airport_ident'],
:ourairports_airport_id => row['airport_ref'].to_i,
:our_airports_id => row['id'].to_i,
Comment on lines +60 to +61
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these were strings originally, making ints to be consistent

:type => row['type']
}.to_h
end
{ :airport_frequencies => frequencies }.to_h
end

def write_pretty_json(path, data)
File.open(path, 'w') do |f|
f.write(JSON.pretty_generate(data))
end
end

def write_json(path, data)
File.open(path, 'w') do |f|
f.write(JSON.generate(data))
end
end

# Download and process airports.csv
airports_csv = download_csv(AIRPORTS_CSV_URL)
airports_rows = CSV.parse(airports_csv.force_encoding("UTF-8"), headers: true)
airports_json = map_airports_to_json(airports_rows)
write_pretty_json(AIRPORTS_PRETTY_PATH, airports_json)
write_json(AIRPORTS_JSON_PATH, airports_json)
puts "Updated #{AIRPORTS_JSON_PATH}"

# Download and process airport-frequencies.csv
frequencies_csv = download_csv(FREQUENCIES_CSV_URL)
frequencies_rows = CSV.parse(frequencies_csv.force_encoding("UTF-8"), headers: true)
frequencies_json = map_frequencies_to_json(frequencies_rows)
write_pretty_json(FREQUENCIES_PRETTY_PATH, frequencies_json)
write_json(FREQUENCIES_JSON_PATH, frequencies_json)
puts "Updated #{FREQUENCIES_JSON_PATH}"