aixm 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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