aixm 0.3.8 → 0.3.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +1 -0
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG.md +33 -3
  5. data/README.md +166 -56
  6. data/exe/ckmid +14 -0
  7. data/exe/mkmid +14 -0
  8. data/lib/aixm.rb +16 -6
  9. data/lib/aixm/association.rb +369 -0
  10. data/lib/aixm/classes.rb +43 -0
  11. data/lib/aixm/component/fato.rb +45 -53
  12. data/lib/aixm/component/frequency.rb +11 -12
  13. data/lib/aixm/component/geometry.rb +36 -38
  14. data/lib/aixm/component/geometry/arc.rb +2 -2
  15. data/lib/aixm/component/geometry/border.rb +6 -3
  16. data/lib/aixm/component/geometry/circle.rb +8 -2
  17. data/lib/aixm/component/geometry/point.rb +8 -2
  18. data/lib/aixm/component/helipad.rb +30 -38
  19. data/lib/aixm/component/layer.rb +28 -19
  20. data/lib/aixm/component/lighting.rb +12 -13
  21. data/lib/aixm/component/runway.rb +44 -48
  22. data/lib/aixm/{feature → component}/service.rb +37 -36
  23. data/lib/aixm/component/surface.rb +3 -3
  24. data/lib/aixm/component/timetable.rb +2 -2
  25. data/lib/aixm/component/{vertical_limits.rb → vertical_limit.rb} +12 -6
  26. data/lib/aixm/config.rb +2 -1
  27. data/lib/aixm/document.rb +27 -50
  28. data/lib/aixm/executables.rb +85 -0
  29. data/lib/aixm/feature.rb +13 -3
  30. data/lib/aixm/feature/address.rb +12 -13
  31. data/lib/aixm/feature/airport.rb +103 -128
  32. data/lib/aixm/feature/airspace.rb +44 -17
  33. data/lib/aixm/feature/navigational_aid.rb +7 -9
  34. data/lib/aixm/feature/navigational_aid/designated_point.rb +13 -15
  35. data/lib/aixm/feature/navigational_aid/dme.rb +11 -12
  36. data/lib/aixm/feature/navigational_aid/marker.rb +7 -3
  37. data/lib/aixm/feature/navigational_aid/ndb.rb +7 -3
  38. data/lib/aixm/feature/navigational_aid/tacan.rb +7 -3
  39. data/lib/aixm/feature/navigational_aid/vor.rb +23 -15
  40. data/lib/aixm/feature/obstacle.rb +29 -43
  41. data/lib/aixm/feature/obstacle_group.rb +37 -34
  42. data/lib/aixm/feature/organisation.rb +21 -5
  43. data/lib/aixm/feature/unit.rb +36 -46
  44. data/lib/aixm/memoize.rb +89 -0
  45. data/lib/aixm/object.rb +9 -0
  46. data/lib/aixm/payload_hash.rb +114 -0
  47. data/lib/aixm/refinements.rb +29 -76
  48. data/lib/aixm/shortcuts.rb +5 -42
  49. data/lib/aixm/version.rb +1 -1
  50. data/lib/aixm/xy.rb +1 -1
  51. data/schemas/ofmx/0/OFMX-Features.xsd +152 -20
  52. data/schemas/ofmx/0/OFMX-Snapshot.xsd +0 -5
  53. metadata +107 -156
  54. metadata.gz.sig +2 -0
  55. data/.github/workflows/test.yml +0 -26
  56. data/.gitignore +0 -6
  57. data/.ruby-version +0 -1
  58. data/.yardopts +0 -3
  59. data/Guardfile +0 -8
  60. data/aixm.gemspec +0 -35
  61. data/gems.rb +0 -3
  62. data/lib/aixm/component.rb +0 -6
  63. data/rakefile.rb +0 -36
  64. data/spec/factory.rb +0 -559
  65. data/spec/lib/aixm/a_spec.rb +0 -203
  66. data/spec/lib/aixm/component/fato_spec.rb +0 -267
  67. data/spec/lib/aixm/component/frequency_spec.rb +0 -74
  68. data/spec/lib/aixm/component/geometry/arc_spec.rb +0 -73
  69. data/spec/lib/aixm/component/geometry/border_spec.rb +0 -38
  70. data/spec/lib/aixm/component/geometry/circle_spec.rb +0 -68
  71. data/spec/lib/aixm/component/geometry/point_spec.rb +0 -37
  72. data/spec/lib/aixm/component/geometry_spec.rb +0 -316
  73. data/spec/lib/aixm/component/helipad_spec.rb +0 -193
  74. data/spec/lib/aixm/component/layer_spec.rb +0 -135
  75. data/spec/lib/aixm/component/lighting_spec.rb +0 -94
  76. data/spec/lib/aixm/component/runway_spec.rb +0 -479
  77. data/spec/lib/aixm/component/surface_spec.rb +0 -124
  78. data/spec/lib/aixm/component/timetable_spec.rb +0 -47
  79. data/spec/lib/aixm/component/vertical_limits_spec.rb +0 -94
  80. data/spec/lib/aixm/config_spec.rb +0 -41
  81. data/spec/lib/aixm/d_spec.rb +0 -150
  82. data/spec/lib/aixm/document_spec.rb +0 -1884
  83. data/spec/lib/aixm/errors_spec.rb +0 -14
  84. data/spec/lib/aixm/f_spec.rb +0 -85
  85. data/spec/lib/aixm/feature/address_spec.rb +0 -60
  86. data/spec/lib/aixm/feature/airport_spec.rb +0 -776
  87. data/spec/lib/aixm/feature/airspace_spec.rb +0 -394
  88. data/spec/lib/aixm/feature/navigational_aid/designated_point_spec.rb +0 -103
  89. data/spec/lib/aixm/feature/navigational_aid/dme_spec.rb +0 -98
  90. data/spec/lib/aixm/feature/navigational_aid/marker_spec.rb +0 -85
  91. data/spec/lib/aixm/feature/navigational_aid/ndb_spec.rb +0 -95
  92. data/spec/lib/aixm/feature/navigational_aid/tacan_spec.rb +0 -94
  93. data/spec/lib/aixm/feature/navigational_aid/vor_spec.rb +0 -251
  94. data/spec/lib/aixm/feature/navigational_aid_spec.rb +0 -52
  95. data/spec/lib/aixm/feature/obstacle_group_spec.rb +0 -330
  96. data/spec/lib/aixm/feature/obstacle_spec.rb +0 -284
  97. data/spec/lib/aixm/feature/organisation_spec.rb +0 -83
  98. data/spec/lib/aixm/feature/service_spec.rb +0 -59
  99. data/spec/lib/aixm/feature/unit_spec.rb +0 -238
  100. data/spec/lib/aixm/feature_spec.rb +0 -38
  101. data/spec/lib/aixm/p_spec.rb +0 -189
  102. data/spec/lib/aixm/refinements_spec.rb +0 -430
  103. data/spec/lib/aixm/version_spec.rb +0 -7
  104. data/spec/lib/aixm/w_spec.rb +0 -150
  105. data/spec/lib/aixm/xy_spec.rb +0 -180
  106. data/spec/lib/aixm/z_spec.rb +0 -94
  107. data/spec/macros/marking.rb +0 -12
  108. data/spec/macros/organisation.rb +0 -11
  109. data/spec/macros/remarks.rb +0 -12
  110. data/spec/macros/timetable.rb +0 -11
  111. data/spec/macros/xy.rb +0 -11
  112. data/spec/macros/z_qnh.rb +0 -11
  113. data/spec/sounds/failure.mp3 +0 -0
  114. data/spec/sounds/success.mp3 +0 -0
  115. data/spec/spec_helper.rb +0 -62
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- class Component
4
+ module Component
5
5
 
