aixm 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +91 -11
- data/lib/aixm.rb +10 -0
- data/lib/aixm/base.rb +10 -0
- data/lib/aixm/component/base.rb +1 -1
- data/lib/aixm/component/class_layer.rb +0 -3
- data/lib/aixm/component/geometry.rb +0 -3
- data/lib/aixm/component/geometry/arc.rb +4 -8
- data/lib/aixm/component/geometry/base.rb +8 -0
- data/lib/aixm/component/geometry/border.rb +3 -8
- data/lib/aixm/component/geometry/circle.rb +5 -9
- data/lib/aixm/component/geometry/point.rb +6 -13
- data/lib/aixm/component/schedule.rb +8 -10
- data/lib/aixm/component/vertical_limits.rb +1 -4
- data/lib/aixm/document.rb +9 -6
- data/lib/aixm/f.rb +41 -0
- data/lib/aixm/feature/airspace.rb +5 -9
- data/lib/aixm/feature/base.rb +6 -0
- data/lib/aixm/feature/navigational_aid/base.rb +46 -0
- data/lib/aixm/feature/navigational_aid/designated_point.rb +69 -0
- data/lib/aixm/feature/navigational_aid/dme.rb +54 -0
- data/lib/aixm/feature/navigational_aid/marker.rb +41 -0
- data/lib/aixm/feature/navigational_aid/ndb.rb +56 -0
- data/lib/aixm/feature/navigational_aid/tacan.rb +54 -0
- data/lib/aixm/feature/navigational_aid/vor.rb +92 -0
- data/lib/aixm/refinements.rb +23 -2
- data/lib/aixm/shortcuts.rb +12 -5
- data/lib/aixm/version.rb +1 -1
- data/lib/aixm/xy.rb +9 -6
- data/lib/aixm/z.rb +22 -11
- data/spec/factory.rb +87 -4
- data/spec/lib/aixm/component/class_layer_spec.rb +6 -6
- data/spec/lib/aixm/component/geometry/arc_spec.rb +16 -16
- data/spec/lib/aixm/component/geometry/border_spec.rb +4 -4
- data/spec/lib/aixm/component/geometry/circle_spec.rb +10 -10
- data/spec/lib/aixm/component/geometry/point_spec.rb +4 -4
- data/spec/lib/aixm/component/geometry_spec.rb +21 -21
- data/spec/lib/aixm/component/schedule_spec.rb +6 -6
- data/spec/lib/aixm/component/vertical_limits_spec.rb +18 -18
- data/spec/lib/aixm/document_spec.rb +220 -30
- data/spec/lib/aixm/f_spec.rb +58 -0
- data/spec/lib/aixm/feature/airspace_spec.rb +5 -5
- data/spec/lib/aixm/feature/navigational_aid/base_spec.rb +37 -0
- data/spec/lib/aixm/feature/navigational_aid/designated_point_spec.rb +43 -0
- data/spec/lib/aixm/feature/navigational_aid/dme_spec.rb +43 -0
- data/spec/lib/aixm/feature/navigational_aid/marker_spec.rb +44 -0
- data/spec/lib/aixm/feature/navigational_aid/ndb_spec.rb +54 -0
- data/spec/lib/aixm/feature/navigational_aid/tacan_spec.rb +43 -0
- data/spec/lib/aixm/feature/navigational_aid/vor_spec.rb +58 -0
- data/spec/lib/aixm/refinements_spec.rb +27 -0
- data/spec/lib/aixm/xy_spec.rb +29 -23
- data/spec/lib/aixm/z_spec.rb +33 -17
- metadata +29 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd29f2661b79750343e05d494102c232fa91ffa861038eb4fe2b147fe2a01bd2
|
4
|
+
data.tar.gz: 657c897f48236120da2c82b833f65e8e540585176c46c939b1b9a73a594f13fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a356611cb807985b0dba0cde0fc5ced0ec07b84a9be92608145f32ea736a6d87f283d523855276e8902bb420575e80acca2d9f2109d424348f2c8771593c1a05
|
7
|
+
data.tar.gz: 0d98d537ced8fdea59cae71328bb684144e4c52c684f895b076a401ca39138f64683b796e8ba6486244f326662be9df30851fbf3c7819f4a8489b0c1315edeb0
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## 0.2.0
|
2
|
+
|
3
|
+
* Additions:
|
4
|
+
* Frequency
|
5
|
+
* Navigational aids
|
6
|
+
* `AIXM::Z#qfe?` and friends
|
7
|
+
* Breaking major changes:
|
8
|
+
* Symbols such as :qnh, :ofm or :mhz are downcased now
|
9
|
+
|
10
|
+
## 0.1.4
|
11
|
+
|
12
|
+
* Breaking minor changes:
|
13
|
+
* `AIXM.z(alt: 123, code: :QNE)` is now `AIXM.z(123, :QNE)`
|
14
|
+
|
1
15
|
## 0.1.3
|
2
16
|
|
3
17
|
* Breaking major changes:
|
data/README.md
CHANGED
@@ -31,13 +31,13 @@ You can initialize all elements either traditionally or by use of shorter
|
|
31
31
|
AIXM class methods:
|
32
32
|
|
33
33
|
```ruby
|
34
|
-
AIXM
|
34
|
+
AIXM.airspace(...)
|
35
35
|
AIXM.airspace(...)
|
36
36
|
```
|
37
37
|
|
38
38
|
### Fundamentals
|
39
39
|
|
40
|
-
All fundamentals are
|
40
|
+
All fundamentals are subclasses of `AIXM::Base`.
|
41
41
|
|
42
42
|
### Document
|
43
43
|
|
@@ -77,14 +77,20 @@ AIXM.xy(lat: 11.375955555555556, long: -111.37595555555555)
|
|
77
77
|
Altitudes and heights exist in three different forms:
|
78
78
|
|
79
79
|
```ruby
|
80
|
-
AIXM.z(
|
81
|
-
AIXM.z(
|
82
|
-
AIXM.z(
|
80
|
+
AIXM.z(1000, :qfe) # height: 1000ft above ground
|
81
|
+
AIXM.z(2000, :qnh) # altitude: of 2000ft above mean sea level
|
82
|
+
AIXM.z(45, :qne) # altitude: flight level 45
|
83
|
+
```
|
84
|
+
|
85
|
+
#### Frequency
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
AIXM.f(123.35, :mhz)
|
83
89
|
```
|
84
90
|
|
85
91
|
### Features
|
86
92
|
|
87
|
-
All features are subclasses of `AIXM::Feature`.
|
93
|
+
All features are subclasses of `AIXM::Feature::Base`.
|
88
94
|
|
89
95
|
#### Airspace
|
90
96
|
|
@@ -97,9 +103,72 @@ All features are subclasses of `AIXM::Feature`.
|
|
97
103
|
* class_layers << AIXM.class_layer
|
98
104
|
* remarks = String
|
99
105
|
|
106
|
+
#### Navigational Aids
|
107
|
+
|
108
|
+
##### Designated Point
|
109
|
+
|
110
|
+
* AIXM.designated_point
|
111
|
+
* id: String
|
112
|
+
* name: String
|
113
|
+
* xy: AIXM.xy
|
114
|
+
* z: AIXM.z or *nil*
|
115
|
+
* type: :icao, :adhp, :coordinates or :other
|
116
|
+
* remarks = String
|
117
|
+
|
118
|
+
##### DME
|
119
|
+
|
120
|
+
* AIXM.dme
|
121
|
+
* id: String
|
122
|
+
* name: String
|
123
|
+
* xy: AIXM.xy
|
124
|
+
* z: AIXM.z or *nil*
|
125
|
+
* channel: String
|
126
|
+
* remarks = String
|
127
|
+
|
128
|
+
##### NDB
|
129
|
+
|
130
|
+
* AIXM.ndb
|
131
|
+
* id: String
|
132
|
+
* name: String
|
133
|
+
* xy: AIXM.xy
|
134
|
+
* z: AIXM.z or *nil*
|
135
|
+
* f: AIXM.f
|
136
|
+
* remarks = String
|
137
|
+
|
138
|
+
##### Marker
|
139
|
+
|
140
|
+
* AIXM.marker
|
141
|
+
* id: String
|
142
|
+
* name: String
|
143
|
+
* xy: AIXM.xy
|
144
|
+
* z: AIXM.z or *nil*
|
145
|
+
* remarks = String
|
146
|
+
|
147
|
+
##### TACAN
|
148
|
+
|
149
|
+
* AIXM.tacan
|
150
|
+
* id: String
|
151
|
+
* name: String
|
152
|
+
* xy: AIXM.xy
|
153
|
+
* z: AIXM.z or *nil*
|
154
|
+
* channel: String
|
155
|
+
* remarks = String
|
156
|
+
|
157
|
+
##### VOR and DVOR
|
158
|
+
|
159
|
+
* AIXM.vor
|
160
|
+
* id: String
|
161
|
+
* name: String
|
162
|
+
* xy: AIXM.xy
|
163
|
+
* z: AIXM.z or *nil*
|
164
|
+
* type: :vor or :vordme
|
165
|
+
* f: AIXM.f
|
166
|
+
* north: :geographic or :magnetic
|
167
|
+
* remarks = String
|
168
|
+
|
100
169
|
### Components
|
101
170
|
|
102
|
-
All components are subclasses of `AIXM::Component`.
|
171
|
+
All components are subclasses of `AIXM::Component::Base`.
|
103
172
|
|
104
173
|
#### Schedule
|
105
174
|
|
@@ -148,16 +217,21 @@ For a geometry to be complete, it must be comprised of either:
|
|
148
217
|
|
149
218
|
## Validation
|
150
219
|
|
151
|
-
|
220
|
+
Use `AIXM::Document#complete?` to check whether all mandatory information is
|
152
221
|
present. Airspaces, geometries etc have `complete?` methods as well.
|
153
|
-
|
154
|
-
|
222
|
+
|
223
|
+
Use `AIXM::Document#valid?` to validate the resulting AIXM against the XSD
|
224
|
+
schema. If any, you find the errors in `AIXM::Document#errors`. Since the data
|
225
|
+
model is not fully implemented, some associations cannot be assigned and have
|
226
|
+
to be left empty. The resulting validation errors are silently ignored:
|
227
|
+
|
228
|
+
* OrgUid - organizations may be empty tags
|
155
229
|
|
156
230
|
## Rendering
|
157
231
|
|
158
232
|
```ruby
|
159
233
|
document.to_xml # render AIXM 4.5 compliant XML
|
160
|
-
document.to_xml(:
|
234
|
+
document.to_xml(:ofm) # render AIXM 4.5 + OFM extensions XML
|
161
235
|
```
|
162
236
|
|
163
237
|
## Constants
|
@@ -170,6 +244,7 @@ document.to_xml(:OFM) # render AIXM 4.5 + OFM extensions XML
|
|
170
244
|
|
171
245
|
By `using AIXM::Refinements` you get the following general purpose methods:
|
172
246
|
|
247
|
+
* `Hash#lookup(key, default)`<br>Similar to `fetch` but falls back to values
|
173
248
|
* `String#indent(number)`<br>Indent every line of a string with *number* spaces
|
174
249
|
* `String#uptrans`<br>upcase and transliterate to match the reduced character set for names
|
175
250
|
* `String#to_dd`<br>Convert DMS angle to DD or `nil` if the format is not recognized
|
@@ -177,6 +252,9 @@ By `using AIXM::Refinements` you get the following general purpose methods:
|
|
177
252
|
* `Float#trim`<br>Convert whole numbers to Integer and leave all other untouched
|
178
253
|
* `Float#to_km(from: unit)`<br>Convert a distance from *unit* (:km, :m, :nm or :ft) to km
|
179
254
|
|
255
|
+
See the [source code](https://github.com/svoop/aixm/blob/master/lib/aixm/refinements.rb)
|
256
|
+
for more explicit descriptions and examples.
|
257
|
+
|
180
258
|
## Extensions
|
181
259
|
|
182
260
|
### OFM
|
@@ -194,6 +272,8 @@ originative suite:
|
|
194
272
|
|
195
273
|
* [AIXM](http://aixm.aero)
|
196
274
|
* [AIXM on Wikipedia](https://en.wikipedia.org/wiki/AIXM)
|
275
|
+
* [AIXM 4.5 Specification](http://aixm.aero/document/aixm-45-specification)
|
276
|
+
* [AICM 4.5 Entity-Relationship](https://www.ead.eurocontrol.int/SystemHelp/mergedProjects/SDO/aixm/)
|
197
277
|
* [Open Flightmaps](https://openflightmaps.org)
|
198
278
|
|
199
279
|
## Tests
|
data/lib/aixm.rb
CHANGED
@@ -8,9 +8,11 @@ require 'time'
|
|
8
8
|
require_relative 'aixm/version'
|
9
9
|
require_relative 'aixm/refinements'
|
10
10
|
|
11
|
+
require_relative 'aixm/base'
|
11
12
|
require_relative 'aixm/document'
|
12
13
|
require_relative 'aixm/xy'
|
13
14
|
require_relative 'aixm/z'
|
15
|
+
require_relative 'aixm/f'
|
14
16
|
|
15
17
|
require_relative 'aixm/component/base'
|
16
18
|
require_relative 'aixm/component/geometry'
|
@@ -22,6 +24,14 @@ require_relative 'aixm/component/class_layer'
|
|
22
24
|
require_relative 'aixm/component/vertical_limits'
|
23
25
|
require_relative 'aixm/component/schedule'
|
24
26
|
|
27
|
+
require_relative 'aixm/feature/base'
|
25
28
|
require_relative 'aixm/feature/airspace'
|
29
|
+
require_relative 'aixm/feature/navigational_aid/base'
|
30
|
+
require_relative 'aixm/feature/navigational_aid/designated_point'
|
31
|
+
require_relative 'aixm/feature/navigational_aid/dme'
|
32
|
+
require_relative 'aixm/feature/navigational_aid/marker'
|
33
|
+
require_relative 'aixm/feature/navigational_aid/ndb'
|
34
|
+
require_relative 'aixm/feature/navigational_aid/tacan'
|
35
|
+
require_relative 'aixm/feature/navigational_aid/vor'
|
26
36
|
|
27
37
|
require_relative 'aixm/shortcuts'
|
data/lib/aixm/base.rb
ADDED
data/lib/aixm/component/base.rb
CHANGED
@@ -31,19 +31,15 @@ module AIXM
|
|
31
31
|
|
32
32
|
##
|
33
33
|
# Render AIXM
|
34
|
-
#
|
35
|
-
# Extensions:
|
36
|
-
# * +:OFM+ - Open Flightmaps
|
37
34
|
def to_xml(*extensions)
|
38
|
-
format = extensions >> :OFM ? :OFM : :AIXM
|
39
35
|
builder = Builder::XmlMarkup.new(indent: 2)
|
40
36
|
builder.Avx do |avx|
|
41
37
|
avx.codeType(clockwise? ? 'CWA' : 'CCA')
|
42
|
-
avx.geoLat(xy.lat(
|
43
|
-
avx.geoLong(xy.long(
|
38
|
+
avx.geoLat(xy.lat(format_for(*extensions)))
|
39
|
+
avx.geoLong(xy.long(format_for(*extensions)))
|
44
40
|
avx.codeDatum('WGE')
|
45
|
-
avx.geoLatArc(center_xy.lat(
|
46
|
-
avx.geoLongArc(center_xy.long(
|
41
|
+
avx.geoLatArc(center_xy.lat(format_for(*extensions)))
|
42
|
+
avx.geoLongArc(center_xy.long(format_for(*extensions)))
|
47
43
|
end
|
48
44
|
end
|
49
45
|
end
|
@@ -23,19 +23,14 @@ module AIXM
|
|
23
23
|
|
24
24
|
##
|
25
25
|
# Render AIXM
|
26
|
-
#
|
27
|
-
# Extensions:
|
28
|
-
# * +:OFM+ - Open Flightmaps
|
29
26
|
def to_xml(*extensions)
|
30
|
-
format = extensions >> :OFM ? :OFM : :AIXM
|
31
27
|
builder = Builder::XmlMarkup.new(indent: 2)
|
32
28
|
builder.Avx do |avx|
|
33
29
|
avx.codeType('FNT')
|
34
|
-
avx.geoLat(xy.lat(
|
35
|
-
avx.geoLong(xy.long(
|
30
|
+
avx.geoLat(xy.lat(format_for(*extensions)))
|
31
|
+
avx.geoLong(xy.long(format_for(*extensions)))
|
36
32
|
avx.codeDatum('WGE')
|
37
|
-
|
38
|
-
if extensions >> :OFM
|
33
|
+
if extensions >> :ofm
|
39
34
|
avx.GbrUid do |gbruid|
|
40
35
|
gbruid.txtName(name.to_s)
|
41
36
|
end
|
@@ -4,7 +4,7 @@ module AIXM
|
|
4
4
|
|
5
5
|
##
|
6
6
|
# Circles are defined by a +center_xy+ and a +radius+ in kilometers.
|
7
|
-
class Circle
|
7
|
+
class Circle < Base
|
8
8
|
using AIXM::Refinements
|
9
9
|
|
10
10
|
attr_reader :center_xy, :radius
|
@@ -22,19 +22,15 @@ module AIXM
|
|
22
22
|
|
23
23
|
##
|
24
24
|
# Render AIXM
|
25
|
-
#
|
26
|
-
# Extensions:
|
27
|
-
# * +:OFM+ - Open Flightmaps
|
28
25
|
def to_xml(*extensions)
|
29
|
-
format = extensions >> :OFM ? :OFM : :AIXM
|
30
26
|
builder = Builder::XmlMarkup.new(indent: 2)
|
31
27
|
builder.Avx do |avx|
|
32
28
|
avx.codeType('CWA')
|
33
|
-
avx.geoLat(north_xy.lat(
|
34
|
-
avx.geoLong(north_xy.long(
|
29
|
+
avx.geoLat(north_xy.lat(format_for(*extensions)))
|
30
|
+
avx.geoLong(north_xy.long(format_for(*extensions)))
|
35
31
|
avx.codeDatum('WGE')
|
36
|
-
avx.geoLatArc(center_xy.lat(
|
37
|
-
avx.geoLongArc(center_xy.long(
|
32
|
+
avx.geoLatArc(center_xy.lat(format_for(*extensions)))
|
33
|
+
avx.geoLongArc(center_xy.long(format_for(*extensions)))
|
38
34
|
end
|
39
35
|
end
|
40
36
|
|
@@ -4,9 +4,12 @@ module AIXM
|
|
4
4
|
|
5
5
|
##
|
6
6
|
# Points are defined by +xy+ coordinates.
|
7
|
-
class Point
|
7
|
+
class Point < Base
|
8
|
+
extend Forwardable
|
8
9
|
using AIXM::Refinements
|
9
10
|
|
11
|
+
def_delegators :xy, :to_digest
|
12
|
+
|
10
13
|
attr_reader :xy
|
11
14
|
|
12
15
|
def initialize(xy:)
|
@@ -14,24 +17,14 @@ module AIXM
|
|
14
17
|
@xy = xy
|
15
18
|
end
|
16
19
|
|
17
|
-
##
|
18
|
-
# Digest to identify the payload
|
19
|
-
def to_digest
|
20
|
-
[xy.lat, xy.long].to_digest
|
21
|
-
end
|
22
|
-
|
23
20
|
##
|
24
21
|
# Render AIXM
|
25
|
-
#
|
26
|
-
# Extensions:
|
27
|
-
# * +:OFM+ - Open Flightmaps
|
28
22
|
def to_xml(*extensions)
|
29
|
-
format = extensions >> :OFM ? :OFM : :AIXM
|
30
23
|
builder = Builder::XmlMarkup.new(indent: 2)
|
31
24
|
builder.Avx do |avx|
|
32
25
|
avx.codeType('GRC')
|
33
|
-
avx.geoLat(xy.lat(
|
34
|
-
avx.geoLong(xy.long(
|
26
|
+
avx.geoLat(xy.lat(format_for(*extensions)))
|
27
|
+
avx.geoLong(xy.long(format_for(*extensions)))
|
35
28
|
avx.codeDatum('WGE')
|
36
29
|
end
|
37
30
|
end
|
@@ -12,20 +12,18 @@ module AIXM
|
|
12
12
|
using AIXM::Refinements
|
13
13
|
|
14
14
|
CODES = {
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
H24: :continuous,
|
16
|
+
HJ: :sunrise_to_sunset,
|
17
|
+
HN: :sunset_to_sunrise,
|
18
|
+
HX: :unspecified,
|
19
|
+
HO: :operational_request,
|
20
|
+
NOTAM: :notam
|
21
21
|
}.freeze
|
22
22
|
|
23
23
|
attr_reader :code
|
24
24
|
|
25
25
|
def initialize(code:)
|
26
|
-
@code = code&.to_sym
|
27
|
-
@code = CODES[code] unless CODES.has_value? code
|
28
|
-
fail(ArgumentError, "code `#{code}' not recognized") unless @code
|
26
|
+
@code = CODES.lookup(code&.to_sym, nil) || fail(ArgumentError, "invalid code")
|
29
27
|
end
|
30
28
|
|
31
29
|
##
|
@@ -37,7 +35,7 @@ module AIXM
|
|
37
35
|
##
|
38
36
|
# Render AIXM
|
39
37
|
def to_xml(*extensions)
|
40
|
-
Builder::XmlMarkup.new(indent: 2).codeWorkHr(code.to_s)
|
38
|
+
Builder::XmlMarkup.new(indent: 2).codeWorkHr(CODES.key(code).to_s)
|
41
39
|
end
|
42
40
|
end
|
43
41
|
|
@@ -16,7 +16,7 @@ module AIXM
|
|
16
16
|
using AIXM::Refinements
|
17
17
|
|
18
18
|
TAGS = { upper: :Upper, lower: :Lower, max: :Max, min: :Mnm }.freeze
|
19
|
-
CODES = {
|
19
|
+
CODES = { qfe: :HEI, qnh: :ALT, qne: :STD }.freeze
|
20
20
|
|
21
21
|
attr_reader :upper_z, :lower_z, :max_z, :min_z
|
22
22
|
|
@@ -36,9 +36,6 @@ module AIXM
|
|
36
36
|
|
37
37
|
##
|
38
38
|
# Render AIXM
|
39
|
-
#
|
40
|
-
# Extensions:
|
41
|
-
# * +:OFM+ - Open Flightmaps
|
42
39
|
def to_xml(*extensions)
|
43
40
|
%i(upper lower max min).each_with_object(Builder::XmlMarkup.new(indent: 2)) do |limit, builder|
|
44
41
|
if z = send(:"#{limit}_z")
|