aixm 1.0.0 → 1.1.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.
- 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
|