aixm 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +14 -3
  4. data/README.md +30 -2
  5. data/exe/ckmid +1 -7
  6. data/exe/mkmid +1 -7
  7. data/lib/aixm/classes.rb +2 -1
  8. data/lib/aixm/component/address.rb +12 -15
  9. data/lib/aixm/component/approach_lighting.rb +11 -16
  10. data/lib/aixm/component/fato.rb +22 -34
  11. data/lib/aixm/component/frequency.rb +10 -15
  12. data/lib/aixm/component/geometry/arc.rb +2 -3
  13. data/lib/aixm/component/geometry/border.rb +6 -10
  14. data/lib/aixm/component/geometry/circle.rb +4 -4
  15. data/lib/aixm/component/geometry/point.rb +4 -4
  16. data/lib/aixm/component/geometry/rhumb_line.rb +4 -4
  17. data/lib/aixm/component/geometry.rb +4 -4
  18. data/lib/aixm/component/helipad.rb +13 -20
  19. data/lib/aixm/component/layer.rb +6 -8
  20. data/lib/aixm/component/lighting.rb +12 -17
  21. data/lib/aixm/component/runway.rb +26 -38
  22. data/lib/aixm/component/service.rb +12 -16
  23. data/lib/aixm/component/surface.rb +8 -10
  24. data/lib/aixm/component/timesheet.rb +9 -10
  25. data/lib/aixm/component/timetable.rb +6 -7
  26. data/lib/aixm/component/vasis.rb +6 -8
  27. data/lib/aixm/component/vertical_limit.rb +8 -8
  28. data/lib/aixm/component.rb +3 -2
  29. data/lib/aixm/concerns/association.rb +381 -0
  30. data/lib/aixm/concerns/memoize.rb +107 -0
  31. data/lib/aixm/concerns/xml_builder.rb +34 -0
  32. data/lib/aixm/document.rb +52 -21
  33. data/lib/aixm/feature/airport.rb +44 -47
  34. data/lib/aixm/feature/airspace.rb +27 -34
  35. data/lib/aixm/feature/generic.rb +67 -0
  36. data/lib/aixm/feature/navigational_aid/designated_point.rb +11 -13
  37. data/lib/aixm/feature/navigational_aid/dme.rb +12 -15
  38. data/lib/aixm/feature/navigational_aid/marker.rb +12 -15
  39. data/lib/aixm/feature/navigational_aid/ndb.rb +13 -16
  40. data/lib/aixm/feature/navigational_aid/tacan.rb +15 -17
  41. data/lib/aixm/feature/navigational_aid/vor.rb +16 -19
  42. data/lib/aixm/feature/navigational_aid.rb +7 -7
  43. data/lib/aixm/feature/obstacle.rb +20 -21
  44. data/lib/aixm/feature/obstacle_group.rb +19 -20
  45. data/lib/aixm/feature/organisation.rb +11 -12
  46. data/lib/aixm/feature/unit.rb +16 -18
  47. data/lib/aixm/feature.rb +26 -7
  48. data/lib/aixm/object.rb +1 -1
  49. data/lib/aixm/refinements.rb +57 -0
  50. data/lib/aixm/version.rb +1 -1
  51. data/lib/aixm.rb +4 -3
  52. data/schemas/ofmx/0.1/OFMX-Snapshot.xsd +6 -1
  53. data.tar.gz.sig +3 -3
  54. metadata +7 -19
  55. metadata.gz.sig +0 -0
  56. data/lib/aixm/association.rb +0 -378
  57. data/lib/aixm/memoize.rb +0 -105
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce948465612571ae319c68d7f0eff0664d41c696440fb190298ac475b0e3105d
4
- data.tar.gz: 402358be48d240b24baef522ace4c501b1c685073ef28be35ce70985a5eaa9e8
3
+ metadata.gz: af33154acb182006b0c9f4e048c305b2489cba22d15ee1bc9aa724ddec70ceab
4
+ data.tar.gz: 44c42b5e93537e33cb2623a19a043216853664358d5c616f59aa884ee4c3e80c
5
5
  SHA512:
