aixm 0.3.7 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +72 -6
  4. data/README.md +191 -53
  5. data/exe/ckmid +11 -0
  6. data/exe/mkmid +11 -0
  7. data/lib/aixm/association.rb +367 -0
  8. data/lib/aixm/classes.rb +44 -0
  9. data/lib/aixm/component/fato.rb +44 -52
  10. data/lib/aixm/component/frequency.rb +13 -14
  11. data/lib/aixm/component/geometry/arc.rb +2 -2
  12. data/lib/aixm/component/geometry/border.rb +14 -5
  13. data/lib/aixm/component/geometry/circle.rb +8 -2
  14. data/lib/aixm/component/geometry/point.rb +10 -3
  15. data/lib/aixm/component/geometry/rhumb_line.rb +54 -0
  16. data/lib/aixm/component/geometry.rb +38 -38
  17. data/lib/aixm/component/helipad.rb +29 -37
  18. data/lib/aixm/component/layer.rb +28 -19
  19. data/lib/aixm/component/lighting.rb +11 -12
  20. data/lib/aixm/component/runway.rb +46 -53
  21. data/lib/aixm/{feature → component}/service.rb +36 -35
  22. data/lib/aixm/component/surface.rb +3 -3
  23. data/lib/aixm/component/timetable.rb +5 -3
  24. data/lib/aixm/component/{vertical_limits.rb → vertical_limit.rb} +12 -6
  25. data/lib/aixm/config.rb +6 -3
  26. data/lib/aixm/document.rb +31 -49
  27. data/lib/aixm/executables.rb +85 -0
  28. data/lib/aixm/f.rb +28 -0
  29. data/lib/aixm/feature/address.rb +20 -15
  30. data/lib/aixm/feature/airport.rb +113 -129
  31. data/lib/aixm/feature/airspace.rb +54 -23
  32. data/lib/aixm/feature/navigational_aid/designated_point.rb +12 -14
  33. data/lib/aixm/feature/navigational_aid/dme.rb +10 -11
  34. data/lib/aixm/feature/navigational_aid/marker.rb +6 -2
  35. data/lib/aixm/feature/navigational_aid/ndb.rb +6 -2
  36. data/lib/aixm/feature/navigational_aid/tacan.rb +6 -2
  37. data/lib/aixm/feature/navigational_aid/vor.rb +22 -14
  38. data/lib/aixm/feature/navigational_aid.rb +7 -9
  39. data/lib/aixm/feature/obstacle.rb +22 -20
  40. data/lib/aixm/feature/obstacle_group.rb +30 -30
  41. data/lib/aixm/feature/organisation.rb +20 -4
  42. data/lib/aixm/feature/unit.rb +35 -45
  43. data/lib/aixm/feature.rb +13 -3
  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 +34 -50
  48. data/lib/aixm/shortcuts.rb +6 -43
  49. data/lib/aixm/version.rb +1 -1
  50. data/lib/aixm/xy.rb +9 -1
  51. data/lib/aixm.rb +18 -7
  52. data/schemas/ofmx/{0 → 0.1}/OFMX-CSV-Obstacle.json +0 -0
  53. data/schemas/ofmx/{0 → 0.1}/OFMX-CSV.json +0 -0
  54. data/schemas/ofmx/{0 → 0.1}/OFMX-DataTypes.xsd +52 -2
  55. data/schemas/ofmx/{0 → 0.1}/OFMX-Features.xsd +225 -14
  56. data/schemas/ofmx/{0 → 0.1}/OFMX-Snapshot.xsd +0 -5
  57. data.tar.gz.sig +0 -0
  58. metadata +116 -164
  59. metadata.gz.sig +0 -0
  60. data/.gitignore +0 -6
  61. data/.ruby-version +0 -1
  62. data/.travis.yml +0 -8
  63. data/.yardopts +0 -3
  64. data/Guardfile +0 -8
  65. data/aixm.gemspec +0 -35
  66. data/gems.rb +0 -3
  67. data/lib/aixm/component.rb +0 -6
  68. data/rakefile.rb +0 -22
  69. data/spec/factory.rb +0 -559
  70. data/spec/lib/aixm/a_spec.rb +0 -203
  71. data/spec/lib/aixm/component/fato_spec.rb +0 -260
  72. data/spec/lib/aixm/component/frequency_spec.rb +0 -75
  73. data/spec/lib/aixm/component/geometry/arc_spec.rb +0 -75
  74. data/spec/lib/aixm/component/geometry/border_spec.rb +0 -33
  75. data/spec/lib/aixm/component/geometry/circle_spec.rb +0 -70
  76. data/spec/lib/aixm/component/geometry/point_spec.rb +0 -39
  77. data/spec/lib/aixm/component/geometry_spec.rb +0 -321
  78. data/spec/lib/aixm/component/helipad_spec.rb +0 -187
  79. data/spec/lib/aixm/component/layer_spec.rb +0 -137
  80. data/spec/lib/aixm/component/lighting_spec.rb +0 -88
  81. data/spec/lib/aixm/component/runway_spec.rb +0 -472
  82. data/spec/lib/aixm/component/surface_spec.rb +0 -124
  83. data/spec/lib/aixm/component/timetable_spec.rb +0 -49
  84. data/spec/lib/aixm/component/vertical_limits_spec.rb +0 -97
  85. data/spec/lib/aixm/config_spec.rb +0 -41
  86. data/spec/lib/aixm/d_spec.rb +0 -150
  87. data/spec/lib/aixm/document_spec.rb +0 -1875
  88. data/spec/lib/aixm/errors_spec.rb +0 -14
  89. data/spec/lib/aixm/f_spec.rb +0 -85
  90. data/spec/lib/aixm/feature/address_spec.rb +0 -55
  91. data/spec/lib/aixm/feature/airport_spec.rb +0 -770
  92. data/spec/lib/aixm/feature/airspace_spec.rb +0 -390
  93. data/spec/lib/aixm/feature/navigational_aid/designated_point_spec.rb +0 -98
  94. data/spec/lib/aixm/feature/navigational_aid/dme_spec.rb +0 -92
  95. data/spec/lib/aixm/feature/navigational_aid/marker_spec.rb +0 -79
  96. data/spec/lib/aixm/feature/navigational_aid/ndb_spec.rb +0 -89
  97. data/spec/lib/aixm/feature/navigational_aid/tacan_spec.rb +0 -88
  98. data/spec/lib/aixm/feature/navigational_aid/vor_spec.rb +0 -245
  99. data/spec/lib/aixm/feature/navigational_aid_spec.rb +0 -52
  100. data/spec/lib/aixm/feature/obstacle_group_spec.rb +0 -326
  101. data/spec/lib/aixm/feature/obstacle_spec.rb +0 -279
  102. data/spec/lib/aixm/feature/organisation_spec.rb +0 -77
  103. data/spec/lib/aixm/feature/service_spec.rb +0 -59
  104. data/spec/lib/aixm/feature/unit_spec.rb +0 -230
  105. data/spec/lib/aixm/feature_spec.rb +0 -38
  106. data/spec/lib/aixm/p_spec.rb +0 -189
  107. data/spec/lib/aixm/refinements_spec.rb +0 -381
  108. data/spec/lib/aixm/version_spec.rb +0 -7
  109. data/spec/lib/aixm/w_spec.rb +0 -150
  110. data/spec/lib/aixm/xy_spec.rb +0 -180
  111. data/spec/lib/aixm/z_spec.rb +0 -94
  112. data/spec/macros/marking.rb +0 -12
  113. data/spec/macros/organisation.rb +0 -11
  114. data/spec/macros/remarks.rb +0 -12
  115. data/spec/macros/timetable.rb +0 -11
  116. data/spec/macros/xy.rb +0 -11
  117. data/spec/macros/z_qnh.rb +0 -11
  118. data/spec/sounds/failure.mp3 +0 -0
  119. data/spec/sounds/success.mp3 +0 -0
  120. data/spec/spec_helper.rb +0 -55
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bad5f1c431575562810faf541c197660e815e3652213dc8d6fedc8cde897f9d4
4
- data.tar.gz: f1a750f511dc13146af92a25aea066a89a67d358534f2f4a582e415919855ef4
3
+ metadata.gz: 2f4efdae60e160732c8f30262673f01b49d6dd53d5c5e9bc2d8c395cf696ccae
4
+ data.tar.gz: 7b129a858e6c6d0eb7545d4a32910243e7a8ecd00a8895698f4ae69fcaed33f2
5
5
  SHA512:
6
- metadata.gz: f587e9d97f7a1fdb21e38f79c2be3567a9a8a8a4c0bc692b74c19305db8b0c2c8fb734d0b90b7ba488916ca9bc23a2a60ba4e836510be6984d1bd95055ffbe28
7
- data.tar.gz: ac70ee0a8c63f20f0fb0277ba075c0880ed2ad39ae32e6c5e38d9fa76d80943a7c8efb394bb33af52f5c6ce00081d066e59d9df9a1105812bfaf8bafc2a23596
6
+ metadata.gz: 98115e7b0f93f82e976235045afdff88b3b6a99b256620de733b4b4741ffa7fb769e6bb92aae86657d6ae57b5744aef5df82a634b22adb5ae81b9db18a7c1531
7
+ data.tar.gz: fd3bf40b77d4cfef51465b4e1806382465a4eee86abd8c74c3639763a627653a7832696395bab9673dd6433458bef8474871b7dcd121533891df3c911a429baf
checksums.yaml.gz.sig ADDED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,3 +1,65 @@
1
+ ## 1.0.0
2
+
3
+ #### Breaking Changes
4
+ * Move `Ase->txtLocalType` up into `AseUid` for OFMX
5
+
6
+ #### Additions
7
+ * Add `AIXM::Component::Geometry::RhumbLine`
8
+
9
+ ## 0.3.11
10
+
11
+ #### Breaking Changes
12
+ * Renamed default git branch to `main`
13
+ * Require Ruby 3.0
14
+ * `Address#address` requires and returns `AIXM::F` for type `:radio_frequency`
15
+
16
+ #### Changes
17
+ * Fix `Obstacle#source` for OFMX
18
+
19
+ #### Additions
20
+ * Add `f#voice?` and `AIXM.config.voice_channel_separation` to check whether a
21
+ frequency belongs to the voice communication airband and use it to validate
22
+ `AIXM::Frequency`
23
+
24
+ ## 0.3.10
25
+
26
+ #### Additions
27
+ * Proper `has_many` and `has_one` associations
28
+ * `AIXM::Association:Array#find_by|find|duplicate` on `has_many` associations
29
+ * `AIXM.config.mid` now defines whether `mid` attributes are inserted or not
30
+ provided the selected schema is OFMX
31
+ * `AIXM::Memoize` module
32
+ * `AIXM::PayloadHash` class
33
+ * `mkmid` executable to insert `mid` attributes into valid OFMX file
34
+ * `ckmid` executable to check `mid` attributes in an OFMX file
35
+ * `AIXM::Component::Geometry#point?|circle?|polygon?`
36
+ * `AIXM::Component::Layer#services`
37
+
38
+ #### Breaking Changes
39
+ * Require Ruby 2.7
40
+ * Moved `region` attribute from `Document` back to features again
41
+ * Use `Document#add_feature` instead of `Document@features#<<`
42
+ * Use `Document@features#find` instead of `Document#select_features`
43
+ * Use `Airspace#add_layer` instead of `Airspace@layers#<<`
44
+ * Use `Geometry#add_segment` instead of `Geometry#<<`
45
+ * Renamed `VerticalLimits` to `VerticalLimit`
46
+ * Moved `AIXM::Feature::Service` to `AIXM::Component::Service`
47
+ * Refinements `String#insert_payload_hash` and `Array#to_uuid` removed again
48
+ * Refinement `String#payload_hash` removed in favor of `AIXM::PayloadHash` class
49
+ * Refinements `Array#find|duplicates` removed
50
+
51
+ #### Changes
52
+ * Renamed `AIXM.config.mid_region` to `AIXM.config.region`
53
+
54
+ ## 0.3.8
55
+
56
+ #### Additions
57
+ * `AIXM.config.mid_region` to insert `mid` attributes
58
+ * Refinement `String#insert_payload_hash`
59
+
60
+ #### Changes
61
+ * Fix calculation of magnetic bearing
62
+
1
63
  ## 0.3.7
