aixm 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +43 -13
- data/README.md +31 -20
- data/lib/aixm/a.rb +89 -71
- data/lib/aixm/association.rb +37 -27
- data/lib/aixm/classes.rb +5 -2
- data/lib/aixm/{feature → component}/address.rb +12 -9
- data/lib/aixm/component/approach_lighting.rb +136 -0
- data/lib/aixm/component/fato.rb +58 -42
- data/lib/aixm/component/frequency.rb +2 -2
- data/lib/aixm/component/geometry/arc.rb +1 -1
- data/lib/aixm/component/geometry/border.rb +1 -1
- data/lib/aixm/component/geometry/circle.rb +3 -3
- data/lib/aixm/component/geometry/point.rb +1 -1
- data/lib/aixm/component/geometry/rhumb_line.rb +1 -1
- data/lib/aixm/component/geometry.rb +3 -2
- data/lib/aixm/component/helipad.rb +26 -36
- data/lib/aixm/component/layer.rb +5 -3
- data/lib/aixm/component/lighting.rb +5 -5
- data/lib/aixm/component/runway.rb +81 -52
- data/lib/aixm/component/service.rb +12 -3
- data/lib/aixm/component/surface.rb +12 -12
- data/lib/aixm/component/timetable.rb +2 -2
- data/lib/aixm/component/vasis.rb +105 -0
- data/lib/aixm/component/vertical_limit.rb +3 -3
- data/lib/aixm/component.rb +10 -0
- data/lib/aixm/config.rb +2 -0
- data/lib/aixm/d.rb +16 -15
- data/lib/aixm/document.rb +10 -1
- data/lib/aixm/f.rb +1 -1
- data/lib/aixm/feature/airport.rb +34 -10
- data/lib/aixm/feature/airspace.rb +3 -0
- data/lib/aixm/feature/navigational_aid/dme.rb +29 -10
- data/lib/aixm/feature/navigational_aid/marker.rb +2 -2
- data/lib/aixm/feature/navigational_aid/tacan.rb +3 -2
- data/lib/aixm/feature/navigational_aid/vor.rb +32 -13
- data/lib/aixm/feature/navigational_aid.rb +1 -1
- data/lib/aixm/feature/obstacle.rb +6 -6
- data/lib/aixm/feature/obstacle_group.rb +6 -2
- data/lib/aixm/feature/organisation.rb +1 -0
- data/lib/aixm/feature/unit.rb +2 -1
- data/lib/aixm/feature.rb +3 -0
- data/lib/aixm/memoize.rb +27 -11
- data/lib/aixm/p.rb +3 -2
- data/lib/aixm/payload_hash.rb +1 -1
- data/lib/aixm/r.rb +62 -0
- data/lib/aixm/refinements.rb +4 -4
- data/lib/aixm/version.rb +1 -1
- data/lib/aixm/w.rb +2 -1
- data/lib/aixm/xy.rb +1 -1
- data/lib/aixm/z.rb +5 -4
- data/lib/aixm.rb +10 -5
- data/schemas/ofmx/0.1/OFMX-DataTypes.xsd +6 -0
- data/schemas/ofmx/0.1/OFMX-Snapshot.xsd +5 -0
- data.tar.gz.sig +0 -0
- metadata +8 -4
- metadata.gz.sig +0 -0
data/lib/aixm/document.rb
CHANGED
@@ -22,6 +22,7 @@ module AIXM
|
|
22
22
|
# @!method features
|
23
23
|
# @return [Array<AIXM::Feature>] features (e.g. airport or airspace) present
|
24
24
|
# in this document
|
25
|
+
#
|
25
26
|
# @!method add_feature(feature)
|
26
27
|
# @param feature [AIXM::Feature]
|
27
28
|
# @return [self]
|
@@ -58,6 +59,13 @@ module AIXM
|
|
58
59
|
@effective_at = value&.to_time || created_at || Time.now
|
59
60
|
end
|
60
61
|
|
62
|
+
# Regions used throughout this document.
|
63
|
+
#
|
64
|
+
# @return [Array<String>] white space separated list of region codes
|
65
|
+
def regions
|
66
|
+
features.map(&:region).uniq.sort
|
67
|
+
end
|
68
|
+
|
61
69
|
# Compare all ungrouped obstacles and create new obstacle groups whose
|
62
70
|
# members are located within +max_distance+ pairwise.
|
63
71
|
#
|
@@ -110,6 +118,7 @@ module AIXM
|
|
110
118
|
version: AIXM.schema(:version),
|
111
119
|
origin: "rubygem aixm-#{AIXM::VERSION}",
|
112
120
|
namespace: (namespace if AIXM.ofmx?),
|
121
|
+
regions: (regions.join(' '.freeze) if AIXM.ofmx?),
|
113
122
|
created: @created_at.xmlschema,
|
114
123
|
effective: @effective_at.xmlschema
|
115
124
|
}.compact
|
@@ -117,7 +126,7 @@ module AIXM
|
|
117
126
|
builder.instruct!
|
118
127
|
builder.tag!(AIXM.schema(:root), meta) do |root|
|
119
128
|
AIXM::Memoize.method :to_uid do
|
120
|
-
root << features.map
|
129
|
+
root << features.map(&:to_xml).join.indent(2)
|
121
130
|
end
|
122
131
|
end
|
123
132
|
if AIXM.ofmx? && AIXM.config.mid
|
data/lib/aixm/f.rb
CHANGED
data/lib/aixm/feature/airport.rb
CHANGED
@@ -16,7 +16,7 @@ module AIXM
|
|
16
16
|
# xy: AIXM.xy
|
17
17
|
# )
|
18
18
|
# airport.gps = String or nil
|
19
|
-
# airport.type = TYPES
|
19
|
+
# airport.type = TYPES (other than AD, HP and AH only)
|
20
20
|
# airport.z = AIXM.z or nil
|
21
21
|
# airport.declination = Float or nil
|
22
22
|
# airport.transition_z = AIXM.z or nil
|
@@ -27,6 +27,8 @@ module AIXM
|
|
27
27
|
# airport.add_fato(AIXM.fato)
|
28
28
|
# airport.add_helipad(AIXM.helipad)
|
29
29
|
# airport.add_usage_limitation(UsageLimitation::TYPES)
|
30
|
+
# airport.add_unit(AIXM.unit)
|
31
|
+
# airport.add_service(AIXM.service)
|
30
32
|
# airport.add_address(AIXM.address)
|
31
33
|
#
|
32
34
|
# For airports without an +id+, you may assign the two character region
|
@@ -48,33 +50,30 @@ module AIXM
|
|
48
50
|
LS: :landing_site
|
49
51
|
}.freeze
|
50
52
|
|
51
|
-
# @!method addresses
|
52
|
-
# @return [Array<AIXM::Feature::Address>] postal address, url, A/A or A/G frequency etc
|
53
|
-
# @!method add_address(address)
|
54
|
-
# @param address [AIXM::Feature::Address]
|
55
|
-
# @return [self]
|
56
|
-
has_many :addresses, as: :addressable
|
57
|
-
|
58
53
|
# @!method fatos
|
59
54
|
# @return [Array<AIXM::Component::FATO>] FATOs present at this airport
|
55
|
+
#
|
60
56
|
# @!method add_fato(fato)
|
61
57
|
# @param fato [AIXM::Component::FATO]
|
62
58
|
has_many :fatos
|
63
59
|
|
64
60
|
# @!method helipads
|
65
61
|
# @return [Array<AIXM::Component::Helipad>] helipads present at this airport
|
62
|
+
#
|
66
63
|
# @!method add_helipad(helipad)
|
67
64
|
# @param helipad [AIXM::Component::Helipad]
|
68
65
|
has_many :helipads
|
69
66
|
|
70
67
|
# @!method runways
|
71
68
|
# @return [Array<AIXM::Component::Runway>] runways present at this airport
|
69
|
+
#
|
72
70
|
# @!method add_runway(runway)
|
73
71
|
# @param runway [AIXM::Component::Runway]
|
74
72
|
has_many :runways
|
75
73
|
|
76
74
|
# @!method usage_limitations
|
77
75
|
# @return [Array<AIXM::Feature::Airport::UsageLimitation>] usage limitations
|
76
|
+
#
|
78
77
|
# @!method add_usage_limitation
|
79
78
|
# @yield [AIXM::Feature::Airport::UsageLimitation]
|
80
79
|
# @return [self]
|
@@ -82,16 +81,33 @@ module AIXM
|
|
82
81
|
|
83
82
|
# @!method designated_points
|
84
83
|
# @return [Array<AIXM::Feature::NavigationalAid::DesignatedPoint>] designated points
|
84
|
+
#
|
85
85
|
# @!method add_designated_point(designated_point)
|
86
86
|
# @param designated_point [AIXM::Feature::NavigationalAid::DesignatedPoint]
|
87
87
|
has_many :designated_points
|
88
88
|
|
89
89
|
# @!method units
|
90
90
|
# @return [Array<AIXM::Feature::Unit>] units
|
91
|
+
#
|
91
92
|
# @!method add_unit(unit)
|
92
93
|
# @param unit [AIXM::Feature::Unit]
|
93
94
|
has_many :units
|
94
95
|
|
96
|
+
# @!method services
|
97
|
+
# @return [Array<AIXM::Component::Service>] services
|
98
|
+
#
|
99
|
+
# @!method add_service(service)
|
100
|
+
# @param service [AIXM::Component::Service]
|
101
|
+
has_many :services
|
102
|
+
|
103
|
+
# @!method addresses
|
104
|
+
# @return [Array<AIXM::Feature::Address>] postal address, url, A/A or A/G frequency etc
|
105
|
+
#
|
106
|
+
# @!method add_address(address)
|
107
|
+
# @param address [AIXM::Feature::Address]
|
108
|
+
# @return [self]
|
109
|
+
has_many :addresses, as: :addressable
|
110
|
+
|
95
111
|
# @!method organisation
|
96
112
|
# @return [AIXM::Feature::Organisation] superior organisation
|
97
113
|
belongs_to :organisation, as: :member
|
@@ -144,8 +160,7 @@ module AIXM
|
|
144
160
|
|
145
161
|
def initialize(source: nil, region: nil, organisation:, id: nil, name:, xy:)
|
146
162
|
super(source: source, region: region)
|
147
|
-
self.organisation, self.name, self.xy = organisation, name, xy
|
148
|
-
self.id = id # name must already be set
|
163
|
+
self.organisation, self.name, self.id, self.xy = organisation, name, id, xy # name must be set before id
|
149
164
|
end
|
150
165
|
|
151
166
|
# @return [String]
|
@@ -293,6 +308,14 @@ module AIXM
|
|
293
308
|
sequences[address.type] = (sequences[address.type] || 0) + 1
|
294
309
|
builder << address.to_xml(as: :Aha, sequence: sequences[address.type])
|
295
310
|
end
|
311
|
+
services.each do |service|
|
312
|
+
builder.Sah do |sah|
|
313
|
+
sah.SahUid do |sah_uid|
|
314
|
+
sah_uid << to_uid.indent(4)
|
315
|
+
sah_uid << service.to_uid.indent(4)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
296
319
|
builder.target!
|
297
320
|
end
|
298
321
|
|
@@ -337,6 +360,7 @@ module AIXM
|
|
337
360
|
|
338
361
|
# @!method conditions
|
339
362
|
# @return [Array<AIXM::Feature::Airport::UsageLimitation::Condition>] conditions for this limitation to apply
|
363
|
+
#
|
340
364
|
# @!method add_condition
|
341
365
|
# @yield [AIXM::Feature::Airport::UsageLimitation::Condition]
|
342
366
|
# @return [self]
|
@@ -80,18 +80,21 @@ module AIXM
|
|
80
80
|
|
81
81
|
# @!method geometry
|
82
82
|
# @return [AIXM::Component::Geometry] horizontal geometry shape
|
83
|
+
#
|
83
84
|
# @!method geometry=(geometry)
|
84
85
|
# @param geometry [AIXM::Component::Geometry]
|
85
86
|
has_one :geometry
|
86
87
|
|
87
88
|
# @!method layers
|
88
89
|
# @return [Array<AIXM::Compoment::Layer>] vertical layers
|
90
|
+
#
|
89
91
|
# @!method add_layer(layer)
|
90
92
|
# @param layer [AIXM::Compoment::Layer]
|
91
93
|
has_many :layers
|
92
94
|
|
93
95
|
# @note When assigning +nil+, a 4 byte hex derived from {#type}, {#name}
|
94
96
|
# and {#local_type} is written instead.
|
97
|
+
#
|
95
98
|
# @return [String] published identifier (e.g. "LFP81")
|
96
99
|
attr_reader :id
|
97
100
|
|
@@ -18,7 +18,8 @@ module AIXM
|
|
18
18
|
# name: String
|
19
19
|
# xy: AIXM.xy
|
20
20
|
# z: AIXM.z or nil
|
21
|
-
# channel: String
|
21
|
+
# channel: String # either set channel directly
|
22
|
+
# ghost_f: AIXM.f # or set channel via VOR ghost frequency
|
22
23
|
# )
|
23
24
|
# dme.timetable = AIXM.timetable or nil
|
24
25
|
# dme.remarks = String or nil
|
@@ -31,6 +32,13 @@ module AIXM
|
|
31
32
|
|
32
33
|
CHANNEL_RE = /\A([1-9]|[1-9]\d|1[0-1]\d|12[0-6])[XY]\z/.freeze
|
33
34
|
|
35
|
+
GHOST_MAP = {
|
36
|
+
108_00 => (17..59),
|
37
|
+
112_30 => (70..126),
|
38
|
+
133_30 => (60..69),
|
39
|
+
134_40 => (1..16)
|
40
|
+
}.freeze
|
41
|
+
|
34
42
|
# @!method vor
|
35
43
|
# @return [AIXM::Feature::NavigationalAid::VOR, nil] associated VOR
|
36
44
|
belongs_to :vor, readonly: true
|
@@ -38,9 +46,13 @@ module AIXM
|
|
38
46
|
# @return [String] radio channel
|
39
47
|
attr_reader :channel
|
40
48
|
|
41
|
-
def initialize(channel
|
49
|
+
def initialize(channel: nil, ghost_f: nil, **arguments)
|
42
50
|
super(**arguments)
|
43
|
-
|
51
|
+
case
|
52
|
+
when channel then self.channel = channel
|
53
|
+
when ghost_f then self.ghost_f = ghost_f
|
54
|
+
else fail(ArgumentError, "either channel or ghost_f must be set")
|
55
|
+
end
|
44
56
|
end
|
45
57
|
|
46
58
|
def channel=(value)
|
@@ -48,17 +60,24 @@ module AIXM
|
|
48
60
|
@channel = value
|
49
61
|
end
|
50
62
|
|
63
|
+
def ghost_f=(value)
|
64
|
+
fail(ArgumentError, "invalid ghost_f") unless value.is_a?(AIXM::F) && value.unit == :mhz
|
65
|
+
integer, letter = (value.freq * 100).round, 'X'
|
66
|
+
unless (integer % 10).zero?
|
67
|
+
integer -= 5
|
68
|
+
letter = 'Y'
|
69
|
+
end
|
70
|
+
base = GHOST_MAP.keys.reverse.bsearch { _1 <= integer }
|
71
|
+
number = ((integer - base) / 10) + GHOST_MAP[base].min
|
72
|
+
self.channel = "#{number}#{letter}"
|
73
|
+
end
|
74
|
+
|
51
75
|
# @return [AIXM::F] ghost frequency matching the channel
|
52
76
|
def ghost_f
|
53
77
|
if channel
|
54
78
|
number, letter = channel.split(/(?=[XY])/)
|
55
|
-
integer =
|
56
|
-
|
57
|
-
when (17..59) then 10630
|
58
|
-
when (60..69) then 12730
|
59
|
-
when (70..126) then 10530
|
60
|
-
end
|
61
|
-
integer += number.to_i * 10
|
79
|
+
integer = GHOST_MAP.find { _2.include?(number.to_i) }.first
|
80
|
+
integer += (number.to_i - GHOST_MAP[integer].min) * 10
|
62
81
|
integer += 5 if letter == 'Y'
|
63
82
|
AIXM.f(integer.to_f / 100, :mhz)
|
64
83
|
end
|
@@ -28,7 +28,7 @@ module AIXM
|
|
28
28
|
# @see https://gitlab.com/openflightmaps/ofmx/wikis/Navigational-aid#mkr-marker-beacon
|
29
29
|
class Marker < NavigationalAid
|
30
30
|
include AIXM::Memoize
|
31
|
-
|
31
|
+
|
32
32
|
public_class_method :new
|
33
33
|
|
34
34
|
TYPES = {
|
@@ -46,7 +46,7 @@ module AIXM
|
|
46
46
|
def initialize(type:, **arguments)
|
47
47
|
super(**arguments)
|
48
48
|
self.type = type
|
49
|
-
warn("WARNING:
|
49
|
+
warn("WARNING: Marker is not fully implemented yet due to the lack of ILS")
|
50
50
|
end
|
51
51
|
|
52
52
|
def type=(value)
|
@@ -17,7 +17,8 @@ module AIXM
|
|
17
17
|
# name: String
|
18
18
|
# xy: AIXM.xy
|
19
19
|
# z: AIXM.z or nil
|
20
|
-
# channel: String
|
20
|
+
# channel: String # either set channel directly
|
21
|
+
# ghost_f: AIXM.f # or set channel via VOR ghost frequency
|
21
22
|
# )
|
22
23
|
# tacan.timetable = AIXM.timetable or nil
|
23
24
|
# tacan.remarks = String or nil
|
@@ -25,7 +26,7 @@ module AIXM
|
|
25
26
|
# @see https://gitlab.com/openflightmaps/ofmx/wikis/Navigational-aid#tcn-tacan
|
26
27
|
class TACAN < DME
|
27
28
|
include AIXM::Memoize
|
28
|
-
|
29
|
+
|
29
30
|
public_class_method :new
|
30
31
|
|
31
32
|
# @return [String] UID markup
|
@@ -23,13 +23,13 @@ module AIXM
|
|
23
23
|
# )
|
24
24
|
# vor.timetable = AIXM.timetable or nil
|
25
25
|
# vor.remarks = String or nil
|
26
|
-
# vor.associate_dme
|
27
|
-
# vor.associate_tacan
|
26
|
+
# vor.associate_dme # turns the VOR into a VOR/DME
|
27
|
+
# vor.associate_tacan # turns the VOR into a VORTAC
|
28
28
|
#
|
29
29
|
# @see https://gitlab.com/openflightmaps/ofmx/wikis/Navigational-aid#vor-vor
|
30
30
|
class VOR < NavigationalAid
|
31
31
|
include AIXM::Memoize
|
32
|
-
|
32
|
+
|
33
33
|
public_class_method :new
|
34
34
|
|
35
35
|
TYPES = {
|
@@ -47,12 +47,14 @@ module AIXM
|
|
47
47
|
|
48
48
|
# @!method dme
|
49
49
|
# @return [AIXM::Feature::NavigationalAid::DME, nil] associated DME
|
50
|
+
#
|
50
51
|
# @!method dme=(dme)
|
51
52
|
# @param dme [AIXM::Feature::NavigationalAid::DME, nil]
|
52
53
|
has_one :dme, allow_nil: true
|
53
54
|
|
54
55
|
# @!method tacan
|
55
56
|
# @return [AIXM::Feature::NavigationalAid::TACAN, nil] associated TACAN
|
57
|
+
#
|
56
58
|
# @!method tacan=(tacan)
|
57
59
|
# @param tacan [AIXM::Feature::NavigationalAid::TACAN, nil]
|
58
60
|
has_one :tacan, allow_nil: true
|
@@ -84,16 +86,33 @@ module AIXM
|
|
84
86
|
@north = NORTHS.lookup(value&.to_s&.to_sym, nil) || fail(ArgumentError, "invalid north")
|
85
87
|
end
|
86
88
|
|
87
|
-
#
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
#
|
94
|
-
|
95
|
-
|
96
|
-
|
89
|
+
# @!method associate_dme
|
90
|
+
# Build a DME associated to this VOR (which turns it into a VOR/DME)
|
91
|
+
#
|
92
|
+
# @return [AIXM::Feature::NavigationalAid::DME] associated DME
|
93
|
+
#
|
94
|
+
# @!method dassociate_tacan
|
95
|
+
# Build a TACAN associated to this VOR (which turns it into a VORTAC)
|
96
|
+
#
|
97
|
+
# @return [AIXM::Feature::NavigationalAid::TACAN] associated TACAN
|
98
|
+
%i(dme tacan).each do |secondary|
|
99
|
+
define_method("associate_#{secondary}") do
|
100
|
+
send("#{secondary}=",
|
101
|
+
AIXM.send(secondary,
|
102
|
+
region: region,
|
103
|
+
source: source,
|
104
|
+
organisation: organisation,
|
105
|
+
id: id,
|
106
|
+
name: name,
|
107
|
+
xy: xy,
|
108
|
+
z: z,
|
109
|
+
ghost_f: f
|
110
|
+
).tap do |navigational_aid|
|
111
|
+
navigational_aid.timetable = timetable
|
112
|
+
navigational_aid.remarks = remarks
|
113
|
+
end
|
114
|
+
)
|
115
|
+
end
|
97
116
|
end
|
98
117
|
|
99
118
|
# @return [String] UID markup
|
@@ -72,7 +72,7 @@ module AIXM
|
|
72
72
|
|
73
73
|
# @return [String] fully descriptive combination of {#class} and {#type} key
|
74
74
|
def kind
|
75
|
-
[self.class.name.split('::').last, type_key].compact.join(':')
|
75
|
+
[self.class.name.split('::').last, type_key].compact.join(':'.freeze)
|
76
76
|
end
|
77
77
|
|
78
78
|
private
|
@@ -155,7 +155,7 @@ module AIXM
|
|
155
155
|
end
|
156
156
|
|
157
157
|
def radius=(value)
|
158
|
-
fail(ArgumentError, "invalid radius") unless value.nil? || (value.is_a?(AIXM::D) && value.
|
158
|
+
fail(ArgumentError, "invalid radius") unless value.nil? || (value.is_a?(AIXM::D) && value.dim > 0)
|
159
159
|
@radius = value
|
160
160
|
end
|
161
161
|
|
@@ -178,7 +178,7 @@ module AIXM
|
|
178
178
|
end
|
179
179
|
|
180
180
|
def height=(value)
|
181
|
-
fail(ArgumentError, "invalid height") unless value.nil? || (value.is_a?(AIXM::D) && value.
|
181
|
+
fail(ArgumentError, "invalid height") unless value.nil? || (value.is_a?(AIXM::D) && value.dim > 0)
|
182
182
|
@height = value
|
183
183
|
end
|
184
184
|
|
@@ -267,21 +267,21 @@ module AIXM
|
|
267
267
|
obs.txtDescrMarking(marking_remarks) if marking_remarks
|
268
268
|
obs.codeDatum('WGE')
|
269
269
|
if AIXM.aixm? && obstacle_group.xy_accuracy
|
270
|
-
obs.valGeoAccuracy(obstacle_group.xy_accuracy.
|
270
|
+
obs.valGeoAccuracy(obstacle_group.xy_accuracy.dim.trim)
|
271
271
|
obs.uomGeoAccuracy(obstacle_group.xy_accuracy.unit.upcase.to_s)
|
272
272
|
end
|
273
273
|
obs.valElev(z.alt)
|
274
274
|
if AIXM.aixm? && obstacle_group.z_accuracy
|
275
|
-
obs.valElevAccuracy(obstacle_group.z_accuracy.to_ft.
|
275
|
+
obs.valElevAccuracy(obstacle_group.z_accuracy.to_ft.dim.round)
|
276
276
|
end
|
277
|
-
obs.valHgt(height.to_ft.
|
277
|
+
obs.valHgt(height.to_ft.dim.round) if height
|
278
278
|
obs.uomDistVer('FT')
|
279
279
|
if AIXM.ofmx? && !height_accurate.nil?
|
280
280
|
obs.codeHgtAccuracy(height_accurate ? 'Y' : 'N')
|
281
281
|
end
|
282
282
|
if AIXM.ofmx?
|
283
283
|
if radius
|
284
|
-
obs.valRadius(radius.
|
284
|
+
obs.valRadius(radius.dim.trim)
|
285
285
|
obs.uomRadius(radius.unit.upcase.to_s)
|
286
286
|
end
|
287
287
|
if grouped? && linked?
|
@@ -45,6 +45,7 @@ module AIXM
|
|
45
45
|
|
46
46
|
# @!method obstacles
|
47
47
|
# @return [Array<AIXM::Feature::Obstacle>] obstacles in this obstacle group
|
48
|
+
#
|
48
49
|
# @!method add_obstacle(obstacle, linked_to: nil, link_type: nil)
|
49
50
|
# @param obstacle [AIXM::Feature::Obstacle] obstacle instance
|
50
51
|
# @param linked_to [Symbol, AIXM::Feature::Obstacle, nil] Either:
|
@@ -62,10 +63,13 @@ module AIXM
|
|
62
63
|
|
63
64
|
# @!method source
|
64
65
|
# @return [String] reference to source of the feature data
|
66
|
+
#
|
65
67
|
# @!method name
|
66
68
|
# @return [String] obstacle group name
|
69
|
+
#
|
67
70
|
# @!method xy_accuracy
|
68
71
|
# @return [AIXM::D, nil] margin of error for circular base center point
|
72
|
+
#
|
69
73
|
# @!method z_accuracy
|
70
74
|
# @return [AIXM::D, nil] margin of error for top point
|
71
75
|
%i(source name xy_accuracy z_accuracy).each do |method|
|
@@ -126,11 +130,11 @@ module AIXM
|
|
126
130
|
ogr << to_uid.indent(2)
|
127
131
|
ogr.codeDatum('WGE')
|
128
132
|
if xy_accuracy
|
129
|
-
ogr.valGeoAccuracy(xy_accuracy.
|
133
|
+
ogr.valGeoAccuracy(xy_accuracy.dim.trim)
|
130
134
|
ogr.uomGeoAccuracy(xy_accuracy.unit.upcase.to_s)
|
131
135
|
end
|
132
136
|
if z_accuracy
|
133
|
-
ogr.valElevAccuracy(z_accuracy.to_ft.
|
137
|
+
ogr.valElevAccuracy(z_accuracy.to_ft.dim.round)
|
134
138
|
ogr.uomElevAccuracy('FT')
|
135
139
|
end
|
136
140
|
ogr.txtRmk(remarks) if remarks
|
@@ -39,6 +39,7 @@ module AIXM
|
|
39
39
|
# @return [Array<AIXM::Feature::Airport,
|
40
40
|
# AIXM::Feature::Unit,
|
41
41
|
# AIXM::Feature::NavigationalAid>] aiports, units or navigational aids
|
42
|
+
#
|
42
43
|
# @!method add_member(member)
|
43
44
|
# @param member [AIXM::Feature::Airport,
|
44
45
|
# AIXM::Feature::Unit,
|
data/lib/aixm/feature/unit.rb
CHANGED
@@ -82,6 +82,7 @@ module AIXM
|
|
82
82
|
|
83
83
|
# @!method services
|
84
84
|
# @return [Array<AIXM::Component::Service>] services provided by this unit
|
85
|
+
#
|
85
86
|
# @!method add_service(service)
|
86
87
|
# @param service [AIXM::Component::Service]
|
87
88
|
has_many :services
|
@@ -169,7 +170,7 @@ module AIXM
|
|
169
170
|
private
|
170
171
|
|
171
172
|
def name_with_type
|
172
|
-
[name, TYPES.key(type)].join(' ')
|
173
|
+
[name, TYPES.key(type)].join(' '.freeze)
|
173
174
|
end
|
174
175
|
end
|
175
176
|
|
data/lib/aixm/feature.rb
CHANGED
data/lib/aixm/memoize.rb
CHANGED
@@ -8,6 +8,9 @@ module AIXM
|
|
8
8
|
# independently. On the other hand, when calling the method with a block,
|
9
9
|
# no memoization is performed at all.
|
10
10
|
#
|
11
|
+
# Nested memoization of the same method is allowed and won't reset the
|
12
|
+
# memoization cache.
|
13
|
+
#
|
11
14
|
# @example
|
12
15
|
# class Either
|
13
16
|
# include AIXM::Memoize
|
@@ -53,14 +56,15 @@ module AIXM
|
|
53
56
|
unmemoized_method = :"unmemoized_#{method}"
|
54
57
|
alias_method unmemoized_method, method
|
55
58
|
define_method method do |*args, **kargs, &block|
|
56
|
-
if block || !AIXM::Memoize.cache
|
59
|
+
if block || !AIXM::Memoize.cache.has_key?(method)
|
57
60
|
send(unmemoized_method, *args, **kargs, &block)
|
58
61
|
else
|
62
|
+
cache = AIXM::Memoize.cache[method]
|
59
63
|
id = object_id.hash ^ args.hash ^ kargs.hash
|
60
|
-
if
|
61
|
-
|
64
|
+
if cache.has_key?(id)
|
65
|
+
cache[id]
|
62
66
|
else
|
63
|
-
|
67
|
+
cache[id] = send(unmemoized_method, *args, **kargs)
|
64
68
|
end
|
65
69
|
end
|
66
70
|
end
|
@@ -68,22 +72,34 @@ module AIXM
|
|
68
72
|
end
|
69
73
|
|
70
74
|
class << self
|
75
|
+
attr_reader :cache
|
76
|
+
|
71
77
|
def included(base)
|
72
78
|
base.extend(ClassMethods)
|
73
79
|
@cache = {}
|
74
80
|
end
|
75
81
|
|
76
|
-
def method(method)
|
77
|
-
|
78
|
-
|
82
|
+
def method(method, &)
|
83
|
+
send(:"call_with#{:out if cached?(method)}_cache", method, &)
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def cached?(method)
|
89
|
+
cache.has_key?(method)
|
90
|
+
end
|
91
|
+
|
92
|
+
def call_without_cache(method)
|
79
93
|
yield
|
80
|
-
ensure
|
81
|
-
@method = nil
|
82
94
|
end
|
83
95
|
|
84
|
-
def
|
85
|
-
|
96
|
+
def call_with_cache(method)
|
97
|
+
cache[method] = {}
|
98
|
+
yield
|
99
|
+
ensure
|
100
|
+
cache.delete(method)
|
86
101
|
end
|
102
|
+
|
87
103
|
end
|
88
104
|
end
|
89
105
|
end
|
data/lib/aixm/p.rb
CHANGED
@@ -2,7 +2,7 @@ using AIXM::Refinements
|
|
2
2
|
|
3
3
|
module AIXM
|
4
4
|
|
5
|
-
#
|
5
|
+
# Pressure
|
6
6
|
#
|
7
7
|
# @example
|
8
8
|
# AIXM.d(14, :bar)
|
@@ -39,7 +39,7 @@ module AIXM
|
|
39
39
|
|
40
40
|
# @return [String] human readable representation (e.g. "14 bar")
|
41
41
|
def to_s
|
42
|
-
[pres, unit].join(' ')
|
42
|
+
[pres, unit].join(' '.freeze)
|
43
43
|
end
|
44
44
|
|
45
45
|
def pres=(value)
|
@@ -58,6 +58,7 @@ module AIXM
|
|
58
58
|
# @!method to_psi
|
59
59
|
# @!method to_bar
|
60
60
|
# @!method to_torr
|
61
|
+
#
|
61
62
|
# @return [AIXM::P] convert pressure
|
62
63
|
UNITS.each_key do |target_unit|
|
63
64
|
define_method "to_#{target_unit}" do
|
data/lib/aixm/payload_hash.rb
CHANGED
@@ -44,7 +44,7 @@ module AIXM
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def uuid_for(array)
|
47
|
-
::Digest::MD5.hexdigest(array.flatten.map(&:to_s).join('|')).unpack("a8a4a4a4a12").join(
|
47
|
+
::Digest::MD5.hexdigest(array.flatten.map(&:to_s).join('|'.freeze)).unpack("a8a4a4a4a12").join('-'.freeze)
|
48
48
|
end
|
49
49
|
|
50
50
|
# Insert OFMX-compliant payload hashes as mid attributes into an XML
|
data/lib/aixm/r.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
using AIXM::Refinements
|
2
|
+
|
3
|
+
module AIXM
|
4
|
+
|
5
|
+
# Rectangle shape composed of two lengths
|
6
|
+
#
|
7
|
+
# @examples
|
8
|
+
# AIXM.r(AIXM.d(25, :m), AIXM.d(20, :m)) # rectangle
|
9
|
+
# AIXM.r(AIXM.d(25, :m)) # square
|
10
|
+
class R
|
11
|
+
|
12
|
+
# @return [AIXM::D] rectangle length
|
13
|
+
attr_reader :length
|
14
|
+
|
15
|
+
# @return [AIXM::D] rectangle width
|
16
|
+
attr_reader :width
|
17
|
+
|
18
|
+
def initialize(length, width=nil)
|
19
|
+
self.length, self.width = length, (width || length)
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [String]
|
23
|
+
def inspect
|
24
|
+
%Q(#<#{self.class} #{to_s}>)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [String] human readable representation (e.g. "25.0 m x 20.0 m")
|
28
|
+
def to_s
|
29
|
+
[length, width].join(' x ')
|
30
|
+
end
|
31
|
+
|
32
|
+
%i(length width).each do |dimension|
|
33
|
+
define_method("#{dimension}=") do |value|
|
34
|
+
fail(ArgumentError, "invalid dimension") unless value.is_a? AIXM::D
|
35
|
+
instance_variable_set(:"@#{dimension}", value)
|
36
|
+
@length, @width = @width, @length if @length && @width && @length < @width
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Calculate the surface in square meters
|
41
|
+
#
|
42
|
+
# @return [Float]
|
43
|
+
def surface
|
44
|
+
length.to_m.dim * width.to_m.dim
|
45
|
+
end
|
46
|
+
|
47
|
+
# @see Object#==
|
48
|
+
# @return [Boolean]
|
49
|
+
def ==(other)
|
50
|
+
self.class === other && length == other.length && width == other.width
|
51
|
+
end
|
52
|
+
alias_method :eql?, :==
|
53
|
+
|
54
|
+
# @see Object#hash
|
55
|
+
# @return [Integer]
|
56
|
+
def hash
|
57
|
+
to_s.hash
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|