aipp 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +2 -2
- data/CHANGELOG.md +17 -1
- data/README.md +269 -150
- data/exe/aip2aixm +2 -8
- data/exe/aip2ofmx +2 -8
- data/exe/notam2aixm +5 -0
- data/exe/notam2ofmx +5 -0
- data/lib/aipp/aip/README.md +10 -0
- data/lib/aipp/aip/executable.rb +40 -0
- data/lib/aipp/aip/parser.rb +9 -0
- data/lib/aipp/aip/runner.rb +85 -0
- data/lib/aipp/border.rb +2 -2
- data/lib/aipp/debugger.rb +14 -19
- data/lib/aipp/downloader/file.rb +57 -0
- data/lib/aipp/downloader/graphql.rb +29 -0
- data/lib/aipp/downloader/http.rb +48 -0
- data/lib/aipp/downloader.rb +78 -29
- data/lib/aipp/environment.rb +88 -0
- data/lib/aipp/executable.rb +36 -53
- data/lib/aipp/notam/README.md +25 -0
- data/lib/aipp/notam/executable.rb +27 -0
- data/lib/aipp/notam/parser.rb +9 -0
- data/lib/aipp/notam/runner.rb +28 -0
- data/lib/aipp/parser.rb +133 -160
- data/lib/aipp/patcher.rb +4 -5
- data/lib/aipp/regions/LF/README.md +6 -2
- data/lib/aipp/regions/LF/aip/aerodromes.rb +220 -0
- data/lib/aipp/regions/LF/aip/d_p_r_airspaces.rb +53 -0
- data/lib/aipp/regions/LF/aip/dangerous_activities.rb +48 -0
- data/lib/aipp/regions/LF/aip/designated_points.rb +44 -0
- data/lib/aipp/regions/LF/aip/helipads.rb +119 -0
- data/lib/aipp/regions/LF/aip/navigational_aids.rb +82 -0
- data/lib/aipp/regions/LF/aip/obstacles.rb +150 -0
- data/lib/aipp/regions/LF/aip/serviced_airspaces.rb +67 -0
- data/lib/aipp/regions/LF/aip/services.rb +169 -0
- data/lib/aipp/regions/LF/fixtures/aerodromes.yml +2 -2
- data/lib/aipp/regions/LF/helpers/base.rb +32 -32
- data/lib/aipp/regions/LS/README.md +59 -0
- data/lib/aipp/regions/LS/helpers/base.rb +111 -0
- data/lib/aipp/regions/LS/notam/ENR.rb +173 -0
- data/lib/aipp/runner.rb +152 -0
- data/lib/aipp/version.rb +1 -1
- data/lib/aipp.rb +30 -11
- data/lib/core_ext/array.rb +13 -0
- data/lib/core_ext/nokogiri.rb +56 -8
- data/lib/core_ext/string.rb +63 -1
- data.tar.gz.sig +0 -0
- metadata +115 -64
- metadata.gz.sig +0 -0
- data/lib/aipp/aip.rb +0 -166
- data/lib/aipp/regions/LF/aerodromes.rb +0 -223
- data/lib/aipp/regions/LF/d_p_r_airspaces.rb +0 -56
- data/lib/aipp/regions/LF/dangerous_activities.rb +0 -49
- data/lib/aipp/regions/LF/designated_points.rb +0 -47
- data/lib/aipp/regions/LF/helipads.rb +0 -122
- data/lib/aipp/regions/LF/navigational_aids.rb +0 -85
- data/lib/aipp/regions/LF/obstacles.rb +0 -153
- data/lib/aipp/regions/LF/serviced_airspaces.rb +0 -70
- data/lib/aipp/regions/LF/services.rb +0 -172
@@ -1,172 +0,0 @@
|
|
1
|
-
module AIPP
|
2
|
-
module LF
|
3
|
-
|
4
|
-
class Services < AIP
|
5
|
-
|
6
|
-
include AIPP::LF::Helpers::Base
|
7
|
-
|
8
|
-
DEPENDS = %w(aerodromes serviced_airspaces)
|
9
|
-
|
10
|
-
# Service types and how to treat them
|
11
|
-
SOURCE_TYPES = {
|
12
|
-
'A/A' => :address,
|
13
|
-
'AFIS' => :service,
|
14
|
-
'APP' => :service,
|
15
|
-
'ATIS' => :service,
|
16
|
-
'CCM' => :ignore, # centre de contrôle militaire
|
17
|
-
'CEV' => :ignore, # centre d’essai en vol
|
18
|
-
'D-ATIS' => :ignore, # data link ATIS
|
19
|
-
'FIS' => :service,
|
20
|
-
'PAR' => :service,
|
21
|
-
'SRE' => :ignore, # surveillance radar element of PAR
|
22
|
-
'TWR' => :service,
|
23
|
-
'UAC' => :ignore, # upper area control
|
24
|
-
'VDF' => :service,
|
25
|
-
'OTHER' => :service # no <Service> specified at source
|
26
|
-
}.freeze
|
27
|
-
|
28
|
-
# Map French callsigns to English and service type
|
29
|
-
CALLSIGNS = {
|
30
|
-
'Approche' => { en: 'Approach', service_type: 'APP' },
|
31
|
-
'Contrôle' => { en: 'Control', service_type: 'ACS' },
|
32
|
-
'Information' => { en: 'Information', service_type: 'FIS' },
|
33
|
-
'GCA' => { en: 'GCA', service_type: 'GCA' },
|
34
|
-
'Gonio' => { en: 'Gonio', service_type: 'VDF' },
|
35
|
-
'Prévol' => { en: 'Delivery', service_type: 'SMC' },
|
36
|
-
'Sol' => { en: 'Ground', service_type: 'SMC' },
|
37
|
-
'Tour' => { en: 'Tower', service_type: 'TWR' },
|
38
|
-
'Trafic' => { en: 'Apron', service_type: 'SMC' }
|
39
|
-
}.freeze
|
40
|
-
|
41
|
-
def parse
|
42
|
-
cache.service.css(%Q(Service[lk^="[LF]"][pk])).each do |service_node|
|
43
|
-
# Ignore private services/frequencies
|
44
|
-
next if service_node.(:IndicLieu) == 'XX'
|
45
|
-
# Load referenced airport
|
46
|
-
airport = given(service_node.at_css('Ad')&.attr('pk')) do
|
47
|
-
find_by(:airport, meta: _1).first
|
48
|
-
end
|
49
|
-
# Build addresses and services
|
50
|
-
case SOURCE_TYPES.fetch(type_for(service_node))
|
51
|
-
when :address
|
52
|
-
fail "dangling address without airport" unless airport
|
53
|
-
addresses_from(service_node).each { airport.add_address(_1) }
|
54
|
-
when :service
|
55
|
-
given service_from(service_node) do |service|
|
56
|
-
cache.frequence.css(%Q(Frequence:has(Service[pk="#{service_node['pk']}"]))).each do |frequence_node|
|
57
|
-
if frequency = frequency_from(frequence_node, service_node)
|
58
|
-
service.add_frequency frequency
|
59
|
-
end
|
60
|
-
end
|
61
|
-
if airport
|
62
|
-
airport.add_unit(service.unit) if airport.units.find(service.unit).none?
|
63
|
-
airport.add_service(service) if airport.services.find(service).none?
|
64
|
-
end
|
65
|
-
given service_node.at_css('Espace')&.attr('pk') do |espace_pk|
|
66
|
-
find_by(:airspace, meta: espace_pk).each do |airspace|
|
67
|
-
airspace.layers.each { _1.add_service(service) }
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
# Assign fallback address (default A/A frequency) to all yet radioless airports
|
74
|
-
find_by(:airport).each do |airport|
|
75
|
-
unless airport.services.find_by(:service, type: :aerodrome_control_tower_service).any? || airport.addresses.any?
|
76
|
-
airport.add_address(fallback_address_for(airport.name))
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
private
|
82
|
-
|
83
|
-
def type_for(service_node)
|
84
|
-
SOURCE_TYPES.include?(type = service_node.(:Service)) ? type : 'OTHER'
|
85
|
-
end
|
86
|
-
|
87
|
-
def addresses_from(service_node)
|
88
|
-
cache.frequence.css(%Q(Frequence:has(Service[pk="#{service_node['pk']}"]))).map do |frequence_node|
|
89
|
-
if frequency = frequency_from(frequence_node, service_node)
|
90
|
-
AIXM.address(
|
91
|
-
type: :radio_frequency,
|
92
|
-
address: frequency.transmission_f
|
93
|
-
).tap do |address|
|
94
|
-
address.remarks = {
|
95
|
-
'type' => service_node.(:Service),
|
96
|
-
'indicatif/callsign' => frequency.callsigns.map { "#{_2} (#{_1})" }.join("/n")
|
97
|
-
}.to_remarks
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end.compact
|
101
|
-
end
|
102
|
-
|
103
|
-
def fallback_address_for(callsign)
|
104
|
-
AIXM.address(
|
105
|
-
type: :radio_frequency,
|
106
|
-
address: AIXM.f(123.5, :mhz)
|
107
|
-
).tap do |address|
|
108
|
-
address.remarks = {
|
109
|
-
'type' => 'A/A',
|
110
|
-
'indicatif/callsign' => callsign
|
111
|
-
}.to_remarks
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def service_from(service_node)
|
116
|
-
service_type = CALLSIGNS.dig(service_node.(:IndicService), :service_type) || type_for(service_node)
|
117
|
-
service = find_by(:service, type: service_type).first
|
118
|
-
unit = service&.unit
|
119
|
-
unless service
|
120
|
-
service = AIXM.service(type: service_type)
|
121
|
-
unit = find_by(:unit, name: service_node.(:IndicLieu), type: service.guessed_unit_type).first
|
122
|
-
unless unit
|
123
|
-
unit = AIXM.unit(
|
124
|
-
source: source(section: 'GEN', position: service_node.line),
|
125
|
-
organisation: organisation_lf,
|
126
|
-
name: service_node.(:IndicLieu),
|
127
|
-
type: service.guessed_unit_type,
|
128
|
-
class: :icao
|
129
|
-
)
|
130
|
-
add unit
|
131
|
-
end
|
132
|
-
unit.add_service service
|
133
|
-
service
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def frequency_from(frequence_node, service_node)
|
138
|
-
frequency = frequence_node.(:Frequence).to_f
|
139
|
-
case
|
140
|
-
when frequency >= 137
|
141
|
-
nil
|
142
|
-
when frequency < 108
|
143
|
-
warn("ignoring too low frequency `#{frequency}'", severe: false)
|
144
|
-
nil
|
145
|
-
else
|
146
|
-
AIXM.frequency(
|
147
|
-
transmission_f: AIXM.f(frequency, :mhz),
|
148
|
-
callsigns: callsigns_from(service_node)
|
149
|
-
).tap do |frequency|
|
150
|
-
frequency.timetable = timetable_from(frequence_node.(:HorCode))
|
151
|
-
frequency.remarks = frequence_node.(:Remarque)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
def callsigns_from(service_node)
|
157
|
-
if service_node.(:IndicService) == '.' # auto-information
|
158
|
-
%i(fr en).to_h { [_1, '(auto)'] }
|
159
|
-
else
|
160
|
-
warn("language other than french") unless service_node.(:Langue) == 'fr'
|
161
|
-
english = CALLSIGNS.fetch(service_node.(:IndicService)).fetch(:en)
|
162
|
-
warn("no english translation for callsign `#{service_node.(:IndicService)}'") unless english
|
163
|
-
{
|
164
|
-
fr: "#{service_node.(:IndicLieu)} #{service_node.(:IndicService)}",
|
165
|
-
en: ("#{service_node.(:IndicLieu)} #{english}" if english)
|
166
|
-
}.compact
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|