2
64
 
3
65
  #### Additions
@@ -37,14 +99,17 @@
37
99
  * `Runway#preparation`, `Runway#condition` and `Runway#vfr_pattern`
38
100
  * `Service#guessed_unit_type`
39
101
  * Surface for `Runway|Helipad#surface`
40
- * Extracted `AIXM::MIN`, `AIXM::SEC` and `AIXM::DMS_RE` to scan for coordinates in texts
41
- * Refinement `String#payload_hash`
102
+ * Extracted `AIXM::MIN`, `AIXM::SEC` and `AIXM::DMS_RE` to scan for coordinates
103
+ in texts
104
+ * Refinements `Array#to_uuid` and `String#payload_hash`
42
105
 
43
106
  #### Breaking Changes
44
107
  * Require Ruby 2.6
45
- * Renamed `AIXM::H` to `AIXM::A` (angle) and add simple arithmetics to make it more versatile
108
+ * Renamed `AIXM::H` to `AIXM::A` (angle) and add simple arithmetics to make it
109
+ more versatile
46
110
  * `Runway|Helipad#composition` moved to `Runway|Helipad#surface`
47
- * DMS notation `{-}{DD}DMMSS{.SS}[NESW]` now requires compulsory cardinal direction (N, E, S or W) at the end
111
+ * DMS notation `{-}{DD}DMMSS{.SS}[NESW]` now requires compulsory cardinal
112
+ direction (N, E, S or W) at the end
48
113
 
