aixm 1.0.0 → 1.1.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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +43 -13
  4. data/README.md +31 -20
  5. data/lib/aixm/a.rb +89 -71
  6. data/lib/aixm/association.rb +37 -27
  7. data/lib/aixm/classes.rb +5 -2
  8. data/lib/aixm/{feature → component}/address.rb +12 -9
  9. data/lib/aixm/component/approach_lighting.rb +136 -0
  10. data/lib/aixm/component/fato.rb +58 -42
  11. data/lib/aixm/component/frequency.rb +2 -2
  12. data/lib/aixm/component/geometry/arc.rb +1 -1
  13. data/lib/aixm/component/geometry/border.rb +1 -1
  14. data/lib/aixm/component/geometry/circle.rb +3 -3
  15. data/lib/aixm/component/geometry/point.rb +1 -1
  16. data/lib/aixm/component/geometry/rhumb_line.rb +1 -1
  17. data/lib/aixm/component/geometry.rb +3 -2
  18. data/lib/aixm/component/helipad.rb +26 -36
  19. data/lib/aixm/component/layer.rb +5 -3
  20. data/lib/aixm/component/lighting.rb +5 -5
  21. data/lib/aixm/component/runway.rb +81 -52
  22. data/lib/aixm/component/service.rb +12 -3
  23. data/lib/aixm/component/surface.rb +12 -12
  24. data/lib/aixm/component/timetable.rb +2 -2
  25. data/lib/aixm/component/vasis.rb +105 -0
  26. data/lib/aixm/component/vertical_limit.rb +3 -3
  27. data/lib/aixm/component.rb +10 -0
  28. data/lib/aixm/config.rb +2 -0
  29. data/lib/aixm/d.rb +16 -15
  30. data/lib/aixm/document.rb +10 -1
  31. data/lib/aixm/f.rb +1 -1
  32. data/lib/aixm/feature/airport.rb +34 -10
  33. data/lib/aixm/feature/airspace.rb +3 -0
  34. data/lib/aixm/feature/navigational_aid/dme.rb +29 -10
  35. data/lib/aixm/feature/navigational_aid/marker.rb +2 -2
  36. data/lib/aixm/feature/navigational_aid/tacan.rb +3 -2
  37. data/lib/aixm/feature/navigational_aid/vor.rb +32 -13
  38. data/lib/aixm/feature/navigational_aid.rb +1 -1
  39. data/lib/aixm/feature/obstacle.rb +6 -6
  40. data/lib/aixm/feature/obstacle_group.rb +6 -2
  41. data/lib/aixm/feature/organisation.rb +1 -0
  42. data/lib/aixm/feature/unit.rb +2 -1
  43. data/lib/aixm/feature.rb +3 -0
  44. data/lib/aixm/memoize.rb +27 -11
  45. data/lib/aixm/p.rb +3 -2
  46. data/lib/aixm/payload_hash.rb +1 -1
  47. data/lib/aixm/r.rb +62 -0
  48. data/lib/aixm/refinements.rb +4 -4
  49. data/lib/aixm/version.rb +1 -1
  50. data/lib/aixm/w.rb +2 -1
  51. data/lib/aixm/xy.rb +1 -1
  52. data/lib/aixm/z.rb +5 -4
  53. data/lib/aixm.rb +10 -5
  54. data/schemas/ofmx/0.1/OFMX-DataTypes.xsd +6 -0
  55. data/schemas/ofmx/0.1/OFMX-Snapshot.xsd +5 -0
  56. data.tar.gz.sig +0 -0
  57. metadata +8 -4
  58. metadata.gz.sig +0 -0
