aixm 0.3.8 → 0.3.10

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 (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
@@ -8,13 +8,14 @@ module AIXM
8
8
  # ===Cheat Sheet in Pseudo Code:
9
9
  # airspace = AIXM.airspace(
10
10
  # source: String or nil
11
+ # region: String or nil
11
12
  # id: String or nil # nil is converted to an 8 character digest
12
13
  # type: String or Symbol
13
14
  # local_type: String or nil
14
15
  # name: String or nil
15
16
  # )
16
- # airspace.geometry << AIXM.point or AIXM.arc or AIXM.border or AIXM.circle
17
- # airspace.layers << AIXM.layer
17
+ # airspace.add_layer(AIXM.layer)
18
+ # airspace.geometry.add_segment(AIXM.point or AIXM.arc or AIXM.border or AIXM.circle)
18
19
  #
19
20
  # The +id+ is mandatory, however, you may omit it when initializing a new
20
21
  # airspace or assign +nil+ to an existing airspace which will generate a 8
@@ -27,8 +28,11 @@ module AIXM
27
28
  #
28
29
  # airspace= AIXM.airspace(type: :regulated_airspace, local_type: "RMZ")
29
30
  #
30
- # @see https://github.com/openflightmaps/ofmx/wiki/Airspace#ase-airspace
31
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace#ase-airspace
31
32
  class Airspace < Feature
33
+ include AIXM::Association
34
+ include AIXM::Memoize
35
+
32
36
  public_class_method :new
33
37
 
34
38
  TYPES = {
@@ -74,6 +78,18 @@ module AIXM
74
78
  PART: :part_of_airspace
75
79
  }.freeze
76
80
 
81
+ # @!method geometry
82
+ # @return [AIXM::Component::Geometry] horizontal geometry shape
83
+ # @!method geometry=(geometry)
84
+ # @param geometry [AIXM::Component::Geometry]
85
+ has_one :geometry
86
+
87
+ # @!method layers
88
+ # @return [Array<AIXM::Compoment::Layer>] vertical layers
89
+ # @!method add_layer(layer)
90
+ # @param layer [AIXM::Compoment::Layer]
91
+ has_many :layers
92
+
77
93
  # @note When assigning +nil+, a 4 byte hex derived from {#type}, {#name}
78
94
  # and {#local_type} is written instead.
79
95
  # @return [String] published identifier (e.g. "LFP81")
@@ -90,18 +106,11 @@ module AIXM
90
106
  # @return [String, nil] full name (e.g. "LF P 81 CHERBOURG")
91
107
  attr_reader :name
92
108
 
93
- # @return [AIXM::Component::Geometry] horizontal geometrical shape
94
- attr_accessor :geometry
95
-
96
- # @return [Array<AIXM::Compoment::Layer>] vertical layers
97
- attr_accessor :layers
98
-
99
- def initialize(source: nil, id: nil, type:, local_type: nil, name: nil)
100
- super(source: source)
109
+ def initialize(source: nil, region: nil, id: nil, type:, local_type: nil, name: nil)
110
+ super(source: source, region: region)
101
111
  self.type, self.local_type, self.name = type, local_type, name
102
112
  self.id = id
103
- @geometry = AIXM.geometry
104
- @layers = []
113
+ self.geometry = AIXM.geometry
105
114
  end
106
115
 
107
116
  # @return [String]
@@ -133,18 +142,19 @@ module AIXM
133
142
  # @return [String] UID markup
134
143
  def to_uid(as: :AseUid)
135
144
  builder = Builder::XmlMarkup.new(indent: 2)
136
- builder.tag!(as) do |tag|
145
+ builder.tag!(as, ({ region: (region if AIXM.ofmx?) }.compact)) do |tag|
137
146
  tag.codeType(TYPES.key(type).to_s)
138
147
  tag.codeId(id)
139
- end.insert_payload_hash(region: AIXM.config.mid_region)
148
+ end
140
149
  end
150
+ memoize :to_uid
141
151
 
142
152
  # @return [String] UID markup
143
153
  def to_wrapped_uid(as: :AseUid, with:)
144
154
  builder = Builder::XmlMarkup.new(indent: 2)
145
155
  builder.tag!(with) do |tag|
146
156
  tag << to_uid(as: as).indent(2)
147
- end.insert_payload_hash(region: AIXM.config.mid_region)
157
+ end
148
158
  end
149
159
 
150
160
  # @raise [AIXM::GeometryError] if the geometry is not closed
@@ -168,7 +178,7 @@ module AIXM
168
178
  end
169
179
  if layered?
170
180
  layers.each.with_index do |layer, index|
171
- layer_airspace = AIXM.airspace(type: 'CLASS', name: "#{name} LAYER #{index + 1}")
181
+ layer_airspace = AIXM.airspace(region: region, type: 'CLASS', name: "#{name} LAYER #{index + 1}")
172
182
  builder.Ase do |ase|
173
183
  ase << layer_airspace.to_uid.indent(2)
174
184
  ase.txtName(layer_airspace.name)
@@ -178,6 +188,23 @@ module AIXM
178
188
  adg << layer_airspace.to_wrapped_uid(with: :AdgUid).indent(2)
179
189
  adg << to_uid(as: :AseUidSameExtent).indent(2)
180
190
  end
191
+ layer.services.each do |service|
192
+ builder.Sae do |sae|
193
+ sae.SaeUid do |sae_uid|
194
+ sae_uid << service.to_uid.indent(4)
195
+ sae_uid << layer_airspace.to_uid.indent(4)
196
+ end
197
+ end
198
+ end
199
+ end
200
+ else
201
+ layers.first.services.each do |service|
202
+ builder.Sae do |sae|
203
+ sae.SaeUid do |sae_uid|
204
+ sae_uid << service.to_uid.indent(4)
205
+ sae_uid << to_uid.indent(4)
206
+ end
207
+ end
181
208
  end
182
209
  end
183
210
  builder.target!
@@ -5,10 +5,13 @@ module AIXM
5
5
 
6
6
  # @abstract
7
7
  class NavigationalAid < Feature
8
+ include AIXM::Association
9
+
8
10
  private_class_method :new
9
11
 
10
- # @return [AIXM::Feature::Organisation] superior organisation
11
- attr_reader :organisation
12
+ # @!method organisation
13
+ # @return [AIXM::Feature::Organisation] superior organisation
14
+ belongs_to :organisation, as: :member
12
15
 
13
16
  # @return [String] published identifier
14
17
  attr_reader :id
@@ -28,8 +31,8 @@ module AIXM
28
31
  # @return [String, nil] free text remarks
29
32
  attr_reader :remarks
30
33
 
31
- def initialize(source: nil, organisation:, id:, name: nil, xy:, z: nil)
32
- super(source: source)
34
+ def initialize(source: nil, region: nil, organisation:, id:, name: nil, xy:, z: nil)
35
+ super(source: source, region: region)
33
36
  self.organisation, self.id, self.name, self.xy, self.z = organisation, id, name, xy, z
34
37
  end
35
38
 
@@ -38,11 +41,6 @@ module AIXM
38
41
  %Q(#<#{self.class} id=#{id.inspect} name=#{name.inspect}>)
39
42
  end
40
43
 
41
- def organisation=(value)
42
- fail(ArgumentError, "invalid organisation") unless value == false || value.is_a?(AIXM::Feature::Organisation)
43
- @organisation = value
44
- end
45
-
46
44
  def id=(value)
47
45
  fail(ArgumentError, "invalid id") unless value.is_a? String
48
46
  @id = value.upcase
@@ -10,6 +10,7 @@ module AIXM
10
10
  # ===Cheat Sheet in Pseudo Code:
11
11
  # designated_point = AIXM.designated_point(
12
12
  # source: String or nil
13
+ # region: String or nil
13
14
  # id: String
14
15
  # name: String or nil
15
16
  # xy: AIXM.xy
@@ -18,11 +19,12 @@ module AIXM
18
19
  # designated_point.airport = AIXM.airport or nil
19
20
  # designated_point.remarks = String or nil
20
21
  #
21
- # @see https://github.com/openflightmaps/ofmx/wiki/Navigational-aid#dpn-designated-point
22
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Navigational-aid#dpn-designated-point
22
23
  class DesignatedPoint < NavigationalAid
24
+ include AIXM::Association
25
+ include AIXM::Memoize
26
+
23
27
  public_class_method :new
24
- private :organisation=
25
- private :organisation
26
28
 
27
29
  TYPES = {
28
30
  ICAO: :icao, # five-letter ICAO id
@@ -35,15 +37,15 @@ module AIXM
35
37
  OTHER: :other # specify in remarks
36
38
  }.freeze
37
39
 
38
- # @return [Symbol] type of designated point
39
- attr_reader :type
40
-
41
40
  # @return [AIXM::Feature::Airport] airport this designated point is
42
41
  # associated with
43
- attr_reader :airport
42
+ belongs_to :airport
43
+
44
+ # @return [Symbol] type of designated point
45
+ attr_reader :type
44
46
 
45
47
  def initialize(type:, **arguments)
46
- super(organisation: false, z: nil, **arguments)
48
+ super(organisation: nil, z: nil, **arguments)
47
49
  self.type = type
48
50
  end
49
51
 
@@ -51,20 +53,16 @@ module AIXM
51
53
  @type = TYPES.lookup(value&.to_s&.to_sym, nil) || fail(ArgumentError, "invalid type")
52
54
  end
53
55
 
54
- def airport=(value)
55
- fail(ArgumentError, "invalid airport") unless value.nil? || value.is_a?(AIXM::Feature::Airport)
56
- @airport = value
57
- end
58
-
59
56
  # @return [String] UID markup
60
57
  def to_uid
61
58
  builder = Builder::XmlMarkup.new(indent: 2)
62
- builder.DpnUid do |dpn_uid|
59
+ builder.DpnUid({ region: (region if AIXM.ofmx?) }.compact) do |dpn_uid|
63
60
  dpn_uid.codeId(id)
64
61
  dpn_uid.geoLat(xy.lat(AIXM.schema))
65
62
  dpn_uid.geoLong(xy.long(AIXM.schema))
66
- end.insert_payload_hash(region: AIXM.config.mid_region)
63
+ end
67
64
  end
65
+ memoize :to_uid
68
66
 
69
67
  # @return [String] AIXM or OFMX markup
70
68
  def to_xml
@@ -12,6 +12,7 @@ module AIXM
12
12
  # ===Cheat Sheet in Pseudo Code:
13
13
  # dme = AIXM.dme(
14
14
  # source: String or nil
15
+ # region: String or nil
15
16
  # organisation: AIXM.organisation
16
17
  # id: String
17
18
  # name: String
@@ -22,18 +23,21 @@ module AIXM
22
23
  # dme.timetable = AIXM.timetable or nil
23
24
  # dme.remarks = String or nil
24
25
  #
25
- # @see https://github.com/openflightmaps/ofmx/wiki/Navigational-aid#dme-dme
26
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Navigational-aid#dme-dme
26
27
  class DME < NavigationalAid
28
+ include AIXM::Memoize
29
+
27
30
  public_class_method :new
28
31
 
29
32
  CHANNEL_RE = /\A([1-9]|[1-9]\d|1[0-1]\d|12[0-6])[XY]\z/.freeze
30
33
 
34
+ # @!method vor
35
+ # @return [AIXM::Feature::NavigationalAid::VOR, nil] associated VOR
36
+ belongs_to :vor, readonly: true
37
+
31
38
  # @return [String] radio channel
32
39
  attr_reader :channel
33
40
 
34
- # @return [AIXM::Feature::NavigationalAid::VOR, nil] associated VOR
35
- attr_reader :vor
36
-
37
41
  def initialize(channel:, **arguments)
38
42
  super(**arguments)
39
43
  self.channel = channel
@@ -60,21 +64,16 @@ module AIXM
60
64
  end
61
65
  end
62
66
 
63
- def vor=(value)
64
- fail(ArgumentError, "invalid VOR") unless value.is_a? VOR
65
- @vor = value
66
- end
67
- private :vor=
68
-
69
67
  # @return [String] UID markup
70
68
  def to_uid
71
69
  builder = Builder::XmlMarkup.new(indent: 2)
72
- builder.DmeUid do |dme_uid|
70
+ builder.DmeUid({ region: (region if AIXM.ofmx?) }.compact) do |dme_uid|
73
71
  dme_uid.codeId(id)
74
72
  dme_uid.geoLat(xy.lat(AIXM.schema))
75
73
  dme_uid.geoLong(xy.long(AIXM.schema))
76
- end.insert_payload_hash(region: AIXM.config.mid_region)
74
+ end
77
75
  end
76
+ memoize :to_uid
78
77
 
79
78
  # @return [String] AIXM or OFMX markup
80
79
  def to_xml
@@ -11,6 +11,7 @@ module AIXM
11
11
  # ===Cheat Sheet in Pseudo Code:
12
12
  # marker = AIXM.marker(
13
13
  # source: String or nil
14
+ # region: String or nil
14
15
  # organisation: AIXM.organisation
15
16
  # id: String
16
17
  # name: String
@@ -24,8 +25,10 @@ module AIXM
24
25
  # @note Marker are not fully implemented because they usually have to be
25
26
  # associated with an ILS which are not implemented as of now.
26
27
  #
27
- # @see https://github.com/openflightmaps/ofmx/wiki/Navigational-aid#mkr-marker-beacon
28
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Navigational-aid#mkr-marker-beacon
28
29
  class Marker < NavigationalAid
30
+ include AIXM::Memoize
31
+
29
32
  public_class_method :new
30
33
 
31
34
  TYPES = {
@@ -53,12 +56,13 @@ module AIXM
53
56
  # @return [String] UID markup
54
57
  def to_uid
55
58
  builder = Builder::XmlMarkup.new(indent: 2)
56
- builder.MkrUid do |mkr_uid|
59
+ builder.MkrUid({ region: (region if AIXM.ofmx?) }.compact) do |mkr_uid|
57
60
  mkr_uid.codeId(id)
58
61
  mkr_uid.geoLat(xy.lat(AIXM.schema))
59
62
  mkr_uid.geoLong(xy.long(AIXM.schema))
60
- end.insert_payload_hash(region: AIXM.config.mid_region)
63
+ end
61
64
  end
65
+ memoize :to_uid
62
66
 
63
67
  # @return [String] AIXM or OFMX markup
64
68
  def to_xml
@@ -10,6 +10,7 @@ module AIXM
10
10
  # ===Cheat Sheet in Pseudo Code:
11
11
  # ndb = AIXM.ndb(
12
12
  # source: String or nil
13
+ # region: String or nil
13
14
  # organisation: AIXM.organisation
14
15
  # id: String
15
16
  # name: String
@@ -21,8 +22,10 @@ module AIXM
21
22
  # ndb.timetable = AIXM.timetable or nil
22
23
  # ndb.remarks = String or nil
23
24
  #
24
- # @see https://github.com/openflightmaps/ofmx/wiki/Navigational-aid#ndb-ndb
25
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Navigational-aid#ndb-ndb
25
26
  class NDB < NavigationalAid
27
+ include AIXM::Memoize
28
+
26
29
  public_class_method :new
27
30
 
28
31
  TYPES = {
@@ -55,12 +58,13 @@ module AIXM
55
58
  # @return [String] UID markup
56
59
  def to_uid
57
60
  builder = Builder::XmlMarkup.new(indent: 2)
58
- builder.NdbUid do |ndb_uid|
61
+ builder.NdbUid({ region: (region if AIXM.ofmx?) }.compact) do |ndb_uid|
59
62
  ndb_uid.codeId(id)
60
63
  ndb_uid.geoLat(xy.lat(AIXM.schema))
61
64
  ndb_uid.geoLong(xy.long(AIXM.schema))
62
- end.insert_payload_hash(region: AIXM.config.mid_region)
65
+ end
63
66
  end
67
+ memoize :to_uid
64
68
 
65
69
  # @return [String] AIXM or OFMX markup
66
70
  def to_xml
@@ -11,6 +11,7 @@ module AIXM
11
11
  # ===Cheat Sheet in Pseudo Code:
12
12
  # tacan = AIXM.tacan(
13
13
  # source: String or nil
14
+ # region: String or nil
14
15
  # organisation: AIXM.organisation
15
16
  # id: String
16
17
  # name: String
@@ -21,19 +22,22 @@ module AIXM
21
22
  # tacan.timetable = AIXM.timetable or nil
22
23
  # tacan.remarks = String or nil
23
24
  #
24
- # @see https://github.com/openflightmaps/ofmx/wiki/Navigational-aid#tcn-tacan
25
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Navigational-aid#tcn-tacan
25
26
  class TACAN < DME
27
+ include AIXM::Memoize
28
+
26
29
  public_class_method :new
27
30
 
28
31
  # @return [String] UID markup
29
32
  def to_uid
30
33
  builder = Builder::XmlMarkup.new(indent: 2)
31
- builder.TcnUid do |tcn_uid|
34
+ builder.TcnUid({ region: (region if AIXM.ofmx?) }.compact) do |tcn_uid|
32
35
  tcn_uid.codeId(id)
33
36
  tcn_uid.geoLat(xy.lat(AIXM.schema))
34
37
  tcn_uid.geoLong(xy.long(AIXM.schema))
35
- end.insert_payload_hash(region: AIXM.config.mid_region)
38
+ end
36
39
  end
40
+ memoize :to_uid
37
41
 
38
42
  # @return [String] AIXM or OFMX markup
39
43
  def to_xml
@@ -11,6 +11,7 @@ module AIXM
11
11
  # ===Cheat Sheet in Pseudo Code:
12
12
  # vor = AIXM.vor(
13
13
  # source: String or nil
14
+ # region: String or nil
14
15
  # organisation: AIXM.organisation
15
16
  # id: String
16
17
  # name: String
@@ -25,8 +26,10 @@ module AIXM
25
26
  # vor.associate_dme(channel: String) # turns the VOR into a VOR/DME
26
27
  # vor.associate_tacan(channel: String) # turns the VOR into a VORTAC
27
28
  #
28
- # @see https://github.com/openflightmaps/ofmx/wiki/Navigational-aid#vor-vor
29
+ # @see https://gitlab.com/openflightmaps/ofmx/wikis/Navigational-aid#vor-vor
29
30
  class VOR < NavigationalAid
31
+ include AIXM::Memoize
32
+
30
33
  public_class_method :new
31
34
 
32
35
  TYPES = {
@@ -42,6 +45,18 @@ module AIXM
42
45
  OTHER: :other # specify in remarks
43
46
  }.freeze
44
47
 
48
+ # @!method dme
49
+ # @return [AIXM::Feature::NavigationalAid::DME, nil] associated DME
50
+ # @!method dme=(dme)
51
+ # @param dme [AIXM::Feature::NavigationalAid::DME, nil]
52
+ has_one :dme, allow_nil: true
53
+
54
+ # @!method tacan
55
+ # @return [AIXM::Feature::NavigationalAid::TACAN, nil] associated TACAN
56
+ # @!method tacan=(tacan)
57
+ # @param tacan [AIXM::Feature::NavigationalAid::TACAN, nil]
58
+ has_one :tacan, allow_nil: true
59
+
45
60
  # @return [Symbol] type of VOR (see {TYPES})
46
61
  attr_reader :type
47
62
 
@@ -51,12 +66,6 @@ module AIXM
51
66
  # @return [Symbol] north indication (see {NORTHS})
52
67
  attr_reader :north
53
68
 
54
- # @return [AIXM::Feature::NavigationalAid::DME, nil] associated DME
55
- attr_reader :dme
56
-
57
- # @return [AIXM::Feature::NavigationalAid::TACAN, nil] associated TACAN
58
- attr_reader :tacan
59
-
60
69
  def initialize(type:, f:, north:, **arguments)
61
70
  super(**arguments)
62
71
  self.type, self.f, self.north = type, f, north
@@ -77,27 +86,26 @@ module AIXM
77
86
 
78
87
  # Associate a DME which turns the VOR into a VOR/DME
79
88
  def associate_dme(channel:)
80
- @dme = AIXM.dme(organisation: organisation, id: id, name: name, xy: xy, z: z, channel: channel)
81
- @dme.timetable, @dme.remarks = timetable, remarks
82
- @dme.send(:vor=, self)
89
+ self.dme = AIXM.dme(region: region, organisation: organisation, id: id, name: name, xy: xy, z: z, channel: channel)
90
+ dme.timetable, @dme.remarks = timetable, remarks
83
91
  end
84
92
 
85
93
  # Associate a TACAN which turns the VOR into a VORTAC
86
94
  def associate_tacan(channel:)
87
- @tacan = AIXM.tacan(organisation: organisation, id: id, name: name, xy: xy, z: z, channel: channel)
88
- @tacan.timetable, @tacan.remarks = timetable, remarks
89
- @tacan.send(:vor=, self)
95
+ self.tacan = AIXM.tacan(region: region, organisation: organisation, id: id, name: name, xy: xy, z: z, channel: channel)
96
+ tacan.timetable, @tacan.remarks = timetable, remarks
90
97
  end
91
98
 
92
99
  # @return [String] UID markup
93
100
  def to_uid
94
101
  builder = Builder::XmlMarkup.new(indent: 2)
95
- builder.VorUid do |vor_uid|
102
+ builder.VorUid({ region: (region if AIXM.ofmx?) }.compact) do |vor_uid|
96
103
  vor_uid.codeId(id)
97
104
  vor_uid.geoLat(xy.lat(AIXM.schema))
98
105
  vor_uid.geoLong(xy.long(AIXM.schema))
99
- end.insert_payload_hash(region: AIXM.config.mid_region)
106
+ end
100
107
  end
108
+ memoize :to_uid
101
109
 
102
110
  # @return [String] AIXM or OFMX markup
103
111
  def to_xml