49
114
  #### Changes
50
115
  * Service is a feature now
@@ -56,7 +121,8 @@
56
121
 
57
122
  #### Changes
58
123
  * Updated OFMX schema URI
59
- * Added `eql?` and `hash` to `AIXM::XY|Z|D|H|F` to allow for instances of these classes to be used as Hash keys.
124
+ * Added `eql?` and `hash` to `AIXM::XY|Z|D|H|F` to allow for instances of these
125
+ classes to be used as Hash keys.
60
126
 
61
127
  ## 0.3.2
62
128
 
@@ -81,7 +147,7 @@
81
147
  #### Breaking Changes
82
148
  * Renamed `Airport#code` to `Airport#id`
83
149
  * Renamed `Airspace#short_name` to `Airspace#local_type`
84
- * Moved `region` attribute from features to Document
150
+ * Moved `region` attribute from features to `Document`
85
151
 
86
152
  #### Changes
87
153
  * Be more permissive on `Airport#id` in order to accomodate generated codes
data/README.md CHANGED
@@ -1,38 +1,66 @@
1
1
  [![Version](https://img.shields.io/gem/v/aixm.svg?style=flat)](https://rubygems.org/gems/aixm)
2
- [![Continuous Integration](https://img.shields.io/travis/svoop/aixm/master.svg?style=flat)](https://travis-ci.org/svoop/aixm)
2
+ [![Tests](https://img.shields.io/github/workflow/status/svoop/aixm/Test.svg?style=flat&label=tests)](https://github.com/svoop/aixm/actions?workflow=Test)
3
3
  [![Code Climate](https://img.shields.io/codeclimate/maintainability/svoop/aixm.svg?style=flat)](https://codeclimate.com/github/svoop/aixm/)
4
4
  [![Donorbox](https://img.shields.io/badge/donate-on_donorbox-yellow.svg)](https://donorbox.org/bitcetera)
5
5
 
6
6
  # AIXM
7
7
 
8
- Partial implementation of the [Aeronautical Information Exchange Model (AIXM 4.5)](http://aixm.aero) and it's dialect [Open FlightMaps eXchange format (OFMX 0)](https://github.com/openflightmaps/ofmx) for Ruby.
8
+ Partial implementation of the [Aeronautical Information Exchange Model (AIXM 4.5)](http://aixm.aero) and it's dialect [Open FlightMaps eXchange format (OFMX 0)](https://gitlab.com/openflightmaps/ofmx/wikis) for Ruby.
9
9
 
10
10
  For now, only the parts needed to automize the AIP import of [open flightmaps](https://openflightmaps.org) are part of this gem. Most notably, the gem is only a builder for snapshot files and does not parse them.
11
11
 
12
12
  * [Homepage](https://github.com/svoop/aixm)
13
- * [API](http://www.rubydoc.info/gems/aixm)
13
+ * [API](https://www.rubydoc.info/gems/aixm)
14
14
  * Author: [Sven Schwyn - Bitcetera](http://www.bitcetera.com)
15
15
 
16
16
  ## Install
17
17
 
18
- Add this to your `Gemfile`:
18
+ ### Security
19
+
20
+ This gem is [cryptographically signed](https://guides.rubygems.org/security/#using-gems) in order to assure it hasn't been tampered with. Unless already done, please add the author's public key as a trusted certificate now:
21
+
22
+ ```
23
+ gem cert --add <(curl -Ls https://raw.github.com/svoop/aixm/main/certs/svoop.pem)
24
+ ```
25
+
26
+ ### Bundler
27
+
28
+ Add the following to the <tt>Gemfile</tt> or <tt>gems.rb</tt> of your [Bundler](https://bundler.io) powered Ruby project:
19
29
 
20
30
  ```ruby
21
31
  gem aixm
22
32
  ```
23
33
 
34
+ And then install the bundle:
35
+
36
+ ```
37
+ bundle install --trust-policy MediumSecurity
38
+ ```
39
+
40
+ ### Standalone
41
+
42
+ If you're only going to use [the executables](#executables), make sure to have the [latest version of Ruby](https://www.ruby-lang.org/en/documentation/installation/) and then install this gem:
43
+
44
+ ```
45
+ gem install aixm --trust-policy MediumSecurity
46
+ ```
47
+
24
48
  ## Usage
25
49
 
26
50
  Here's how to build a document object, populate it with a simple feature and then render it as AIXM:
27
51
 
28
52
  ```ruby
29
- document = AIXM.document
30
- document.features << AIXM.designated_point(
31
- id: "ABIXI",
32
- xy: AIXM.xy(lat: %q(46°31'54.3"N), long: %q(002°19'55.2"W)),
33
- type: :icao
53
+ document = AIXM.document(
54
+ region: 'LF'
34
55
  )
35
- document.aixm! # not really necessary since AIXM is the default schema
56
+ document.add_feature(
57
+ AIXM.designated_point(
58
+ id: "ABIXI",
59
+ xy: AIXM.xy(lat: %q(46°31'54.3"N), long: %q(002°19'55.2"W)),
60
+ type: :icao
61
+ )
62
+ )
63
+ AIXM.ofmx!
36
64
  document.to_xml
37
65
  ```
38
66
 
@@ -47,11 +75,12 @@ See `AIXM::CLASSES` for the complete list of shorthand names.
47
75
 
48
76
  ## Configuration
49
77
 
50
- The following configuration options are available for setting and getting:
78
+ ### AIXM.config.schema
79
+
80
+ The schema is either `:aixm` (default) or `:ofmx`:
51
81
 
52
82
  ```ruby
53
- AIXM.config.schema # either :aixm (default) or :ofmx
54
- AIXM.config.ignored_errors # ignore XML schema errors which match this regex
83
+ AIXM.config.schema = :ofmx # =>:ofmx
55
84
  ```
56
85
 
57
86
  There are shortcuts to set and get the schema:
@@ -65,65 +94,174 @@ AIXM.schema # => :ofmx
65
94
  AIXM.schema(:version) # => 0
66
95
  ```
67
96
 
68
- ## Validation
97
+ ### AIXM.config.region
69
98
 
70
- `AIXM::Document#valid?` validates the resulting AIXM or OFMX against its XML schema. If any, you find the errors in `AIXM::Document#errors`.
99
+ The `:ofmx` schema requires the [region to be set on all core features](https://gitlab.com/openflightmaps/ofmx/wikis/Features#core-features). You can do so on individual features, however, you might want to configure a default region to simplify your life:
100
+
101
+ ```ruby
102
+ AIXM.ofmx!
103
+ AIXM.config.region = 'LF'
104
+ ```
105
+
106
+ :warning: This setting has no effect when using the `:aixm` schema.
107
+
108
+ ### AIXM.voice_channel_separation
109
+
110
+ Define which voice channel separation should be used to validate voice communication frequencies.
111
+
112
+ ```ruby
113
+ AIXM.voice_channel_separation = :any # both 25 and 8.33 kHz (default)
114
+ AIXM.voice_channel_separation = 25 # 25 kHz only
115
+ AIXM.voice_channel_separation = 833 # 8.33 kHz only
116
+ ```
117
+
118
+ ### AIXM.config.mid
119
+
120
+ In order to insert [OFMX-compliant `mid` attributes](https://gitlab.com/openflightmaps/ofmx/wikis/Features#mid) into all `*Uid` elements, you have set the mid configuration option to `true`.
121
+
122
+ ```ruby
123
+ AIXM.ofmx!
124
+ AIXM.config.mid = false # don't insert mid attributes (default)
125
+ AIXM.config.mid = true # insert mid attributes
126
+ ```
127
+
128
+ :warning: This setting has no effect when using the `:aixm` schema.
129
+
130
+ ### AIXM.config.ignored_errors
131
+
132
+ In case you want to ignore certain XML schema validation errors, set this configuration option to a regular expression which matches the error messages to ignore. By default, no errors are ignored.
133
+
134
+ ```ruby
135
+ AIXM.config.ignored_errors = /invalid date/i
136
+ ```
71
137
 
72
- ## Model
138
+ ## Models
73
139
 
74
140
  ### Fundamentals
75
- * [Document](http://www.rubydoc.info/gems/aixm/AIXM/Document.html)
76
- * [XY (longitude and latitude)](http://www.rubydoc.info/gems/aixm/AIXM/XY.html)
77
- * [Z (height, elevation or altitude)](http://www.rubydoc.info/gems/aixm/AIXM/Z.html)
78
- * [D (distance or length)](http://www.rubydoc.info/gems/aixm/AIXM/D.html)
79
- * [F (frequency)](http://www.rubydoc.info/gems/aixm/AIXM/F.html)
80
- * [A (angle)](http://www.rubydoc.info/gems/aixm/AIXM/A.html)
141
+ * [Document](https://www.rubydoc.info/gems/aixm/AIXM/Document.html)
142
+ * [XY (longitude and latitude)](https://www.rubydoc.info/gems/aixm/AIXM/XY.html)
143
+ * [Z (height, elevation or altitude)](https://www.rubydoc.info/gems/aixm/AIXM/Z.html)
144
+ * [D (distance or length)](https://www.rubydoc.info/gems/aixm/AIXM/D.html)
145
+ * [F (frequency)](https://www.rubydoc.info/gems/aixm/AIXM/F.html)
146
+ * [A (angle)](https://www.rubydoc.info/gems/aixm/AIXM/A.html)
81
147
 
82
148
  ### Features
83
- * [Address](http://www.rubydoc.info/gems/aixm/AIXM/Feature/Address.html)
84
- * [Organisation](http://www.rubydoc.info/gems/aixm/AIXM/Feature/Organisation.html)
85
- * [Unit](http://www.rubydoc.info/gems/aixm/AIXM/Feature/Unit.html)
86
- * [Service](http://www.rubydoc.info/gems/aixm/AIXM/Component/Service.html)
87
- * [Airport](http://www.rubydoc.info/gems/aixm/AIXM/Feature/Airport.html)
88
- * [Airspace](http://www.rubydoc.info/gems/aixm/AIXM/Feature/Airspace.html)
89
- * [Navigational aid](http://www.rubydoc.info/gems/aixm/AIXM/NavigationalAid.html)
90
- * [Designated point](http://www.rubydoc.info/gems/aixm/AIXM/Feature/DesignatedPoint.html)
91
- * [DME](http://www.rubydoc.info/gems/aixm/AIXM/Feature/DME.html)
92
- * [Marker](http://www.rubydoc.info/gems/aixm/AIXM/Feature/Marker.html)
93
- * [NDB](http://www.rubydoc.info/gems/aixm/AIXM/Feature/NDB.html)
94
- * [TACAN](http://www.rubydoc.info/gems/aixm/AIXM/Feature/TACAN.html)
95
- * [VOR](http://www.rubydoc.info/gems/aixm/AIXM/Feature/VOR.html)
96
- * [Obstacle and obstacle group](http://www.rubydoc.info/gems/aixm/AIXM/Feature/Obstacle.html)
149
+ * [Address](https://www.rubydoc.info/gems/aixm/AIXM/Feature/Address.html)
150
+ * [Organisation](https://www.rubydoc.info/gems/aixm/AIXM/Feature/Organisation.html)
151
+ * [Unit](https://www.rubydoc.info/gems/aixm/AIXM/Feature/Unit.html)
152
+ * [Service](https://www.rubydoc.info/gems/aixm/AIXM/Component/Service.html)
153
+ * [Airport](https://www.rubydoc.info/gems/aixm/AIXM/Feature/Airport.html)
154
+ * [Airspace](https://www.rubydoc.info/gems/aixm/AIXM/Feature/Airspace.html)
155
+ * [Navigational aid](https://www.rubydoc.info/gems/aixm/AIXM/NavigationalAid.html)
156
+ * [Designated point](https://www.rubydoc.info/gems/aixm/AIXM/Feature/DesignatedPoint.html)
157
+ * [DME](https://www.rubydoc.info/gems/aixm/AIXM/Feature/DME.html)
158
+ * [Marker](https://www.rubydoc.info/gems/aixm/AIXM/Feature/Marker.html)
159
+ * [NDB](https://www.rubydoc.info/gems/aixm/AIXM/Feature/NDB.html)
160
+ * [TACAN](https://www.rubydoc.info/gems/aixm/AIXM/Feature/TACAN.html)
161
+ * [VOR](https://www.rubydoc.info/gems/aixm/AIXM/Feature/VOR.html)
162
+ * [Obstacle and obstacle group](https://www.rubydoc.info/gems/aixm/AIXM/Feature/Obstacle.html)
97
163
 
98
164
  ### Components
99
- * [Frequency](http://www.rubydoc.info/gems/aixm/AIXM/Component/Frequency.html)
100
- * [Geometry](http://www.rubydoc.info/gems/aixm/AIXM/Component/Geometry.html)
101
- * [Point](http://www.rubydoc.info/gems/aixm/AIXM/Component/Point.html)
102
- * [Arc](http://www.rubydoc.info/gems/aixm/AIXM/Component/Arc.html)
103
- * [Border](http://www.rubydoc.info/gems/aixm/AIXM/Component/Border.html)
104
- * [Circle](http://www.rubydoc.info/gems/aixm/AIXM/Component/Circle.html)
105
- * [Runway](http://www.rubydoc.info/gems/aixm/AIXM/Component/Runway.html)
106
- * [Helipad](http://www.rubydoc.info/gems/aixm/AIXM/Component/Helipad.html)
107
- * [FATO](http://www.rubydoc.info/gems/aixm/AIXM/Component/FATO.html)
108
- * [Surface](http://www.rubydoc.info/gems/aixm/AIXM/Component/Surface.html)
109
- * [Layer](http://www.rubydoc.info/gems/aixm/AIXM/Component/Layer.html)
110
- * [Vertical limits](http://www.rubydoc.info/gems/aixm/AIXM/Component/VerticalLimits.html)
111
- * [Timetable](http://www.rubydoc.info/gems/aixm/AIXM/Component/Timetable.html)
165
+ * [Frequency](https://www.rubydoc.info/gems/aixm/AIXM/Component/Frequency.html)
166
+ * [Geometry](https://www.rubydoc.info/gems/aixm/AIXM/Component/Geometry.html)
167
+ * [Point](https://www.rubydoc.info/gems/aixm/AIXM/Component/Point.html)
168
+ * [Arc](https://www.rubydoc.info/gems/aixm/AIXM/Component/Arc.html)
169
+ * [Border](https://www.rubydoc.info/gems/aixm/AIXM/Component/Border.html)
170
+ * [Circle](https://www.rubydoc.info/gems/aixm/AIXM/Component/Circle.html)
171
+ * [Runway](https://www.rubydoc.info/gems/aixm/AIXM/Component/Runway.html)
172
+ * [Helipad](https://www.rubydoc.info/gems/aixm/AIXM/Component/Helipad.html)
173
+ * [FATO](https://www.rubydoc.info/gems/aixm/AIXM/Component/FATO.html)
174
+ * [Surface](https://www.rubydoc.info/gems/aixm/AIXM/Component/Surface.html)
175
+ * [Layer](https://www.rubydoc.info/gems/aixm/AIXM/Component/Layer.html)
176
+ * [Vertical limit](https://www.rubydoc.info/gems/aixm/AIXM/Component/VerticalLimit.html)
177
+ * [Timetable](https://www.rubydoc.info/gems/aixm/AIXM/Component/Timetable.html)
178
+
179
+ ## Associations
180
+
181
+ The different models are interwoven with [`has_many` and `has_one` associations](https://www.rubydoc.info/gems/aixm/AIXM/Association).
182
+
183
+ 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:
184
+
185
+ ```ruby
186
+ document.features << airport # => NoMethodError
187
+ document.add_feature airport # okay
188
+ ```
189
+
190
+ ### find_by and find
191
+
192
+ Use `find_by` on `has_many` to filter associations by class and optional attribute values:
193
+
194
+ ```ruby
195
+ document.features.find_by(:airport) # => [#<AIXM::Feature::Airport>, #<AIXM::Feature::Airport>]
196
+ document.features.find_by(:airport, id: 'LFNT') # => [#<AIXM::Feature::Airport>]
197
+ ```
198
+
199
+ To search a `has_many` association for equal objects, use `find`:
200
+
201
+ ```ruby
202
+ document.features.find(airport) # => [#<AIXM::Feature::Airport>]
203
+ ```
204
+
205
+ This may seem redundant at first, but keep in mind that two instances of +AIXM::CLASSES+ which implement `#to_uid` are considered equal if they are instances of the same class and both their UIDs as calculated by `#to_uid` are equal. Attributes which are not part of the `#to_uid` calculation are irrelevant!
206
+
207
+ ### duplicates
208
+
209
+ Equally on `has_many` associations, use `duplicates` to find identical or equal associations:
210
+
211
+ ```ruby
212
+ document.features.duplicates # => [#<AIXM::Feature::Unit>, #<AIXM::Component::Service>, ...]
213
+ ```
214
+
215
+ ## Payload Hash
216
+
217
+ 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:
218
+
219
+ ```ruby
220
+ # Payload hash of XML fragment string
221
+ xml = '<xml><a></a></xml>'
222
+ AIXM::PayloadHash.new(xml).to_uuid
223
+
224
+ # Payload hash of Nokogiri XML fragment
225
+ document = File.open("file.xml") { Nokogiri::XML(_1) }
226
+ AIXM::PayloadHash.new(document).to_uuid
227
+ ```
228
+
229
+ ## Validation
230
+
231
+ `AIXM::Document#valid?` validates the resulting AIXM or OFMX against its XML schema. If any, you find the errors in `AIXM::Document#errors`.
112
232
 
113
233
  ## Refinements
114
234
 
115
- By `using AIXM::Refinements` you get a few handy [extensions to Ruby core classes](http://www.rubydoc.info/gems/aixm/AIXM/Refinements.html).
235
+ By `using AIXM::Refinements` you get a few handy [extensions to Ruby core classes](https://www.rubydoc.info/gems/aixm/AIXM/Refinements.html).
236
+
237
+ ## Executables
238
+
239
+ ### mkmid
240
+
241
+ The `mkmid` executable reads an OFMX file, adds [OFMX-compliant `mid` values](https://gitlab.com/openflightmaps/ofmx/wikis/Features#mid) into all `*Uid` elements and validates the result against the schema.
242
+
243
+ ```
244
+ mkmid --help
245
+ ```
246
+
247
+ ### ckmid
248
+
249
+ The `chmid` executable reads an OFMX file, validates it against the schema and checks all `mid` attributes for [OFMX-compliance](https://gitlab.com/openflightmaps/ofmx/wikis/Features#mid).
250
+
251
+ ```
252
+ ckmid --help
253
+ ```
116
254
 
117
255
  ## References
118
256
 
119
257
  ### AIXM
120
258
  * [AIXM](http://aixm.aero)
121
- * [AICM 4.5 documentation](https://openflightmaps.github.io/ofmx/aixm/4.5/manual/aicm/)
259
+ * [AICM 4.5 documentation](https://openflightmaps.gitlab.io/ofmx/aixm/4.5/manual/aicm/)
122
260
  * [AIXM 4.5 specification](http://aixm.aero/document/aixm-45-specification)
123
261
 
124
262
  ### OFMX
125
- * [OFMX](https://github.com/openflightmaps/ofmx)
126
- * [OFMX documentation](https://github.com/openflightmaps/ofmx/wiki)
263
+ * [OFMX](https://gitlab.com/openflightmaps/ofmx)
264
+ * [OFMX documentation](https://gitlab.com/openflightmaps/ofmx/wikis)
127
265
  * [open flightmaps](https://openflightmaps.org)
128
266
 
129
267
  ## Tests
data/exe/ckmid ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+ ruby '>= 3.0'
8
+ gem 'aixm', '~> 0'
9
+ end
10
+
11
+ AIXM::Executables::Ckmid.new.run
data/exe/mkmid ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/inline'
4
+
5
+ gemfile do
6
+ source 'https://rubygems.org'
7
+ ruby '>= 3.0'
8
+ gem 'aixm', '~> 0'
9
+ end
10
+
11
+ AIXM::Executables::Mkmid.new.run