@@ -0,0 +1,136 @@
1
+ using AIXM::Refinements
2
+
3
+ module AIXM
4
+ class Component
5
+
6
+ # Approach lighting system (ALS)
7
+ #
8
+ # ===Cheat Sheet in Pseudo Code:
9
+ # approach_lighting = AIXM.approach_lighting(
10
+ # type: TYPES
11
+ # )
12
+ # approach_lighting.length = AIXM.d or nil
13
+ # approach_lighting.intensity = INTENSITIES or nil
14
+ # approach_lighting.sequenced_flash = true or false or nil (means: unknown, default)
15
+ # approach_lighting.flash_description = String or nil
16
+ # approach_lighting.remarks = String or nil
17
+ #
18
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airport#rda-runway-direction-approach-lighting
19
+ class ApproachLighting < Component
20
+ include AIXM::Association
21
+ include AIXM::Memoize
22
+
23
+ TYPES = {
24
+ A: :cat_1,
25
+ B: :cat_2,
26
+ C: :cat_3,
27
+ D: :cat_2_and_3,
28
+ E: :simple,
29
+ F: :circling,
30
+ G: :alignment,
31
+ ALSAF: :high_intensity,
32
+ MALS: :medium_intensity,
33
+ MALSR: :medium_intensity_with_alignment,
34
+ SALS: :short,
35
+ SSALS: :simplified_short,
36
+ SSALR: :simplified_short_with_alignment,
37
+ LDIN: :lead_in,
38
+ ODALS: :omni_directional,
39
+ AFOVRN: :usaf_overrun,
40
+ MILOVRN: :military_overrun,
41
+ OTHER: :other # specify in remarks
42
+ }.freeze
43
+
44
+ INTENSITIES = {
45
+ LIL: :low,
46
+ LIM: :medium,
47
+ LIH: :high,
48
+ OTHER: :other # specify in remarks
49
+ }.freeze
50
+
51
+ # @!method approach_lightable
52
+ # @return [AIXM::Component::Runway::Direction, AIXM::Component::FATO::Direction] approach lighted entity
53
+ belongs_to :approach_lightable
54
+
55
+ # @return [Symbol, nil] type of the approach lighting system (see {TYPES})
56
+ attr_reader :type
57
+
58
+ # @return [AIXM::D, nil] length
59
+ attr_reader :length
60
+
61
+ # @return [Symbol, nil] intensity of lights (see {INTENSITIES})
62
+ attr_reader :intensity
63
+
64
+ # @return [Boolean, nil] whether sequenced flash is available
65
+ attr_reader :sequenced_flash
66
+
67
+ # @return [String, nil] description of the flash sequence
68
+ attr_reader :flash_description
69
+
70
+ # @return [String, nil] free text remarks
71
+ attr_reader :remarks
72
+
73
+ def initialize(type:)
74
+ self.type = type
75
+ end
76
+
77
+ # @return [String]
78
+ def inspect
79
+ %Q(#<#{self.class} type=#{type.inspect}>)
80
+ end
81
+
82
+ def type=(value)
83
+ @type = TYPES.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid type")
84
+ end
85
+
86
+ def length=(value)
87
+ fail(ArgumentError, "invalid length") unless value.nil? || value.is_a?(AIXM::D)
88
+ @length = value
89
+ end
90
+
91
+ def intensity=(value)
92
+ @intensity = value.nil? ? nil : INTENSITIES.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid intensity")
93
+ end
94
+
95
+ def sequenced_flash=(value)
96
+ fail(ArgumentError, "invalid sequenced flash") unless [true, false, nil].include? value
97
+ @sequenced_flash = value
98
+ end
99
+
100
+ def flash_description=(value)
101
+ @flash_description = value&.to_s
102
+ end
103
+
104
+ def remarks=(value)
105
+ @remarks = value&.to_s
106
+ end
107
+
108
+ # @return [String] UID markup
109
+ def to_uid(as:)
110
+ builder = Builder::XmlMarkup.new(indent: 2)
111
+ builder.tag!(as) do |tag|
112
+ tag << approach_lightable.to_uid.indent(2)
113
+ tag.codeType(TYPES.key(type).to_s)
114
+ end
115
+ end
116
+ memoize :to_uid
117
+
118
+ # @return [String] AIXM or OFMX markup
119
+ def to_xml(as:)
120
+ builder = Builder::XmlMarkup.new(indent: 2)
121
+ builder.tag!(as) do |tag|
122
+ tag << to_uid(as: "#{as}Uid").indent(2)
123
+ if length
124
+ tag.valLen(length.dim.round)
125
+ tag.uomLen(length.unit.to_s.upcase)
126
+ end
127
+ tag.codeIntst(INTENSITIES.key(intensity).to_s) if intensity
128
+ tag.codeSequencedFlash(sequenced_flash ? 'Y' : 'N') unless sequenced_flash.nil?
129
+ tag.txtDescrFlash(flash_description) if flash_description
130
+ tag.txtRmk(remarks) if remarks
131
+ end
132
+ builder.target!
133
+ end
134
+ end
135
+ end
136
+ end
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- module Component
4
+ class Component
5
5
 
6
6
  # FATO (final approach and take-off area) for vertical take-off aircraft
7
7
  # such as helicopters.
@@ -10,8 +10,7 @@ module AIXM
10
10
  # fato = AIXM.fato(
11
11
  # name: String
12
12
  # )
13
- # fato.length = AIXM.d or nil # must use same unit as width
14
- # fato.width = AIXM.d or nil # must use same unit as length
13
+ # fato.dimensions = AIXM.r or nil
15
14
  # fato.surface = AIXM.surface
16
15
  # fato.marking = String or nil
17
16
  # fato.profile = String or nil
@@ -20,12 +19,15 @@ module AIXM
20
19
  # fato.add_direction(
21
20
  # name: String
22
21
  # ) do |direction|
23
- # direction.geographic_orientation = AIXM.a[precision=3] or nil
22
+ # direction.geographic_bearing = AIXM.a or nil
23
+ # direction.vasis = AIXM.vasis or nil (default: unspecified VASIS)
24
+ # fato.add_lighting = AIXM.lighting
25
+ # fato.add_approach_lighting = AIXM.approach_lighting
24
26
  # direction.remarks = String or nil
25
27
  # end
26
28
  #
27
29
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airport#fto-fato
28
- class FATO
30
+ class FATO < Component
29
31
  include AIXM::Association
30
32
  include AIXM::Memoize
31
33
 
@@ -40,12 +42,14 @@ module AIXM
40
42
 
41
43
  # @!method surface
42
44
  # @return [AIXM::Component::Surface] surface of the FATO
45
+ #
43
46
  # @!method surface=(surface)
44
47
  # @param surface [AIXM::Component::Surface]
45
48
  has_one :surface
46
49
 
47
50
  # @!method directions
48
51
  # @return [Array<AIXM::Component::FATO::Direction>] maps added direction names to full FATO directions
52
+ #
49
53
  # @!method add_direction(direction)
50
54
  # @param direction [AIXM::A] name of the FATO direction (e.g. "12" or "16L")
51
55
  # @return [self]
@@ -62,11 +66,8 @@ module AIXM
62
66
  # @return [String] full name (e.g. "H1")
63
67
  attr_reader :name
64
68
 
65
- # @return [AIXM::D, nil] length
66
- attr_reader :length
67
-
68
- # @return [AIXM::D, nil] width
69
- attr_reader :width
69
+ # @return [AIXM::R, nil] dimensions
70
+ attr_reader :dimensions
70
71
 
71
72
  # @return [String, nil] markings
72
73
  attr_reader :marking
@@ -95,20 +96,9 @@ module AIXM
95
96
  @name = value.uptrans
96
97
  end
97
98
 
98
- def length=(value)
99
- @length = if value
100
- fail(ArgumentError, "invalid length") unless value.is_a?(AIXM::D) && value.dist > 0
101
- fail(ArgumentError, "invalid length unit") if width && width.unit != value.unit
102
- @length = value
103
- end
104
- end
105
-
106
- def width=(value)
107
- @width = if value
108
- fail(ArgumentError, "invalid width") unless value.is_a?(AIXM::D) && value.dist > 0
109
- fail(ArgumentError, "invalid width unit") if length && length.unit != value.unit
110
- @width = value
111
- end
99
+ def dimensions=(value)
100
+ fail(ArgumentError, "invalid dimensions") unless value.nil? || value.is_a?(AIXM::R)
101
+ @dimensions = value
112
102
  end
113
103
 
114
104
  def marking=(value)
@@ -142,10 +132,11 @@ module AIXM
142
132
  builder = Builder::XmlMarkup.new(indent: 2)
143
133
  builder.Fto do |fto|
144
134
  fto << to_uid.indent(2)
145
- fto.valLen(length.dist.trim) if length
146
- fto.valWid(width.dist.trim) if width
147
- fto.uomDim(length.unit.to_s.upcase) if length
148
- fto.uomDim(width.unit.to_s.upcase) if width && !length
135
+ if dimensions
136
+ fto.valLen(dimensions.length.to_m.dim.trim)
137
+ fto.valWid(dimensions.width.to_m.dim.trim)
138
+ fto.uomDim('M')
139
+ end
149
140
  unless (xml = surface.to_xml).empty?
150
141
  fto << xml.indent(2)
151
142
  end
@@ -169,10 +160,19 @@ module AIXM
169
160
 
170
161
  # @!method lightings
171
162
  # @return [Array<AIXM::Component::Lighting>] installed lighting systems
163
+ #
172
164
  # @!method add_lighting(lighting)
173
165
  # @param lighting [AIXM::Component::Lighting]
174
166
  has_many :lightings, as: :lightable
175
167
 
168
+ # @!method approach_lightings
169
+ # @return [Array<AIXM::Component::ApproachLighting>] installed approach lighting systems
170
+ #
171
+ # @!method add_approach_lighting(approach_lighting)
172
+ # @param approach_lighting [AIXM::Component::ApproachLighting]
173
+ # @return [self]
174
+ has_many :approach_lightings, as: :approach_lightable
175
+
176
176
  # @!method fato
177
177
  # @return [AIXM::Component::FATO] FATO the FATO direction is further describing
178
178
  belongs_to :fato
@@ -180,19 +180,24 @@ module AIXM
180
180
  # @return [AIXM::A] name of the FATO direction (e.g. "12" or "16L")
181
181
  attr_reader :name
182
182
 
183
- # @return [AIXM::A, nil] geographic orientation (true bearing) in degrees
184
- attr_reader :geographic_orientation
183
+ # @return [AIXM::A, nil] (true) geographic bearing in degrees
184
+ attr_reader :geographic_bearing
185
+
186
+ # @return [AIXM::Component::VASIS, nil] visual approach slope indicator
187
+ # system
188
+ attr_reader :vasis
185
189
 
186
190
  # @return [String, nil] free text remarks
187
191
  attr_reader :remarks
188
192
 
189
193
  def initialize(name:)
190
194
  self.name = name
195
+ self.vasis = AIXM.vasis
191
196
  end
192
197
 
193
198
  # @return [String]
194
199
  def inspect
195
- %Q(#<#{self.class} airport=#{fato&.airport&.id.inspect} name=#{name.inspect}>)
200
+ %Q(#<#{self.class} airport=#{fato&.airport&.id.inspect} name=#{name.to_s(:runway).inspect}>)
196
201
  end
197
202
 
198
203
  def name=(value)
@@ -200,29 +205,34 @@ module AIXM
200
205
  @name = AIXM.a(value)
201
206
  end
202
207
 
203
- def geographic_orientation=(value)
204
- return @geographic_orientation = nil if value.nil?
205
- fail(ArgumentError, "invalid geographic orientation") unless value.is_a? AIXM::A
206
- @geographic_orientation = value
208
+ def geographic_bearing=(value)
209
+ return @geographic_bearing = nil if value.nil?
210
+ fail(ArgumentError, "invalid geographic bearing") unless value.is_a? AIXM::A
211
+ @geographic_bearing = value
207
212
  end
208
213
 
209
214
  def remarks=(value)
210
215
  @remarks = value&.to_s
211
216
  end
212
217
 
213
- # @return [AIXM::A] magnetic orientation (magnetic bearing) in degrees
214
- def magnetic_orientation
215
- if geographic_orientation && fato.airport.declination
216
- geographic_orientation - fato.airport.declination
218
+ # @return [AIXM::A] magnetic bearing in degrees
219
+ def magnetic_bearing
220
+ if geographic_bearing && fato.airport.declination
221
+ geographic_bearing - fato.airport.declination
217
222
  end
218
223
  end
219
224
 
225
+ def vasis=(value)
226
+ fail(ArgumentError, "invalid vasis") unless value.nil? || value.is_a?(AIXM::Component::VASIS)
227
+ @vasis = value
228
+ end
229
+
220
230
  # @return [String] UID markup
221
231
  def to_uid
222
232
  builder = Builder::XmlMarkup.new(indent: 2)
223
233
  builder.FdnUid do |fdn_uid|
224
234
  fdn_uid << fato.to_uid.indent(2)
225
- fdn_uid.txtDesig(name)
235
+ fdn_uid.txtDesig(name.to_s(:runway))
226
236
  end
227
237
  end
228
238
  memoize :to_uid
@@ -232,13 +242,19 @@ module AIXM
232
242
  builder = Builder::XmlMarkup.new(indent: 2)
233
243
  builder.Fdn do |fdn|
234
244
  fdn << to_uid.indent(2)
235
- fdn.valTrueBrg(geographic_orientation) if geographic_orientation
236
- fdn.valMagBrg(magnetic_orientation) if magnetic_orientation
245
+ fdn.valTrueBrg(geographic_bearing.to_s(:bearing)) if geographic_bearing
246
+ fdn.valMagBrg(magnetic_bearing.to_s(:bearing)) if magnetic_bearing
247
+ if vasis
248
+ fdn << vasis.to_xml.indent(2)
249
+ end
237
250
  fdn.txtRmk(remarks) if remarks
238
251
  end
239
252
  lightings.each do |lighting|
240
253
  builder << lighting.to_xml(as: :Fls)
241
254
  end
255
+ approach_lightings.each do |approach_lighting|
256
+ builder << approach_lighting.to_xml(as: :Fda)
257
+ end
242
258
  builder.target!
243
259
  end
244
260
  end
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- module Component
4
+ class Component
5
5
 
6
6
  # Voice frequencies used by a service.
7
7
  #
@@ -21,7 +21,7 @@ module AIXM
21
21
  # frequency.remarks = String or nil
22
22
  #
23
23
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Organisation#fqy-frequency
24
- class Frequency
24
+ class Frequency < Component
25
25
  include AIXM::Association
26
26
  include AIXM::Memoize
27
27
 
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- module Component
4
+ class Component
5
5
  class Geometry
6
6
 
7
7
  # Arcs are clockwise or counter clockwise circle segments around a
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- module Component
4
+ class Component
5
5
  class Geometry
6
6
 
7
7
  # Borders are following natural or artifical border lines referenced by
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- module Component
4
+ class Component
5
5
  class Geometry
6
6
 
7
7
  # Circles are defined by a {#center_xy} and a {#radius}.
@@ -41,7 +41,7 @@ module AIXM
41
41
  end
42
42
 
43
43
  def radius=(value)
44
- fail(ArgumentError, "invalid radius") unless value.is_a?(AIXM::D) && value.dist > 0
44
+ fail(ArgumentError, "invalid radius") unless value.is_a?(AIXM::D) && value.dim > 0
45
45
  @radius = value
46
46
  end
47
47
 
@@ -64,7 +64,7 @@ module AIXM
64
64
  # and on the circumference of the circle.
65
65
  def north_xy
66
66
  AIXM.xy(
67
- lat: center_xy.lat + radius.to_km.dist / (AIXM::XY::EARTH_RADIUS / 1000) * 180 / Math::PI,
67
+ lat: center_xy.lat + radius.to_km.dim / (AIXM::XY::EARTH_RADIUS / 1000) * 180 / Math::PI,
68
68
  long: center_xy.long
69
69
  )
70
70
  end
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- module Component
4
+ class Component
5
5
  class Geometry
6
6
 
7
7
  # Either an individual point or the starting point of a great circle
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- module Component
4
+ class Component
5
5
  class Geometry
6
6
 
7
7
  # Starting point of a rhumb line which describes a spiral on a sphere
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- module Component
4
+ class Component
5
5
 
6
6
  # Geometries define a 3D airspace horizontally.
7
7
  #
@@ -26,7 +26,7 @@ module AIXM
26
26
  # geometry.add_segment(AIXM.point(...))
27
27
  #
28
28
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace#avx-border-vertex
29
- class Geometry
29
+ class Geometry < Component
30
30
  include AIXM::Association
31
31
 
32
32
  # @!method segments
@@ -35,6 +35,7 @@ module AIXM
35
35
  # AIXM::Component::Geometry::Arc,
36
36
  # AIXM::Component::Geometry::Circle,
37
37
  # AIXM::Component::Geometry::Border>] points, rhumb lines, arcs, borders or circle
38
+ #
38
39
  # @!method add_segment(segment)
39
40
  # @param segment [AIXM::Component::Geometry::Point,
40
41
  # AIXM::Component::Geometry::RhumbLine,
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- module Component
4
+ class Component
5
5
 
6
6
  # Helipads are TLOF (touch-down and lift-off areas) for vertical take-off
7
7
  # aircraft such as helicopters.
@@ -9,24 +9,24 @@ module AIXM
9
9
  # ===Cheat Sheet in Pseudo Code:
10
10
  # helipad = AIXM.helipad(
11
11
  # name: String
12
- # xy = AIXM.xy
12
+ # xy: AIXM.xy
13
13
  # )
14
14
  # helipad.z = AIXM.z or nil
15
- # helipad.length = AIXM.d or nil # must use same unit as width
16
- # helipad.width = AIXM.d or nil # must use same unit as length
15
+ # helipad.dimensions = AIXM.r or nil
17
16
  # helipad.surface = AIXM.surface
18
17
  # helipad.marking = String or nil
18
+ # helipad.add_lighting = AIXM.lighting
19
19
  # helipad.fato = AIXM.fato or nil
20
- # helipad.helicopter_class = HELICOPTER_CLASSES or nil
20
+ # helipad.performance_class = PERFORMANCE_CLASSES or nil
21
21
  # helipad.status = STATUSES or nil
22
22
  # helipad.remarks = String or nil
23
23
  #
24
24
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airport#tla-helipad-tlof
25
- class Helipad
25
+ class Helipad < Component
26
26
  include AIXM::Association
27
27
  include AIXM::Memoize
28
28
 
29
- HELICOPTER_CLASSES = {
29
+ PERFORMANCE_CLASSES = {
30
30
  '1': :'1',
31
31
  '2': :'2',
32
32
  '3': :'3',
@@ -44,18 +44,21 @@ module AIXM
44
44
 
45
45
  # @!method fato
46
46
  # @return [AIXM::Component::FATO, nil] FATO the helipad is situated on
47
+ #
47
48
  # @!method fato=(fato)
48
49
  # @param fato [AIXM::Component::FATO, nil]
49
50
  has_one :fato, allow_nil: true
50
51
 
51
52
  # @!method surface
52
53
  # @return [AIXM::Component::Surface] surface of the helipad
54
+ #
53
55
  # @!method surface=(surface)
54
56
  # @param surface [AIXM::Component::Surface]
55
- has_one :surface
57
+ has_one :surface, accept: 'AIXM::Component::Surface'
56
58
 
57
59
  # @!method lightings
58
60
  # @return [Array<AIXM::Component::Lighting>] installed lighting systems
61
+ #
59
62
  # @!method add_lighting(lighting)
60
63
  # @param lighting [AIXM::Component::Lighting]
61
64
  # @return [self]
@@ -74,17 +77,14 @@ module AIXM
74
77
  # @return [AIXM::Z, nil] elevation in +:qnh+
75
78
  attr_reader :z
76
79
 
77
- # @return [AIXM::D, nil] length
78
- attr_reader :length
79
-
80
- # @return [AIXM::D, nil] width
81
- attr_reader :width
80
+ # @return [AIXM::R, nil] dimensions
81
+ attr_reader :dimensions
82
82
 
83
83
  # @return [String, nil] markings
84
84
  attr_reader :marking
85
85
 
86
- # @return [Integer, Symbol, nil] suitable helicopter class
87
- attr_reader :helicopter_class
86
+ # @return [Integer, Symbol, nil] suitable performance class
87
+ attr_reader :performance_class
88
88
 
89
89
  # @return [Symbol, nil] status of the helipad (see {STATUSES}) or +nil+ for normal operation
90
90
  attr_reader :status
@@ -117,28 +117,17 @@ module AIXM
117
117
  @z = value
118
118
  end
119
119
 
120
- def length=(value)
121
- @length = if value
122
- fail(ArgumentError, "invalid length") unless value.is_a?(AIXM::D) && value.dist > 0
123
- fail(ArgumentError, "invalid length unit") if width && width.unit != value.unit
124
- @length = value
125
- end
126
- end
127
-
128
- def width=(value)
129
- @width = if value
130
- fail(ArgumentError, "invalid width") unless value.is_a?(AIXM::D) && value.dist > 0
131
- fail(ArgumentError, "invalid width unit") if length && length.unit != value.unit
132
- @width = value
133
- end
120
+ def dimensions=(value)
121
+ fail(ArgumentError, "invalid dimensions") unless value.nil? || value.is_a?(AIXM::R)
122
+ @dimensions = value
134
123
  end
135
124
 
136
125
  def marking=(value)
137
126
  @marking = value&.to_s
138
127
  end
139
128
 
140
- def helicopter_class=(value)
141
- @helicopter_class = value.nil? ? nil : (HELICOPTER_CLASSES.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid helicopter class"))
129
+ def performance_class=(value)
130
+ @performance_class = value.nil? ? nil : (PERFORMANCE_CLASSES.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid performance class"))
142
131
  end
143
132
 
144
133
  def status=(value)
@@ -172,14 +161,15 @@ module AIXM
172
161
  tla.valElev(z.alt)
173
162
  tla.uomDistVer(z.unit.upcase.to_s)
174
163
  end
175
- tla.valLen(length.dist.trim) if length
176
- tla.valWid(width.dist.trim) if width
177
- tla.uomDim(length.unit.to_s.upcase) if length
178
- tla.uomDim(width.unit.to_s.upcase) if width && !length
164
+ if dimensions
165
+ tla.valLen(dimensions.length.to_m.dim.trim)
166
+ tla.valWid(dimensions.width.to_m.dim.trim)
167
+ tla.uomDim('M')
168
+ end
179
169
  unless (xml = surface.to_xml).empty?
180
170
  tla << xml.indent(2)
181
171
  end
182
- tla.codeClassHel(HELICOPTER_CLASSES.key(helicopter_class).to_s) if helicopter_class
172
+ tla.codeClassHel(PERFORMANCE_CLASSES.key(performance_class).to_s) if performance_class
183
173
  tla.txtMarking(marking) if marking
184
174
  tla.codeSts(STATUSES.key(status).to_s) if status
185
175
  tla.txtRmk(remarks) if remarks
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- module Component
4
+ class Component
5
5
 
6
6
  # Each airspace has one or more layers with optional airspace class and
7
7
  # mandatory vertical limit.
@@ -16,10 +16,10 @@ module AIXM
16
16
  # layer.timetable = AIXM.timetable or nil
17
17
  # layer.selective = true or false (default)
18
18
  # layer.remarks = String or nil
19
- # airspace.add_service(AIXM.service)
19
+ # layer.add_service(AIXM.service)
20
20
  #
21
21
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace
22
- class Layer
22
+ class Layer < Component
23
23
  include AIXM::Association
24
24
 
25
25
  CLASSES = (:A..:G).freeze
@@ -90,12 +90,14 @@ module AIXM
90
90
 
91
91
  # @!method vertical_limit
92
92
  # @return [AIXM::Component::VerticalLimit] vertical limit of this layer
93
+ #
93
94
  # @!method vertical_limit=(vertical_limit)
94
95
  # @param vertical_limit [AIXM::Component::VerticalLimit]
95
96
  has_one :vertical_limit
96
97
 
97
98
  # @!method services
98
99
  # @return [Array<AIXM::Component::Service>] services
100
+ #
99
101
  # @!method add_service(service)
100
102
  # @param service [AIXM::Component::Service]
101
103
  has_many :services
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- module Component
4
+ class Component
5
5
 
6
6
  # Lighting of a runway, helipad etc
7
7
  #
@@ -17,7 +17,7 @@ module AIXM
17
17
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airport#rls-runway-direction-lighting
18
18
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airport#fls-fato-direction-lighting
19
19
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airport#tls-helipad-tlof-lighting
20
- class Lighting
20
+ class Lighting < Component
21
21
  include AIXM::Association
22
22
  include AIXM::Memoize
23
23
 
@@ -38,14 +38,14 @@ module AIXM
38
38
  HOLDBAY: :taxyway_hold_bay,
39
39
  RTWYINT: :rapid_taxiway_intersection,
40
40
  OTHER: :other # specify in remarks
41
- }
41
+ }.freeze
42
42
 
43
43
  INTENSITIES = {
44
44
  LIL: :low,
45
45
  LIM: :medium,
46
46
  LIH: :high,
47
47
  OTHER: :other # specify in remarks
48
- }
48
+ }.freeze
49
49
 
50
50
  COLORS = {
51
51
  YEL: :yellow,
@@ -55,7 +55,7 @@ module AIXM
55
55
  GRN: :green,
56
56
  PRP: :purple,
57
57
  OTHER: :other # specify in remarks
58
- }
58
+ }.freeze
59
59
 
60
60
  # @!method lightable
61
61
  # @return [AIXM::Component::Runway::Direction, AIXM::Component::FATO::Direction, AIXM::Component::Helipad] lighted entity