aixm 0.3.7 → 1.0.0

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 (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