6
- metadata.gz: ee675af09c87b12e15bd50e2b2a2c8f00b457cb6ec53c8ee3d16d1b1b5965e410687c2f24f51c49a9673cef00d882f2ef6101e6af780161d33f6f898ff903f9f
7
- data.tar.gz: da8135812e7dd27baeb8068b8eefd6004467370763170737c18258b09cdc520bf09aad70fd6eb4c567dd39d5920c46ac1fd87a0ca5e30895c33b684fdf52ab73
6
+ metadata.gz: e960a18401dd58557db667b01cb3f15683728798f3aee736fda794a18519d7b3fb99e0725154a01b564a4e35658cdde5310402fd1c2b6f2e4550880cf47db98b
7
+ data.tar.gz: 2855fb8f01ca9dd515e8c05b60e79d80f4d4af77b48f1b03cc4baaadd1451810b877c92cd9364cb5d84b80f6d99ebda3b8c21d2445143f9d078a9e4e7ef2cc76
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  Nothing so far
4
4
 
5
+ ## 1.3.0
6
+
7
+ #### Breaking Changes
8
+ * `Document#created_at` no longer falls back to `Document#effective_at`
9
+
10
+ #### Additions
11
+ * Refinement to pretty print Nokogiri XML documents
12
+ * XML comments on features (e.g. to include raw NOTAM)
13
+ * `Document#expiration_at` for OFMX
14
+ * Generic features as raw XML (e.g. extracted from another AIXM/OFMX file)
15
+
5
16
  ## 1.2.1
6
17
 
7
18
  #### Additions
@@ -20,7 +31,7 @@ Nothing so far
20
31
  ## 1.1.0
21
32
 
22
33
  #### Breaking Changes
23
- * `AIXM::Association:Array#duplicates` now returns an array of arrays which
34
+ * `AIXM::Concerns::Association:Array#duplicates` now returns an array of arrays which
24
35
  group all duplicates together.
25
36
  * `VOR#associate_dme` and `VOR#associate_tacan` no longer take the channel
26
37
  as argument but calculate it from the (ghost) frequency of the VOR.
@@ -74,10 +85,10 @@ Nothing so far
74
85
 
75
86
  #### Additions
76
87
  * Proper `has_many` and `has_one` associations
77
- * `AIXM::Association:Array#find_by|find|duplicates` on `has_many` associations
88
+ * `AIXM::Concerns::Association:Array#find_by|find|duplicates` on `has_many` associations
78
89
  * `AIXM.config.mid` now defines whether `mid` attributes are inserted or not
79
90
  provided the selected schema is OFMX
80
- * `AIXM::Memoize` module
91
+ * `AIXM::Concerns::Memoize` module
81
92
  * `AIXM::PayloadHash` class
82
93
  * `mkmid` executable to insert `mid` attributes into valid OFMX file
83
94
  * `ckmid` executable to check `mid` attributes in an OFMX file
