aipp 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +2 -2
  3. data/CHANGELOG.md +17 -1
  4. data/README.md +269 -150
  5. data/exe/aip2aixm +2 -8
  6. data/exe/aip2ofmx +2 -8
  7. data/exe/notam2aixm +5 -0
  8. data/exe/notam2ofmx +5 -0
  9. data/lib/aipp/aip/README.md +10 -0
  10. data/lib/aipp/aip/executable.rb +40 -0
  11. data/lib/aipp/aip/parser.rb +9 -0
  12. data/lib/aipp/aip/runner.rb +85 -0
  13. data/lib/aipp/border.rb +2 -2
  14. data/lib/aipp/debugger.rb +14 -19
  15. data/lib/aipp/downloader/file.rb +57 -0
  16. data/lib/aipp/downloader/graphql.rb +29 -0
  17. data/lib/aipp/downloader/http.rb +48 -0
  18. data/lib/aipp/downloader.rb +78 -29
  19. data/lib/aipp/environment.rb +88 -0
  20. data/lib/aipp/executable.rb +36 -53
  21. data/lib/aipp/notam/README.md +25 -0
  22. data/lib/aipp/notam/executable.rb +27 -0
  23. data/lib/aipp/notam/parser.rb +9 -0
  24. data/lib/aipp/notam/runner.rb +28 -0
  25. data/lib/aipp/parser.rb +133 -160
  26. data/lib/aipp/patcher.rb +4 -5
  27. data/lib/aipp/regions/LF/README.md +6 -2
  28. data/lib/aipp/regions/LF/aip/aerodromes.rb +220 -0
  29. data/lib/aipp/regions/LF/aip/d_p_r_airspaces.rb +53 -0
  30. data/lib/aipp/regions/LF/aip/dangerous_activities.rb +48 -0
  31. data/lib/aipp/regions/LF/aip/designated_points.rb +44 -0
  32. data/lib/aipp/regions/LF/aip/helipads.rb +119 -0
  33. data/lib/aipp/regions/LF/aip/navigational_aids.rb +82 -0
  34. data/lib/aipp/regions/LF/aip/obstacles.rb +150 -0
  35. data/lib/aipp/regions/LF/aip/serviced_airspaces.rb +67 -0
  36. data/lib/aipp/regions/LF/aip/services.rb +169 -0
  37. data/lib/aipp/regions/LF/fixtures/aerodromes.yml +2 -2
  38. data/lib/aipp/regions/LF/helpers/base.rb +32 -32
  39. data/lib/aipp/regions/LS/README.md +59 -0
  40. data/lib/aipp/regions/LS/helpers/base.rb +111 -0
  41. data/lib/aipp/regions/LS/notam/ENR.rb +173 -0
  42. data/lib/aipp/runner.rb +152 -0
  43. data/lib/aipp/version.rb +1 -1
  44. data/lib/aipp.rb +30 -11
  45. data/lib/core_ext/array.rb +13 -0
  46. data/lib/core_ext/nokogiri.rb +56 -8
  47. data/lib/core_ext/string.rb +63 -1
  48. data.tar.gz.sig +0 -0
  49. metadata +115 -64
  50. metadata.gz.sig +0 -0
  51. data/lib/aipp/aip.rb +0 -166
  52. data/lib/aipp/regions/LF/aerodromes.rb +0 -223
  53. data/lib/aipp/regions/LF/d_p_r_airspaces.rb +0 -56
  54. data/lib/aipp/regions/LF/dangerous_activities.rb +0 -49
  55. data/lib/aipp/regions/LF/designated_points.rb +0 -47
  56. data/lib/aipp/regions/LF/helipads.rb +0 -122
  57. data/lib/aipp/regions/LF/navigational_aids.rb +0 -85
  58. data/lib/aipp/regions/LF/obstacles.rb +0 -153
  59. data/lib/aipp/regions/LF/serviced_airspaces.rb +0 -70
  60. 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