6
6
  # Frequencies used by a service.
7
7
  #
@@ -20,8 +20,11 @@ module AIXM
20
20
  # frequency.timetable = AIXM.timetable or nil
21
21
  # frequency.remarks = String or nil
22
22
  #
23
- # @see https://github.com/openflightmaps/ofmx/wiki/Organisation#fqy-frequency
23
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Organisation#fqy-frequency
24
24
  class Frequency
25
+ include AIXM::Association
26
+ include AIXM::Memoize
27
+
25
28
  TYPES = {
26
29
  STD: :standard,
27
30
  ALT: :alternative,
@@ -32,8 +35,9 @@ module AIXM
32
35
  OTHER: :other # specify in remarks
33
36
  }.freeze
34
37
 
35
- # @return [AIXM::Feature::Service] service the frequency belongs to
36
- attr_reader :service
38
+ # @!method service
39
+ # @return [AIXM::Component::Service] service the frequency belongs to
40
+ belongs_to :service
37
41
 
38
42
  # @return [AIXM::F] frequency for transmission (outgoing)
39
43
  attr_reader :transmission_f
@@ -68,12 +72,6 @@ module AIXM
68
72
  %Q(#<#{self.class} transmission_f=#{transmission_f.inspect} callsigns=#{callsigns.inspect}>)
69
73
  end
70
74
 
71
- def service=(value)
72
- fail(ArgumentError, "invalid service") unless value.is_a? AIXM::Feature::Service
73
- @service = value
74
- end
75
- private :service=
76
-
77
75
  def transmission_f=(value)
78
76
  fail(ArgumentError, "invalid transmission_f") unless value.is_a? AIXM::F
79
77
  @transmission_f = value
@@ -81,7 +79,7 @@ module AIXM
81
79
 
82
80
  def callsigns=(value)
83
81
  fail(ArgumentError, "invalid callsigns") unless value.is_a?(Hash)
84
- @callsigns = value.transform_keys { |k| k.to_sym.downcase }.transform_values { |v| v.to_s.uptrans }
82
+ @callsigns = value.transform_keys { _1.to_sym.downcase }.transform_values { _1.to_s.uptrans }
85
83
  end
86
84
 
87
85
  def reception_f=(value)
@@ -108,8 +106,9 @@ module AIXM
108
106
  builder.FqyUid do |fqy_uid|
109
107
  fqy_uid << service.to_uid.indent(2)
110
108
  fqy_uid.valFreqTrans(transmission_f.freq)
111
- end.insert_payload_hash(region: AIXM.config.mid_region)
109
+ end
112
110
  end
111
+ memoize :to_uid
113
112
 
114
113
  # @return [String] AIXM or OFMX markup
115
114
  def to_xml
@@ -1,11 +1,9 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- class Component
4
+ module Component
5
5
 
6
- # Geometries define a 3D airspace horizontally. It's either exactly one
7
- # circle or at least three points, arcs and borders (the last of which
8
- # has to be a point with the same coordinates as the first).
6
+ # Geometries define a 3D airspace horizontally.
9
7
  #
10
8
  # For a geometry to be valid, it must be comprised of either:
11
9
  # * exactly one point
@@ -15,7 +13,7 @@ module AIXM
15
13
  #
16
14
  # ===Cheat Sheet in Pseudo Code:
17
15
  # geometry = AIXM.geometry
18
- # geometry << AIXM.point or AIXM.arc or AIXM.border or AIXM.circle
16
+ # geometry.add_segment(AIXM.point or AIXM.arc or AIXM.border or AIXM.circle)
19
17
  #
20
18
  # @example Built by passing elements to the initializer
21
19
  # geometry = AIXM.geometry(
@@ -23,26 +21,33 @@ module AIXM
23
21
  # AIXM.point(...)
24
22
  # )
25
23
  #
26
- # @example Built by adding elements
24
+ # @example Built by adding segments
27
25
  # geometry = AIXM.geometry
28
- # geometry << AIXM.point(...)
29
- # geometry.concat [AIXM.point(...), AIXM.point(...), ...]
26
+ # geometry.add_segment(AIXM.point(...))
30
27
  #
31
- # @see https://github.com/openflightmaps/ofmx/wiki/Airspace#avx-border-vertex
28
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace#avx-border-vertex
32
29
  class Geometry
33
- include Enumerable
34
- extend Forwardable
30
+ include AIXM::Association
35
31
 
36
- # @!method each
37
- # @return [Enumerator] see Array#each
38
- # @!method <<
39
- # @return [Array] see Array#<<
40
- # @!method concat
41
- # @return [Array] see Array#concat
42
- def_delegators :@result_array, :each, :<<, :concat
32
+ # @!method segments
33
+ # @return [Array<AIXM::Component::Geometry::Point,
34
+ # AIXM::Component::Geometry::Arc,
35
+ # AIXM::Component::Geometry::Border,
36
+ # AIXM::Component::Geometry::Circle>] points, arcs, borders or circle
37
+ # @!method add_segment(segment)
38
+ # @param segment [AIXM::Component::Geometry::Point,
39
+ # AIXM::Component::Geometry::Arc,
40
+ # AIXM::Component::Geometry::Border,
41
+ # AIXM::Component::Geometry::Circle]
42
+ # @return [self]
43
+ has_many :segments, accept: %i(point arc border circle)
44
+
45
+ # @!method airspace
46
+ # @return [AIXM::Feature::Airspace] airspace the geometry defines
47
+ belongs_to :airspace
43
48
 
44
49
  def initialize(*segments)
45
- @result_array = segments
50
+ segments.each { add_segment(_1) }
46
51
  end
47
52
 
48
53
  # @return [String]
@@ -50,14 +55,6 @@ module AIXM
50
55
  %Q(#<#{self.class} segments=#{segments.count.inspect}>)
51
56
  end
52
57
 
53
- # @return [Array<AIXM::Component::Geometry::Point,
54
- # AIXM::Component::Geometry::Arc,
55
- # AIXM::Component::Geometry::Border,
56
- # AIXM::Component::Geometry::Circle>] points, arcs, borders or circle
57
- def segments
58
- @result_array
59
- end
60
-
61
58
  # @return [Boolean] whether the geometry is closed
62
59
  def closed?
63
60
  point? || circle? || polygon?
@@ -66,26 +63,27 @@ module AIXM
66
63
  # @return [String] AIXM or OFMX markup
67
64
  def to_xml
68
65
  fail(GeometryError.new("geometry is not closed", self)) unless closed?
69
- @result_array.map { |h| h.to_xml }.join
66
+ segments.map { _1.to_xml }.join
70
67
  end
71
68
 
72
- private
73
-
69
+ # @return [Boolean] Single point geometry?
74
70
  def point?
75
- @result_array.size == 1 &&
76
- @result_array.first.is_a?(AIXM::Component::Geometry::Point)
71
+ segments.size == 1 &&
72
+ segments.first.is_a?(AIXM::Component::Geometry::Point)
77
73
  end
78
74
 
75
+ # @return [Boolean] Circle shaped geometry?
79
76
  def circle?
80
- @result_array.size == 1 &&
81
- @result_array.first.is_a?(AIXM::Component::Geometry::Circle)
77
+ segments.size == 1 &&
78
+ segments.first.is_a?(AIXM::Component::Geometry::Circle)
82
79
  end
83
80
 
81
+ # @return [Boolean] Polygon shaped geometry?
84
82
  def polygon?
85
- @result_array.size >= 3 &&
86
- !@result_array.any? { |h| h.is_a?(AIXM::Component::Geometry::Circle) } &&
87
- @result_array.last.is_a?(AIXM::Component::Geometry::Point) &&
88
- @result_array.first.xy == @result_array.last.xy
83
+ segments.size >= 3 &&
84
+ !segments.any? { _1.is_a?(AIXM::Component::Geometry::Circle) } &&
85
+ segments.last.is_a?(AIXM::Component::Geometry::Point) &&
86
+ segments.first.xy == segments.last.xy
89
87
  end
90
88
  end
91
89
 
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- class Component
4
+ module Component
5
5
  class Geometry
6
6
 
7
7
  # Arcs are clockwise or counter clockwise circle segments around a
@@ -14,7 +14,7 @@ module AIXM
14
14
  # clockwise: true or false
15
15
  # )
16
16
  #
17
- # @see https://github.com/openflightmaps/ofmx/wiki/Airspace#arc
17
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace#arc
18
18
  class Arc < Point
19
19
  # @return [AIXM::XY] center point
20
20
  attr_reader :center_xy
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- class Component
4
+ module Component
5
5
  class Geometry
6
6
 
7
7
  # Borders are following natural or artifical border lines referenced by
@@ -13,8 +13,10 @@ module AIXM
13
13
  # name: String
14
14
  # )
15
15
  #
16
- # @see https://github.com/openflightmaps/ofmx/wiki/Airspace#frontier
16
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace#frontier
17
17
  class Border < Point
18
+ include AIXM::Memoize
19
+
18
20
  # @return [String] name of the border
19
21
  attr_reader :name
20
22
 
@@ -38,8 +40,9 @@ module AIXM
38
40
  builder = Builder::XmlMarkup.new(indent: 2)
39
41
  builder.tag!(as) do |tag|
40
42
  tag.txtName(name.to_s)
41
- end.insert_payload_hash(region: AIXM.config.mid_region)
43
+ end
42
44
  end
45
+ memoize :to_uid
43
46
 
44
47
  # @return [String] AIXM or OFMX markup
45
48
  def to_xml
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- class Component
4
+ module Component
5
5
  class Geometry
6
6
 
7
7
  # Circles are defined by a {#center_xy} and a {#radius}.
@@ -12,8 +12,14 @@ module AIXM
12
12
  # radius: AIXM.d
13
13
  # )
14
14
  #
15
- # @see https://github.com/openflightmaps/ofmx/wiki/Airspace#circle
15
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace#circle
16
16
  class Circle
17
+ include AIXM::Association
18
+
19
+ # @!method geometry
20
+ # @return [AIXM::Component::Geometry] geometry the arc belongs to
21
+ belongs_to :geometry, as: :segment
22
+
17
23
  # @return [AIXM::XY] center point
18
24
  attr_reader :center_xy
19
25
 
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- class Component
4
+ module Component
5
5
  class Geometry
6
6
 
7
7
  # Points are defined by {#xy} coordinates.
@@ -11,8 +11,14 @@ module AIXM
11
11
  # xy: AIXM.xy
12
12
  # )
13
13
  #
14
- # @see https://github.com/openflightmaps/ofmx/wiki/Airspace#point
14
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace#point
15
15
  class Point
16
+ include AIXM::Association
17
+
18
+ # @!method geometry
19
+ # @return [AIXM::Component::Geometry] geometry the arc belongs to
20
+ belongs_to :geometry, as: :segment
21
+
16
22
  # @return [AIXM::XY] (starting) point
17
23
  attr_reader :xy
18
24
 
@@ -1,7 +1,7 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- class Component
4
+ module Component
5
5
 
6
6
  # Helipads are TLOF (touch-down and lift-off areas) for vertical take-off
7
7
  # aircraft such as helicopters.
@@ -21,8 +21,11 @@ module AIXM
21
21
  # helipad.status = STATUSES or nil
22
22
  # helipad.remarks = String or nil
23
23
  #
24
- # @see https://github.com/openflightmaps/ofmx/wiki/Airport#tla-helipad-tlof
24
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airport#tla-helipad-tlof
25
25
  class Helipad
26
+ include AIXM::Association
27
+ include AIXM::Memoize
28
+
26
29
  HELICOPTER_CLASSES = {
27
30
  '1': :'1',
28
31
  '2': :'2',
@@ -39,8 +42,28 @@ module AIXM
39
42
  OTHER: :other # specify in remarks
40
43
  }.freeze
41
44
 
42
- # @return [AIXM::Feature::Airport] airport this helipad belongs to
43
- attr_reader :airport
45
+ # @!method fato
46
+ # @return [AIXM::Component::FATO, nil] FATO the helipad is situated on
47
+ # @!method fato=(fato)
48
+ # @param fato [AIXM::Component::FATO, nil]
49
+ has_one :fato, allow_nil: true
50
+
51
+ # @!method surface
52
+ # @return [AIXM::Component::Surface] surface of the helipad
53
+ # @!method surface=(surface)
54
+ # @param surface [AIXM::Component::Surface]
55
+ has_one :surface
56
+
57
+ # @!method lightings
58
+ # @return [Array<AIXM::Component::Lighting>] installed lighting systems
59
+ # @!method add_lighting(lighting)
60
+ # @param lighting [AIXM::Component::Lighting]
61
+ # @return [self]
62
+ has_many :lightings, as: :lightable
63
+
64
+ # @!method airport
65
+ # @return [AIXM::Feature::Airport] airport this helipad belongs to
66
+ belongs_to :airport
44
67
 
45
68
  # @return [String] full name (e.g. "H1")
46
69
  attr_reader :name
@@ -57,15 +80,9 @@ module AIXM
57
80
  # @return [AIXM::D, nil] width
58
81
  attr_reader :width
59
82
 
60
- # @return [AIXM::Component::Surface] surface of the helipad
61
- attr_reader :surface
62
-
63
83
  # @return [String, nil] markings
64
84
  attr_reader :marking
65
85
 
66
- # @return [AIXM::Component::FATO, nil] FATO the helipad is situated on
67
- attr_reader :fato
68
-
69
86
  # @return [Integer, Symbol, nil] suitable helicopter class
70
87
  attr_reader :helicopter_class
71
88
 
@@ -75,13 +92,9 @@ module AIXM
75
92
  # @return [String, nil] free text remarks
76
93
  attr_reader :remarks
77
94
 
78
- # @return [Array<AIXM::Component::Lighting>] installed lighting systems
79
- attr_reader :lightings
80
-
81
95
  def initialize(name:, xy:)
82
96
  self.name, self.xy = name, xy
83
- @surface = AIXM.surface
84
- @lightings = []
97
+ self.surface = AIXM.surface
85
98
  end
86
99
 
87
100
  # @return [String]
@@ -89,12 +102,6 @@ module AIXM
89
102
  %Q(#<#{self.class} airport=#{airport&.id.inspect} name=#{name.inspect}>)
90
103
  end
91
104
 
92
- def airport=(value)
93
- fail(ArgumentError, "invalid airport") unless value.is_a? AIXM::Feature::Airport
94
- @airport = value
95
- end
96
- private :airport=
97
-
98
105
  def name=(value)
99
106
  fail(ArgumentError, "invalid name") unless value.is_a? String
100
107
  @name = value.uptrans
@@ -130,11 +137,6 @@ module AIXM
130
137
  @marking = value&.to_s
131
138
  end
132
139
 
133
- def fato=(value)
134
- fail(ArgumentError, "invalid FATO") unless value.nil? || value.is_a?(AIXM::Component::FATO)
135
- @fato = value
136
- end
137
-
138
140
  def helicopter_class=(value)
139
141
  @helicopter_class = value.nil? ? nil : (HELICOPTER_CLASSES.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid helicopter class"))
140
142
  end
@@ -147,25 +149,15 @@ module AIXM
147
149
  @remarks = value&.to_s
148
150
  end
149
151
 
150
- # Add a lighting system to the runway direction.
151
- #
152
- # @param lighting [AIXM::Component::Lighting] lighting instance
153
- # @return [self]
154
- def add_lighting(lighting)
155
- fail(ArgumentError, "invalid lighting") unless lighting.is_a? AIXM::Component::Lighting
156
- lighting.send(:lightable=, self)
157
- @lightings << lighting
158
- self
159
- end
160
-
161
152
  # @return [String] UID markup
162
153
  def to_uid
163
154
  builder = Builder::XmlMarkup.new(indent: 2)
164
155
  builder.TlaUid do |tla_uid|
165
156
  tla_uid << airport.to_uid.indent(2)
166
157
  tla_uid.txtDesig(name)
167
- end.insert_payload_hash(region: AIXM.config.mid_region)
158
+ end
168
159
  end
160
+ memoize :to_uid
169
161
 
170
162
  # @return [String] AIXM or OFMX markup
171
163
  def to_xml
@@ -1,24 +1,27 @@
1
1
  using AIXM::Refinements
2
2
 
3
3
  module AIXM
4
- class Component
4
+ module Component
5
5
 
6
6
  # Each airspace has one or more layers with optional airspace class and
7
- # mandatory vertical limits.
7
+ # mandatory vertical limit.
8
8
  #
9
9
  # ===Cheat Sheet in Pseudo Code:
10
10
  # layer = AIXM.layer(
11
11
  # class: String or nil
12
12
  # location_indicator: String or nil
13
- # vertical_limits: AIXM.vertical_limits
13
+ # vertical_limit: AIXM.vertical_limit
14
14
  # )
15
15
  # layer.activity = String or nil
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
20
  #
20
- # @see https://github.com/openflightmaps/ofmx/wiki/Airspace
21
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace
21
22
  class Layer
23
+ include AIXM::Association
24
+
22
25
  CLASSES = (:A..:G).freeze
23
26
 
24
27
  ACTIVITIES = {
@@ -85,12 +88,25 @@ module AIXM
85
88
  OTHER: :other
86
89
  }.freeze
87
90
 
91
+ # @!method vertical_limit
92
+ # @return [AIXM::Component::VerticalLimit] vertical limit of this layer
93
+ # @!method vertical_limit=(vertical_limit)
94
+ # @param vertical_limit [AIXM::Component::VerticalLimit]
95
+ has_one :vertical_limit
96
+
97
+ # @!method services
98
+ # @return [Array<AIXM::Component::Service>] services
99
+ # @!method add_service(service)
100
+ # @param service [AIXM::Component::Service]
101
+ has_many :services
102
+
103
+ # @!method airspace
104
+ # @return [AIXM::Feature::Airspace] airspace the layer defines
105
+ belongs_to :airspace
106
+
88
107
  # @return [String, nil] four letter location identifier as published in the ICAO DOC 7910
89
108
  attr_reader :location_indicator
90
109
 
91
- # @return [AIXM::Component::VerticalLimits] vertical limits of this layer
92
- attr_reader :vertical_limits
93
-
94
110
  # @return [String, nil] primary activity (e.g. "GLIDER")
95
111
  attr_reader :activity
96
112
 
@@ -100,21 +116,19 @@ module AIXM
100
116
  # @return [String, nil] free text remarks
101
117
  attr_reader :remarks
102
118
 
103
- def initialize(class: nil, location_indicator: nil, vertical_limits:)
119
+ def initialize(class: nil, location_indicator: nil, vertical_limit:)
104
120
  self.class = binding.local_variable_get(:class)
105
- self.location_indicator, self.vertical_limits = location_indicator, vertical_limits
121
+ self.location_indicator, self.vertical_limit = location_indicator, vertical_limit
106
122
  self.selective = false
107
123
  end
108
124
 
109
125
  # @return [String]
110
126
  def inspect
111
- %Q(#<#{original_class} class=#{@klass.inspect}>)
127
+ %Q(#<#{__class__} class=#{@klass.inspect}>)
112
128
  end
113
129
 
114
130
  # @!attribute class
115
- # @note Use +original_class+ to query the Ruby object class.
116
131
  # @return [Symbol] class of layer (see {CLASSES})
117
- alias_method :original_class, :class
118
132
  def class
119
133
  @klass
120
134
  end
@@ -129,11 +143,6 @@ module AIXM
129
143
  @location_indicator = value&.uptrans
130
144
  end
131
145
 
132
- def vertical_limits=(value)
133
- fail(ArgumentError, "invalid vertical limits") unless value.is_a? AIXM::Component::VerticalLimits
134
- @vertical_limits = value
135
- end
136
-
137
146
  def activity=(value)
138
147
  @activity = value.nil? ? nil : ACTIVITIES.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid activity")
139
148
  end
@@ -164,9 +173,9 @@ module AIXM
164
173
  builder.codeClass(self.class.to_s) if self.class
165
174
  builder.codeLocInd(location_indicator) if location_indicator
166
175
  if activity
167
- builder.codeActivity(ACTIVITIES.key(activity).to_s.then_if(AIXM.aixm?) { |a| { 'AIRMODEL' => 'UAV', 'WINCH' => 'GLIDER' }[a] || a })
176
+ builder.codeActivity(ACTIVITIES.key(activity).to_s.then_if(AIXM.aixm?) { { 'AIRMODEL' => 'UAV', 'WINCH' => 'GLIDER' }[_1] || _1 })
168
177
  end
169
- builder << vertical_limits.to_xml
178
+ builder << vertical_limit.to_xml
170
179
  builder << timetable.to_xml(as: :Att) if timetable
171
180
  builder.codeSelAvbl(selective? ? 'Y' : 'N') if AIXM.ofmx?
172
181
  builder.txtRmk(remarks) if remarks