data/README.md CHANGED
@@ -28,7 +28,7 @@ gem cert --add <(curl -Ls https://raw.github.com/svoop/aixm/main/certs/svoop.pem
28
28
  Add the following to the <tt>Gemfile</tt> or <tt>gems.rb</tt> of your [Bundler](https://bundler.io) powered Ruby project:
29
29
 
30
30
  ```ruby
31
- gem aixm
31
+ gem 'aixm'
32
32
  ```
33
33
 
34
34
  And then install the bundle:
@@ -163,6 +163,7 @@ AIXM.config.ignored_errors = /invalid date/i
163
163
  * [Organisation](https://www.rubydoc.info/gems/aixm/AIXM/Feature/Organisation.html)
164
164
  * [Service](https://www.rubydoc.info/gems/aixm/AIXM/Component/Service.html)
165
165
  * [Unit](https://www.rubydoc.info/gems/aixm/AIXM/Feature/Unit.html)
166
+ * [Generic](https://www.rubydoc.info/gems/aixm/AIXM/Feature/Generic.html)
166
167
 
167
168
  ### Components
168
169
 
@@ -190,7 +191,7 @@ AIXM.config.ignored_errors = /invalid date/i
190
191
 
191
192
  The different models are interwoven with [`has_many` and `has_one` associations](https://www.rubydoc.info/gems/aixm/AIXM/Association).
192
193
 
193
- Please note that `has_many` associations are instances `AIXM::Association::Array` which mostly behave like normal arrays. However, you must not add or remove elements on the array directly but use the corresponding method on the associating model instead:
194
+ Please note that `has_many` associations are instances `AIXM::Concerns::Association::Array` which mostly behave like normal arrays. However, you must not add or remove elements on the array directly but use the corresponding method on the associating model instead:
194
195
 
195
196
  ```ruby
196
197
  document.features << airport # => NoMethodError
@@ -230,6 +231,33 @@ Equally on `has_many` associations, use `duplicates` to find identical or equal
230
231
  document.features.duplicates # => [#<AIXM::Feature::Unit>, #<AIXM::Component::Service>, ...]
231
232
  ```
232
233
 
234
+ ## XML Comments
235
+
236
+ All features implement the `comment` attribute which accepts any object and converts it `#to_s`. When set, an XML comment is inserted right after the opening tag of the feature. This comes in handy e.g. in case you want to include source data facsimile such as NOTAM. Oneline and multiline comments are inserted differently:
237
+
238
+ ```xml
239
+ <Ase>
240
+ <!--
241
+ B0330/22 NOTAMR B1756/21
242
+ Q) LSAS/QAFLT/V/NBO/E/000/050/4734N00841E005
243
+ A) LSAS B) 2203170746 C) 2206242359 EST
244
+ -->
245
+ <AseUid>
246
+ <codeType>RAS</codeType>
247
+ <codeId>B0330/22</codeId>
248
+ </AseUid>
249
+ (...)
250
+ </Ase>
251
+
252
+ <Org>
253
+ <!-- Generic organisation -->
254
+ <OrgUid>
255
+ <txtName>FRANCE</txtName>
256
+ </OrgUid>
257
+ (...)
258
+ </Org>
259
+ ```
260
+
233
261
  ## Payload Hash
234
262
 
235
263
  OFMX defines a [payload hash function](https://gitlab.com/openflightmaps/ofmx/wikis/Functions) used to facilitate association and modification tracking. It is used internally, but you can also use it in your own code:
data/exe/ckmid CHANGED
@@ -1,11 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'bundler/inline'
4
-
5
- gemfile do
6
- source 'https://rubygems.org'
7
- ruby '>= 3.0'
8
- gem 'aixm', '~> 0'
9
- end
3
+ require 'aixm'
10
4
 
11
5
  AIXM::Executables::Ckmid.new.run
data/exe/mkmid CHANGED
@@ -1,11 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'bundler/inline'
4
-
5
- gemfile do
6
- source 'https://rubygems.org'
7
- ruby '>= 3.0'
8
- gem 'aixm', '~> 0'
9
- end
3
+ require 'aixm'
10
4
 
11
5
  AIXM::Executables::Mkmid.new.run
data/lib/aixm/classes.rb CHANGED
@@ -45,7 +45,8 @@ module AIXM
45
45
  obstacle_group: 'AIXM::Feature::ObstacleGroup',
46
46
  timetable: 'AIXM::Component::Timetable',
47
47
  timesheet: 'AIXM::Component::Timesheet',
48
- vasis: 'AIXM::Component::VASIS'
48
+ vasis: 'AIXM::Component::VASIS',
49
+ generic: 'AIXM::Feature::Generic'
49
50
  }.freeze
50
51
 
51
52
  end
@@ -14,8 +14,7 @@ module AIXM
14
14
  #
15
15
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airport#aha-airport-address
16
16
  class Address < Component
17
- include AIXM::Association
18
- include AIXM::Memoize
17
+ include AIXM::Concerns::Association
19
18
  include AIXM::Concerns::Remarks
20
19
 
21
20
  public_class_method :new
@@ -82,26 +81,24 @@ module AIXM
82
81
  end
83
82
  end
84
83
 
85
- # @return [String] UID markup
86
- def to_uid(as:, sequence:)
87
- builder = Builder::XmlMarkup.new(indent: 2)
88
- builder.tag!(as) do |tag|
89
- tag << addressable.to_uid.indent(2) if addressable
84
+ # @!visibility private
85
+ def add_uid_to(builder, as:, sequence:)
86
+ builder.send(as) do |tag|
87
+ addressable.add_uid_to(tag) if addressable
90
88
  tag.codeType(TYPES.key(type).to_s.then_if(AIXM.aixm?) { _1.sub(/-\w+$/, '') })
91
89
  tag.noSeq(sequence)
92
90
  end
93
91
  end
94
- memoize :to_uid
95
92
 
96
- # @return [String] AIXM or OFMX markup
97
- def to_xml(as:, sequence:)
98
- builder = Builder::XmlMarkup.new(indent: 2)
99
- builder.comment! ["Address: #{TYPES.key(type)}", addressable&.id].compact.join(' for ')
100
- builder.tag!(as) do |tag|
101
- tag << to_uid(as: :"#{as}Uid", sequence: sequence).indent(2)
93
+ # @!visibility private
94
+ def add_to(builder, as:, sequence:)
95
+ builder.comment ["Address: #{TYPES.key(type)}", addressable&.id].compact.join(' for ').dress
96
+ builder.text "\n"
97
+ builder.send(as) do |tag|
98
+ add_uid_to(tag, as: :"#{as}Uid", sequence: sequence)
102
99
  case type
103
100
  when :radio_frequency
104
- tag.txtAddress(address.freq.to_s)
101
+ tag.txtAddress(address.freq)
105
102
  else
106
103
  tag.txtAddress(address)
107
104
  end
@@ -17,8 +17,7 @@ module AIXM
17
17
  #
18
18
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airport#rda-runway-direction-approach-lighting
19
19
  class ApproachLighting < Component
20
- include AIXM::Association
21
- include AIXM::Memoize
20
+ include AIXM::Concerns::Association
22
21
  include AIXM::Concerns::Intensity
23
22
  include AIXM::Concerns::Remarks
24
23
 
@@ -108,31 +107,27 @@ module AIXM
108
107
  @flash_description = value&.to_s
109
108
  end
110
109
 
111
- # @return [String] UID markup
112
- def to_uid(as:)
113
- builder = Builder::XmlMarkup.new(indent: 2)
114
- builder.tag!(as) do |tag|
115
- tag << approach_lightable.to_uid.indent(2)
116
- tag.codeType(TYPES.key(type).to_s)
110
+ # @!visibility private
111
+ def add_uid_to(builder, as:)
112
+ builder.send(as) do |tag|
113
+ approach_lightable.add_uid_to(tag)
114
+ tag.codeType(TYPES.key(type))
117
115
  end
118
116
  end
119
- memoize :to_uid
120
117
 
121
- # @return [String] AIXM or OFMX markup
122
- def to_xml(as:)
123
- builder = Builder::XmlMarkup.new(indent: 2)
124
- builder.tag!(as) do |tag|
125
- tag << to_uid(as: "#{as}Uid").indent(2)
118
+ # @!visibility private
119
+ def add_to(builder, as:)
120
+ builder.send(as) do |tag|
121
+ add_uid_to(tag, as: "#{as}Uid")
126
122
  if length
127
123
  tag.valLen(length.dim.round)
128
124
  tag.uomLen(length.unit.to_s.upcase)
129
125
  end
130
- tag.codeIntst(INTENSITIES.key(intensity).to_s) if intensity
126
+ tag.codeIntst(INTENSITIES.key(intensity)) if intensity
131
127
  tag.codeSequencedFlash(sequenced_flash ? 'Y' : 'N') unless sequenced_flash.nil?
132
128
  tag.txtDescrFlash(flash_description) if flash_description
133
129
  tag.txtRmk(remarks) if remarks
134
130
  end
135
- builder.target!
136
131
  end
137
132
  end
138
133
  end
@@ -28,8 +28,7 @@ module AIXM
28
28
  #
29
29
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airport#fto-fato
30
30
  class FATO < Component
31
- include AIXM::Association
32
- include AIXM::Memoize
31
+ include AIXM::Concerns::Association
33
32
  include AIXM::Concerns::Marking
34
33
  include AIXM::Concerns::Remarks
35
34
 
@@ -128,46 +127,41 @@ module AIXM
128
127
  @status = value.nil? ? nil : (STATUSES.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid status"))
129
128
  end
130
129
 
131
- # @return [String] UID markup
132
- def to_uid
133
- builder = Builder::XmlMarkup.new(indent: 2)
130
+ # @!visibility private
131
+ def add_uid_to(builder)
134
132
  builder.FtoUid do |fto_uid|
135
- fto_uid << airport.to_uid.indent(2)
133
+ airport.add_uid_to(fto_uid)
136
134
  fto_uid.txtDesig(name)
137
135
  end
138
136
  end
139
- memoize :to_uid
140
137
 
141
- # @return [String] AIXM or OFMX markup
142
- def to_xml
143
- builder = Builder::XmlMarkup.new(indent: 2)
138
+ # @!visibility private
139
+ def add_to(builder)
144
140
  builder.Fto do |fto|
145
- fto << to_uid.indent(2)
141
+ add_uid_to(fto)
146
142
  if dimensions
147
143
  fto.valLen(dimensions.length.to_m.dim.trim)
148
144
  fto.valWid(dimensions.width.to_m.dim.trim)
149
145
  fto.uomDim('M')
150
146
  end
151
- unless (xml = surface.to_xml).empty?
152
- fto << xml.indent(2)
153
- end
147
+ surface.add_to(fto) if surface
154
148
  fto.txtProfile(profile) if profile
155
149
  fto.txtMarking(marking) if marking
156
- fto.codeSts(STATUSES.key(status).to_s) if status
150
+ fto.codeSts(STATUSES.key(status)) if status
157
151
  fto.txtRmk(remarks) if remarks
158
152
  end
159
153
  directions.each do |direction|
160
- builder << direction.to_xml
154
+ direction.add_to(builder)
161
155
  end
162
- builder.target!
163
156
  end
164
157
 
165
158
  # FATO directions further describe each direction to and from the FATO.
166
159
  #
167
160
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airport#fdn-fato-direction
168
161
  class Direction
169
- include AIXM::Association
170
- include AIXM::Memoize
162
+ include AIXM::Concerns::Association
163
+ include AIXM::Concerns::Memoize
164
+ include AIXM::Concerns::XMLBuilder
171
165
  include AIXM::Concerns::Remarks
172
166
 
173
167
  # @!method lightings
@@ -239,35 +233,29 @@ module AIXM
239
233
  @vasis = value
240
234
  end
241
235
 
242
- # @return [String] UID markup
243
- def to_uid
244
- builder = Builder::XmlMarkup.new(indent: 2)
236
+ # @!visibility private
237
+ def add_uid_to(builder)
245
238
  builder.FdnUid do |fdn_uid|
246
- fdn_uid << fato.to_uid.indent(2)
239
+ fato.add_uid_to(fdn_uid)
247
240
  fdn_uid.txtDesig(name.to_s(:runway))
248
241
  end
249
242
  end
250
- memoize :to_uid
251
243
 
252
- # @return [String] AIXM or OFMX markup
253
- def to_xml
254
- builder = Builder::XmlMarkup.new(indent: 2)
244
+ # @!visibility private
245
+ def add_to(builder)
255
246
  builder.Fdn do |fdn|
256
- fdn << to_uid.indent(2)
247
+ add_uid_to(fdn)
257
248
  fdn.valTrueBrg(geographic_bearing.to_s(:bearing)) if geographic_bearing
258
249
  fdn.valMagBrg(magnetic_bearing.to_s(:bearing)) if magnetic_bearing
259
- if vasis
260
- fdn << vasis.to_xml.indent(2)
261
- end
250
+ vasis.add_to(fdn) if vasis
262
251
  fdn.txtRmk(remarks) if remarks
263
252
  end
264
253
  lightings.each do |lighting|
265
- builder << lighting.to_xml(as: :Fls)
254
+ lighting.add_to(builder, as: :Fls)
266
255
  end
267
256
  approach_lightings.each do |approach_lighting|
268
- builder << approach_lighting.to_xml(as: :Fda)
257
+ approach_lighting.add_to(builder, as: :Fda)
269
258
  end
270
- builder.target!
271
259
  end
272
260
  end
273
261
  end
@@ -22,8 +22,7 @@ module AIXM
22
22
  #
23
23
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Organisation#fqy-frequency
24
24
  class Frequency < Component
25
- include AIXM::Association
26
- include AIXM::Memoize
25
+ include AIXM::Concerns::Association
27
26
  include AIXM::Concerns::Timetable
28
27
  include AIXM::Concerns::Remarks
29
28
 
@@ -112,32 +111,28 @@ module AIXM
112
111
  @type = value.nil? ? nil : TYPES.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid type")
113
112
  end
114
113
 
115
- # @return [String] UID markup
116
- def to_uid
117
- builder = Builder::XmlMarkup.new(indent: 2)
114
+ # @!visibility private
115
+ def add_uid_to(builder)
118
116
  builder.FqyUid do |fqy_uid|
119
- fqy_uid << service.to_uid.indent(2)
117
+ service.add_uid_to(fqy_uid)
120
118
  fqy_uid.valFreqTrans(transmission_f.freq)
121
119
  end
122
120
  end
123
- memoize :to_uid
124
121
 
125
- # @return [String] AIXM or OFMX markup
126
- def to_xml
127
- builder = Builder::XmlMarkup.new(indent: 2)
122
+ # @!visibility private
123
+ def add_to(builder)
128
124
  builder.Fqy do |fqy|
129
- fqy << to_uid.indent(2)
125
+ add_uid_to(fqy)
130
126
  fqy.valFreqRec(reception_f.freq) if reception_f
131
- fqy.uomFreq(transmission_f.unit.upcase.to_s)
132
- fqy << timetable.to_xml(as: :Ftt).indent(2) if timetable
127
+ fqy.uomFreq(transmission_f.unit.upcase)
128
+ timetable.add_to(fqy, as: :Ftt) if timetable
133
129
  fqy.txtRmk(remarks) if remarks
134
130
  callsigns.each do |language, callsign|
135
131
  fqy.Cdl do |cdl|
136
132
  cdl.txtCallSign(callsign)
137
- cdl.codeLang(language.upcase.to_s)
133
+ cdl.codeLang(language.upcase)
138
134
  end
139
135
  end
140
- fqy.target!
141
136
  end
142
137
  end
143
138
  end
@@ -58,9 +58,8 @@ module AIXM
58
58
  @clockwise = value
59
59
  end
60
60
 
61
- # @return [String] AIXM or OFMX markup
62
- def to_xml
63
- builder = Builder::XmlMarkup.new(indent: 2)
61
+ # @!visibility private
62
+ def add_to(builder)
64
63
  builder.Avx do |avx|
65
64
  avx.codeType(clockwise? ? 'CWA' : 'CCA')
66
65
  avx.geoLat(xy.lat(AIXM.schema))
@@ -15,7 +15,6 @@ module AIXM
15
15
  #
16
16
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace#frontier
17
17
  class Border < Point
18
- include AIXM::Memoize
19
18
 
20
19
  # Name of the border
21
20
  #
@@ -42,20 +41,17 @@ module AIXM
42
41
  @name = value
43
42
  end
44
43
 
45
- # @return [String] UID markup
46
- def to_uid(as: :GbrUid)
47
- builder = Builder::XmlMarkup.new(indent: 2)
48
- builder.tag!(as) do |tag|
44
+ # @!visibility private
45
+ def add_uid_to(builder, as: :GbrUid)
46
+ builder.send(as) do |tag|
49
47
  tag.txtName(name.to_s)
50
48
  end
51
49
  end
52
- memoize :to_uid
53
50
 
54
- # @return [String] AIXM or OFMX markup
55
- def to_xml
56
- builder = Builder::XmlMarkup.new(indent: 2)
51
+ # @!visibility private
52
+ def add_to(builder)
57
53
  builder.Avx do |avx|
58
- avx << to_uid.indent(2)
54
+ add_uid_to(avx)
59
55
  avx.codeType('FNT')
60
56
  avx.geoLat(xy.lat(AIXM.schema))
61
57
  avx.geoLong(xy.long(AIXM.schema))
@@ -14,7 +14,8 @@ module AIXM
14
14
  #
15
15
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace#circle
16
16
  class Circle
17
- include AIXM::Association
17
+ include AIXM::Concerns::Association
18
+ include AIXM::Concerns::XMLBuilder
18
19
 
19
20
  # @!method geometry
20
21
  # @return [AIXM::Component::Geometry] geometry this segment belongs to
@@ -57,9 +58,8 @@ module AIXM
57
58
  @radius = value
58
59
  end
59
60
 
60
- # @return [String] AIXM or OFMX markup
61
- def to_xml
62
- builder = Builder::XmlMarkup.new(indent: 2)
61
+ # @!visibility private
62
+ def add_to(builder)
63
63
  builder.Avx do |avx|
64
64
  avx.codeType('CWA')
65
65
  avx.geoLat(north_xy.lat(AIXM.schema))
@@ -14,7 +14,8 @@ module AIXM
14
14
  #
15
15
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace#point
16
16
  class Point
17
- include AIXM::Association
17
+ include AIXM::Concerns::Association
18
+ include AIXM::Concerns::XMLBuilder
18
19
 
19
20
  # @!method geometry
20
21
  # @return [AIXM::Component::Geometry] geometry this segment belongs to
@@ -44,9 +45,8 @@ module AIXM
44
45
  @xy = value
45
46
  end
46
47
 
47
- # @return [String] AIXM or OFMX markup
48
- def to_xml
49
- builder = Builder::XmlMarkup.new(indent: 2)
48
+ # @!visibility private
49
+ def add_to(builder)
50
50
  builder.Avx do |avx|
51
51
  avx.codeType('GRC')
52
52
  avx.geoLat(xy.lat(AIXM.schema))
@@ -14,7 +14,8 @@ module AIXM
14
14
  #
15
15
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace#rhumb-line
16
16
  class RhumbLine
17
- include AIXM::Association
17
+ include AIXM::Concerns::Association
18
+ include AIXM::Concerns::XMLBuilder
18
19
 
19
20
  # @!method geometry
20
21
  # @return [AIXM::Component::Geometry] geometry this segment belongs to
@@ -44,9 +45,8 @@ module AIXM
44
45
  @xy = value
45
46
  end
46
47
 
47
- # @return [String] AIXM or OFMX markup
48
- def to_xml
49
- builder = Builder::XmlMarkup.new(indent: 2)
48
+ # @!visibility private
49
+ def add_to(builder)
50
50
  builder.Avx do |avx|
51
51
  avx.codeType('RHL')
52
52
  avx.geoLat(xy.lat(AIXM.schema))
@@ -27,7 +27,7 @@ module AIXM
27
27
  #
28
28
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace#avx-border-vertex
29
29
  class Geometry < Component
30
- include AIXM::Association
30
+ include AIXM::Concerns::Association
31
31
 
32
32
  # @!method segments
33
33
  # @return [Array<AIXM::Component::Geometry::Point,
@@ -93,10 +93,10 @@ module AIXM
93
93
  segments.first.xy == segments.last.xy
94
94
  end
95
95
 
96
- # @return [String] AIXM or OFMX markup
97
- def to_xml
96
+ # @!visibility private
97
+ def add_to(builder)
98
98
  fail(GeometryError.new("geometry is not closed", self)) unless closed?
99
- segments.map { _1.to_xml }.join
99
+ segments.each { _1.add_to(builder) }
100
100
  end
101
101
  end
102
102
 
@@ -23,8 +23,7 @@ module AIXM
23
23
  #
24
24
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airport#tla-helipad-tlof
25
25
  class Helipad < Component
26
- include AIXM::Association
27
- include AIXM::Memoize
26
+ include AIXM::Concerns::Association
28
27
  include AIXM::Concerns::Marking
29
28
  include AIXM::Concerns::Remarks
30
29
 
@@ -159,46 +158,40 @@ module AIXM
159
158
  @status = value.nil? ? nil : (STATUSES.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid status"))
160
159
  end
161
160
 
162
- # @return [String] UID markup
163
- def to_uid
164
- builder = Builder::XmlMarkup.new(indent: 2)
161
+ # @!visibility private
162
+ def add_uid_to(builder)
165
163
  builder.TlaUid do |tla_uid|
166
- tla_uid << airport.to_uid.indent(2)
164
+ airport.add_uid_to(tla_uid)
167
165
  tla_uid.txtDesig(name)
168
166
  end
169
167
  end
170
- memoize :to_uid
171
168
 
172
- # @return [String] AIXM or OFMX markup
173
- def to_xml
174
- builder = Builder::XmlMarkup.new(indent: 2)
169
+ # @!visibility private
170
+ def add_to(builder)
175
171
  builder.Tla do |tla|
176
- tla << to_uid.indent(2)
177
- tla << fato.to_uid.indent(2) if fato
172
+ add_uid_to(tla)
173
+ fato.add_uid_to(tla) if fato
178
174
  tla.geoLat(xy.lat(AIXM.schema))
179
175
  tla.geoLong(xy.long(AIXM.schema))
180
176
  tla.codeDatum('WGE')
181
177
  if z
182
178
  tla.valElev(z.alt)
183
- tla.uomDistVer(z.unit.upcase.to_s)
179
+ tla.uomDistVer(z.unit.upcase)
184
180
  end
185
181
  if dimensions
186
182
  tla.valLen(dimensions.length.to_m.dim.trim)
187
183
  tla.valWid(dimensions.width.to_m.dim.trim)
188
184
  tla.uomDim('M')
189
185
  end
190
- unless (xml = surface.to_xml).empty?
191
- tla << xml.indent(2)
192
- end
193
- tla.codeClassHel(PERFORMANCE_CLASSES.key(performance_class).to_s) if performance_class
186
+ surface.add_to(tla) if surface
187
+ tla.codeClassHel(PERFORMANCE_CLASSES.key(performance_class)) if performance_class
194
188
  tla.txtMarking(marking) if marking
195
- tla.codeSts(STATUSES.key(status).to_s) if status
189
+ tla.codeSts(STATUSES.key(status)) if status
196
190
  tla.txtRmk(remarks) if remarks
197
191
  end
198
192
  lightings.each do |lighting|
199
- builder << lighting.to_xml(as: :Tls)
193
+ lighting.add_to(builder, as: :Tls)
200
194
  end
201
- builder.target!
202
195
  end
203
196
  end
204
197
  end
@@ -20,7 +20,7 @@ module AIXM
20
20
  #
21
21
  # @see https://gitlab.com/openflightmaps/ofmx/wikis/Airspace
22
22
  class Layer < Component
23
- include AIXM::Association
23
+ include AIXM::Concerns::Association
24
24
  include AIXM::Concerns::Timetable
25
25
  include AIXM::Concerns::Remarks
26
26
 
@@ -180,19 +180,17 @@ module AIXM
180
180
  @selective = value
181
181
  end
182
182
 
183
- # @return [String] AIXM or OFMX markup
184
- def to_xml
185
- builder = Builder::XmlMarkup.new(indent: 2)
186
- builder.codeClass(self.class.to_s) if self.class
183
+ # @!visibility private
184
+ def add_to(builder)
185
+ builder.codeClass(self.class) if self.class
187
186
  builder.codeLocInd(location_indicator) if location_indicator
188
187
  if activity
189
188
  builder.codeActivity(ACTIVITIES.key(activity).to_s.then_if(AIXM.aixm?) { { 'AIRMODEL' => 'UAV', 'WINCH' => 'GLIDER' }[_1] || _1 })
190
189
  end
191
- builder << vertical_limit.to_xml
192
- builder << timetable.to_xml(as: :Att) if timetable
190
+ vertical_limit.add_to(builder)
191
+ timetable.add_to(builder, as: :Att) if timetable
193
192
  builder.codeSelAvbl(selective? ? 'Y' : 'N') if AIXM.ofmx?
194
193
  builder.txtRmk(remarks) if remarks
195
- builder.target!
196
194
  end
197
195
  end
198
196