aixm 0.3.3 → 0.3.4
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
- data/.ruby-version +1 -1
- data/.travis.yml +1 -2
- data/CHANGELOG.md +20 -0
- data/README.md +7 -2
- data/aixm.gemspec +2 -3
- data/lib/aixm.rb +6 -2
- data/lib/aixm/a.rb +151 -0
- data/lib/aixm/component/frequency.rb +2 -2
- data/lib/aixm/component/geometry.rb +4 -0
- data/lib/aixm/component/geometry/point.rb +0 -4
- data/lib/aixm/component/helipad.rb +8 -22
- data/lib/aixm/component/runway.rb +36 -36
- data/lib/aixm/component/surface.rb +121 -0
- data/lib/aixm/component/timetable.rb +1 -0
- data/lib/aixm/constants.rb +40 -0
- data/lib/aixm/d.rb +5 -0
- data/lib/aixm/document.rb +2 -2
- data/lib/aixm/f.rb +6 -0
- data/lib/aixm/feature/address.rb +100 -0
- data/lib/aixm/feature/airport.rb +26 -7
- data/lib/aixm/feature/airspace.rb +10 -1
- data/lib/aixm/feature/navigational_aid.rb +1 -1
- data/lib/aixm/feature/navigational_aid/designated_point.rb +20 -5
- data/lib/aixm/feature/navigational_aid/dme.rb +2 -2
- data/lib/aixm/{component → feature}/service.rb +67 -16
- data/lib/aixm/feature/unit.rb +40 -6
- data/lib/aixm/refinements.rb +63 -6
- data/lib/aixm/shortcuts.rb +12 -4
- data/lib/aixm/version.rb +1 -1
- data/lib/aixm/xy.rb +6 -1
- data/lib/aixm/z.rb +6 -0
- data/schemas/ofmx/0/OFMX-DataTypes.xsd +5 -2
- data/schemas/ofmx/0/OFMX-Features.xsd +2 -0
- data/spec/factory.rb +32 -10
- data/spec/lib/aixm/a_spec.rb +203 -0
- data/spec/lib/aixm/component/helipad_spec.rb +11 -17
- data/spec/lib/aixm/component/runway_spec.rb +46 -32
- data/spec/lib/aixm/component/surface_spec.rb +88 -0
- data/spec/lib/aixm/d_spec.rb +10 -0
- data/spec/lib/aixm/document_spec.rb +104 -32
- data/spec/lib/aixm/f_spec.rb +10 -0
- data/spec/lib/aixm/feature/address_spec.rb +55 -0
- data/spec/lib/aixm/feature/airport_spec.rb +73 -3
- data/spec/lib/aixm/feature/navigational_aid/designated_point_spec.rb +43 -6
- data/spec/lib/aixm/feature/navigational_aid/dme_spec.rb +2 -2
- data/spec/lib/aixm/feature/navigational_aid/marker_spec.rb +2 -2
- data/spec/lib/aixm/feature/navigational_aid/ndb_spec.rb +2 -2
- data/spec/lib/aixm/feature/navigational_aid/tacan_spec.rb +2 -2
- data/spec/lib/aixm/feature/navigational_aid/vor_spec.rb +6 -6
- data/spec/lib/aixm/{component → feature}/service_spec.rb +12 -14
- data/spec/lib/aixm/feature/unit_spec.rb +7 -4
- data/spec/lib/aixm/refinements_spec.rb +100 -15
- data/spec/lib/aixm/z_spec.rb +10 -0
- metadata +17 -25
- data/lib/aixm/h.rb +0 -87
- data/spec/lib/aixm/h_spec.rb +0 -113
@@ -0,0 +1,121 @@
|
|
1
|
+
using AIXM::Refinements
|
2
|
+
|
3
|
+
module AIXM
|
4
|
+
class Component
|
5
|
+
|
6
|
+
# Surface of a runway, helipad etc
|
7
|
+
#
|
8
|
+
# ===Cheat Sheet in Pseudo Code:
|
9
|
+
# surface = AIXM.surfaceservice(
|
10
|
+
# composition: COMPOSITIONS or nil
|
11
|
+
# preparation: PREPARATIONS or nil
|
12
|
+
# condition: CONDITIONS or nil
|
13
|
+
# )
|
14
|
+
# surface.pcn = String
|
15
|
+
# surface.remarks = String or nil
|
16
|
+
#
|
17
|
+
# ===Constants:
|
18
|
+
# * +AIXM::PCN_RE+ - regular expression to match PCN notations
|
19
|
+
#
|
20
|
+
#
|
21
|
+
# @see https://github.com/openflightmaps/ofmx/wiki/Airport#rwy-runway
|
22
|
+
class Surface
|
23
|
+
COMPOSITIONS = {
|
24
|
+
ASPH: :asphalt,
|
25
|
+
BITUM: :bitumen, # dug up, bound and rolled ground
|
26
|
+
CONC: :concrete,
|
27
|
+
GRADE: :graded_earth, # graded or rolled earth possibly with some grass
|
28
|
+
GRASS: :grass, # lawn
|
29
|
+
GRAVE: :gravel, # small and midsize rounded stones
|
30
|
+
MACADAM: :macadam, # small rounded stones
|
31
|
+
SAND: :sand,
|
32
|
+
WATER: :water,
|
33
|
+
OTHER: :other # specify in remarks
|
34
|
+
}
|
35
|
+
|
36
|
+
PREPARATIONS = {
|
37
|
+
AFSC: :aggregate_friction_seal_coat,
|
38
|
+
GROOVED: :grooved, # cut or plastic grooved
|
39
|
+
NATURAL: :natural, # no treatment
|
40
|
+
OILED: :oiled,
|
41
|
+
PAVED: :paved,
|
42
|
+
PFC: :porous_friction_course,
|
43
|
+
RFSC: :rubberized_friction_seal_coat,
|
44
|
+
ROLLED: :rolled,
|
45
|
+
OTHER: :other
|
46
|
+
}
|
47
|
+
|
48
|
+
CONDITIONS = {
|
49
|
+
GOOD: :good,
|
50
|
+
FAIR: :fair,
|
51
|
+
POOR: :poor,
|
52
|
+
OTHER: :other
|
53
|
+
}
|
54
|
+
|
55
|
+
# @return [Symbol, nil] composition of the surface (see {COMPOSITIONS})
|
56
|
+
attr_reader :composition
|
57
|
+
|
58
|
+
# @return [Symbol, nil] preparation of the surface (see {PREPARATIONS})
|
59
|
+
attr_reader :preparation
|
60
|
+
|
61
|
+
# @return [Symbol, nil] condition of the surface (see {CONDITIONS})
|
62
|
+
attr_reader :condition
|
63
|
+
|
64
|
+
# @return [String, nil] free text remarks
|
65
|
+
attr_reader :remarks
|
66
|
+
|
67
|
+
def initialize
|
68
|
+
@pcn = {}
|
69
|
+
end
|
70
|
+
|
71
|
+
# @return [String]
|
72
|
+
def inspect
|
73
|
+
%Q(#<#{self.class} composition=#{composition.inspect} preparation=#{preparation.inspect} condition=#{condition.inspect} pcn=#{pcn.inspect}>)
|
74
|
+
end
|
75
|
+
|
76
|
+
def composition=(value)
|
77
|
+
@composition = value.nil? ? nil : COMPOSITIONS.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid composition")
|
78
|
+
end
|
79
|
+
|
80
|
+
def preparation=(value)
|
81
|
+
@preparation = value.nil? ? nil : PREPARATIONS.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid preparation")
|
82
|
+
end
|
83
|
+
|
84
|
+
def condition=(value)
|
85
|
+
@condition = value.nil? ? nil : CONDITIONS.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid condition")
|
86
|
+
end
|
87
|
+
|
88
|
+
# @return [String, nil] pavement classification number (e.g. "59/F/A/W/T")
|
89
|
+
def pcn
|
90
|
+
@pcn.none? ? nil : @pcn.values.join("/")
|
91
|
+
end
|
92
|
+
|
93
|
+
def pcn=(value)
|
94
|
+
return @pcn = {} if value.nil?
|
95
|
+
fail(ArgumentError, "invalid PCN") unless match = value.to_s.upcase.match(PCN_RE)
|
96
|
+
@pcn = match.named_captures.reject{ |k| k == 'pcn' }
|
97
|
+
end
|
98
|
+
|
99
|
+
def remarks=(value)
|
100
|
+
@remarks = value&.to_s
|
101
|
+
end
|
102
|
+
|
103
|
+
# @return [String] AIXM or OFMX markup
|
104
|
+
def to_xml
|
105
|
+
builder = Builder::XmlMarkup.new(indent: true)
|
106
|
+
builder.codeComposition(COMPOSITIONS.key(composition).to_s) if composition
|
107
|
+
builder.codePreparation(PREPARATIONS.key(preparation).to_s) if preparation
|
108
|
+
builder.codeCondSfc(CONDITIONS.key(condition).to_s) if condition
|
109
|
+
if pcn
|
110
|
+
builder.valPcnClass(@pcn['capacity'])
|
111
|
+
builder.codePcnPavementType(@pcn['type'])
|
112
|
+
builder.codePcnPavementSubgrade(@pcn['subgrade'])
|
113
|
+
builder.codePcnMaxTirePressure(@pcn['tire_pressure'])
|
114
|
+
builder.codePcnEvalMethod(@pcn['evaluation_method'])
|
115
|
+
end
|
116
|
+
builder.txtPcnNote(@remarks) if remarks
|
117
|
+
builder.target!
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module AIXM
|
2
|
+
|
3
|
+
# Characters recognized as symbols for "minute" in DMS notations
|
4
|
+
MIN = %Q('\u2018\u2019\u00b4).freeze
|
5
|
+
|
6
|
+
# Characters recognized as symbols for "second" in DMS notations
|
7
|
+
SEC = %Q("\u201c\u201d\u201f).freeze
|
8
|
+
|
9
|
+
# Pattern matching geographical coordinates in various DMS notations
|
10
|
+
DMS_RE = %r(
|
11
|
+
(?<dms>
|
12
|
+
(?<sgn>-)?
|
13
|
+
(?<deg>\d{1,3})[° ]{1,2}
|
14
|
+
(?<min>\d{2})[#{MIN}#{SEC} ]{1,2}
|
15
|
+
(?<sec>\d{2}(?:[\.,]\d{0,2})?)[#{SEC}#{MIN} ]{0,2}
|
16
|
+
(?<hem_ne>[NE])?(?<hem_sw>[SW])?
|
17
|
+
|
|
18
|
+
(?<sgn>-)?
|
19
|
+
(?<deg>\d{1,3})
|
20
|
+
(?<min>\d{2})
|
21
|
+
(?<sec>\d{2}(?:[\.,]\d{0,2})?)
|
22
|
+
(?:(?<hem_ne>[NE])|(?<hem_sw>[SW]))
|
23
|
+
)
|
24
|
+
)xi.freeze
|
25
|
+
|
26
|
+
# Pattern matching PCN surface strength notations
|
27
|
+
PCN_RE = %r(
|
28
|
+
(?<pcn>
|
29
|
+
(?<capacity>\d+)\W+
|
30
|
+
(?<type>[RF])\W+
|
31
|
+
(?<subgrade>[A-D])\W+
|
32
|
+
(?<tire_pressure>[W-Z])\W+
|
33
|
+
(?<evaluation_method>[TU])
|
34
|
+
)
|
35
|
+
)x.freeze
|
36
|
+
|
37
|
+
# Pattern matching timetable working hour codes
|
38
|
+
H_RE = /H(?:24|J|N|X|O)/.freeze
|
39
|
+
|
40
|
+
end
|
data/lib/aixm/d.rb
CHANGED
@@ -8,6 +8,7 @@ module AIXM
|
|
8
8
|
# AIXM.d(123, :m)
|
9
9
|
class D
|
10
10
|
include Comparable
|
11
|
+
extend Forwardable
|
11
12
|
|
12
13
|
UNITS = {
|
13
14
|
ft: { km: 0.0003048, m: 0.3048, nm: 0.000164578833554 },
|
@@ -16,6 +17,10 @@ module AIXM
|
|
16
17
|
nm: { ft: 6076.11548554, km: 1.852, m: 1852 }
|
17
18
|
}.freeze
|
18
19
|
|
20
|
+
# @!method zero?
|
21
|
+
# @return [Boolean] whether length is zero
|
22
|
+
def_delegator :@dist, :zero?
|
23
|
+
|
19
24
|
# @return [Float] distance
|
20
25
|
attr_reader :dist
|
21
26
|
|
data/lib/aixm/document.rb
CHANGED
@@ -15,7 +15,7 @@ module AIXM
|
|
15
15
|
#
|
16
16
|
# @see https://github.com/openflightmaps/ofmx/wiki/Snapshot
|
17
17
|
class Document
|
18
|
-
|
18
|
+
NAMESPACE_RE = /\A[a-f\d]{8}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{4}-[a-f\d]{12}\z/.freeze
|
19
19
|
|
20
20
|
# @return [String] OFMX region all features in this document belong to
|
21
21
|
attr_reader :region
|
@@ -48,7 +48,7 @@ module AIXM
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def namespace=(value)
|
51
|
-
fail(ArgumentError, "invalid namespace") unless value.nil? || value.match?(
|
51
|
+
fail(ArgumentError, "invalid namespace") unless value.nil? || value.match?(NAMESPACE_RE)
|
52
52
|
@namespace = value || SecureRandom.uuid
|
53
53
|
end
|
54
54
|
|
data/lib/aixm/f.rb
CHANGED
@@ -7,8 +7,14 @@ module AIXM
|
|
7
7
|
# @example
|
8
8
|
# AIXM.f(123.35, :mhz)
|
9
9
|
class F
|
10
|
+
extend Forwardable
|
11
|
+
|
10
12
|
UNITS = %i(ghz mhz khz).freeze
|
11
13
|
|
14
|
+
# @!method zero?
|
15
|
+
# @return [Boolean] whether frequency is zero
|
16
|
+
def_delegator :@freq, :zero?
|
17
|
+
|
12
18
|
# @return [Float] frequency
|
13
19
|
attr_reader :freq
|
14
20
|
|
@@ -0,0 +1,100 @@
|
|
1
|
+
using AIXM::Refinements
|
2
|
+
|
3
|
+
module AIXM
|
4
|
+
class Feature
|
5
|
+
|
6
|
+
# Address or similar means to contact an entity.
|
7
|
+
#
|
8
|
+
# ===Cheat Sheet in Pseudo Code:
|
9
|
+
# address = AIXM.address(
|
10
|
+
# source: String or nil
|
11
|
+
# type: TYPES
|
12
|
+
# address: String
|
13
|
+
# )
|
14
|
+
# service.remarks = String or nil
|
15
|
+
#
|
16
|
+
# @see https://github.com/openflightmaps/ofmx/wiki/Airport#aha-airport-address
|
17
|
+
class Address < Feature
|
18
|
+
public_class_method :new
|
19
|
+
|
20
|
+
TYPES = {
|
21
|
+
POST: :postal_address,
|
22
|
+
PHONE: :phone,
|
23
|
+
'PHONE-MET': :weather_phone,
|
24
|
+
FAX: :fax,
|
25
|
+
TLX: :telex,
|
26
|
+
SITA: :sita,
|
27
|
+
AFS: :aeronautical_fixed_service_address,
|
28
|
+
EMAIL: :email,
|
29
|
+
URL: :url,
|
30
|
+
'URL-CAM': :webcam,
|
31
|
+
'URL-MET': :weather_url,
|
32
|
+
RADIO: :radio_frequency,
|
33
|
+
OTHER: :other # specify in remarks
|
34
|
+
}
|
35
|
+
|
36
|
+
# @return [AIXM::Feature] addressable feature
|
37
|
+
attr_reader :addressable
|
38
|
+
|
39
|
+
# @return [Symbol] type of address (see {TYPES})
|
40
|
+
attr_reader :type
|
41
|
+
|
42
|
+
# @return [String] postal address, phone number, radio frequency etc
|
43
|
+
attr_reader :address
|
44
|
+
|
45
|
+
# @return [String, nil] free text remarks
|
46
|
+
attr_reader :remarks
|
47
|
+
|
48
|
+
def initialize(source: nil, type:, address:)
|
49
|
+
super(source: source)
|
50
|
+
self.type, self.address = type, address
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [String]
|
54
|
+
def inspect
|
55
|
+
%Q(#<#{self.class} type=#{type.inspect}>)
|
56
|
+
end
|
57
|
+
|
58
|
+
def addressable=(value)
|
59
|
+
fail(ArgumentError, "invalid addressable") unless value.is_a? AIXM::Feature
|
60
|
+
@addressable = value
|
61
|
+
end
|
62
|
+
private :addressable=
|
63
|
+
|
64
|
+
def type=(value)
|
65
|
+
@type = TYPES.lookup(value&.to_s&.to_sym, nil) || fail(ArgumentError, "invalid type")
|
66
|
+
end
|
67
|
+
|
68
|
+
def address=(value)
|
69
|
+
fail(ArgumentError, "invalid address") unless value.is_a? String
|
70
|
+
@address = value&.to_s
|
71
|
+
end
|
72
|
+
|
73
|
+
def remarks=(value)
|
74
|
+
@remarks = value&.to_s
|
75
|
+
end
|
76
|
+
|
77
|
+
# @return [String] UID markup
|
78
|
+
def to_uid(as:, sequence:)
|
79
|
+
builder = Builder::XmlMarkup.new(indent: 2)
|
80
|
+
builder.tag!(as) do |tag|
|
81
|
+
tag << addressable.to_uid.indent(2) if addressable
|
82
|
+
tag.codeType(TYPES.key(type).to_s.then { |t| AIXM.aixm? ? t.sub(/-\w+$/, '') : t })
|
83
|
+
tag.noSeq(sequence)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# @return [String] AIXM or OFMX markup
|
88
|
+
def to_xml(as:, sequence:)
|
89
|
+
builder = Builder::XmlMarkup.new(indent: 2)
|
90
|
+
builder.comment! ["Address: #{TYPES.key(type)}", addressable&.id].compact.join(' for ')
|
91
|
+
builder.tag!(as, { source: (source if AIXM.ofmx?) }.compact) do |tag|
|
92
|
+
tag << to_uid(as: :"#{as}Uid", sequence: sequence).indent(2)
|
93
|
+
tag.txtAddress(address)
|
94
|
+
tag.txtRmk(remarks) if remarks
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
data/lib/aixm/feature/airport.rb
CHANGED
@@ -24,12 +24,13 @@ module AIXM
|
|
24
24
|
# airport.add_runway(AIXM.runway)
|
25
25
|
# airport.add_helipad(AIXM.helipad)
|
26
26
|
# airport.add_usage_limitation(UsageLimitation::TYPES)
|
27
|
+
# airport.add_address(AIXM.address)
|
27
28
|
#
|
28
29
|
# @see https://github.com/openflightmaps/ofmx/wiki/Airport#ahp-airport
|
29
30
|
class Airport < Feature
|
30
31
|
public_class_method :new
|
31
32
|
|
32
|
-
|
33
|
+
ID_RE = /^([A-Z]{3,4}|[A-Z]{2}[A-Z\d]{4,})$/.freeze
|
33
34
|
|
34
35
|
TYPES = {
|
35
36
|
AD: :aerodrome,
|
@@ -90,10 +91,13 @@ module AIXM
|
|
90
91
|
# @return [Array<AIXM::Feature::Airport::UsageLimitation>] usage limitations
|
91
92
|
attr_accessor :usage_limitations
|
92
93
|
|
94
|
+
# @return [Array<AIXM::Feature::Address>] postal address, url, A/A or A/G frequency etc
|
95
|
+
attr_reader :addresses
|
96
|
+
|
93
97
|
def initialize(source: nil, organisation:, id:, name:, xy:)
|
94
98
|
super(source: source)
|
95
99
|
self.organisation, self.id, self.name, self.xy = organisation, id, name, xy
|
96
|
-
@runways, @helipads, @usage_limitations = [], [], []
|
100
|
+
@runways, @helipads, @usage_limitations, @addresses = [], [], [], []
|
97
101
|
end
|
98
102
|
|
99
103
|
# @return [String]
|
@@ -107,7 +111,7 @@ module AIXM
|
|
107
111
|
end
|
108
112
|
|
109
113
|
def id=(value)
|
110
|
-
fail(ArgumentError, "invalid id `#{id}'") unless value&.upcase&.match?
|
114
|
+
fail(ArgumentError, "invalid id `#{id}'") unless value&.upcase&.match? ID_RE
|
111
115
|
@id = value.upcase
|
112
116
|
end
|
113
117
|
|
@@ -155,7 +159,7 @@ module AIXM
|
|
155
159
|
def declination=(value)
|
156
160
|
return @declination = value if value.nil?
|
157
161
|
fail(ArgumentError, "invalid declination") unless value.is_a?(Numeric) && (-180..180).include?(value)
|
158
|
-
@declination = value.to_f
|
162
|
+
@declination = value.to_f + 0 # adding zero prevents -0.0
|
159
163
|
end
|
160
164
|
|
161
165
|
def transition_z=(value)
|
@@ -229,11 +233,22 @@ module AIXM
|
|
229
233
|
self
|
230
234
|
end
|
231
235
|
|
236
|
+
# Add an address (postal address, url, A/A or A/G frequency etc) to the airport.
|
237
|
+
#
|
238
|
+
# @params address [AIXM::Feature::Address] address instance
|
239
|
+
# @return [self]
|
240
|
+
def add_address(address)
|
241
|
+
fail(ArgumentError, "invalid address") unless address.is_a? AIXM::Feature::Address
|
242
|
+
address.send(:addressable=, self)
|
243
|
+
@addresses << address
|
244
|
+
self
|
245
|
+
end
|
246
|
+
|
232
247
|
# @return [String] UID markup
|
233
|
-
def to_uid
|
248
|
+
def to_uid(as: :AhpUid)
|
234
249
|
builder = Builder::XmlMarkup.new(indent: 2)
|
235
|
-
builder.
|
236
|
-
|
250
|
+
builder.tag!(as) do |tag|
|
251
|
+
tag.codeId(id)
|
237
252
|
end
|
238
253
|
end
|
239
254
|
|
@@ -280,6 +295,10 @@ module AIXM
|
|
280
295
|
end
|
281
296
|
end
|
282
297
|
end
|
298
|
+
addresses.each.with_object({}) do |address, sequences|
|
299
|
+
sequences[address.type] = (sequences[address.type] || 0) + 1
|
300
|
+
builder << address.to_xml(as: :Aha, sequence: sequences[address.type])
|
301
|
+
end
|
283
302
|
builder.target!
|
284
303
|
end
|
285
304
|
|
@@ -16,6 +16,13 @@ module AIXM
|
|
16
16
|
# airspace.geometry << AIXM.point or AIXM.arc or AIXM.border or AIXM.circle
|
17
17
|
# airspace.layers << AIXM.layer
|
18
18
|
#
|
19
|
+
# Some regions define additional airspace types. In LF (France) for
|
20
|
+
# intance, the types RMZ (radio mandatory zone) and TMZ (transponder
|
21
|
+
# mandatory zone) exist. Such airspaces are usually specified together
|
22
|
+
# with a generic type such as +:regulated_airspace+:
|
23
|
+
#
|
24
|
+
# airspace= AIXM.airspace(type: :regulated_airspace, local_type: "RMZ")
|
25
|
+
#
|
19
26
|
# @see https://github.com/openflightmaps/ofmx/wiki/Airspace#ase-airspace
|
20
27
|
class Airspace < Feature
|
21
28
|
public_class_method :new
|
@@ -71,7 +78,9 @@ module AIXM
|
|
71
78
|
# @return [Symbol] type of airspace (see {TYPES})
|
72
79
|
attr_reader :type
|
73
80
|
|
74
|
-
#
|
81
|
+
# Some regions define additional types. They are usually specified with
|
82
|
+
#
|
83
|
+
# @return [String, nil] local type (e.g. "RMZ" or "TMZ")
|
75
84
|
attr_reader :local_type
|
76
85
|
|
77
86
|
# @return [String, nil] full name (e.g. "LF P 81 CHERBOURG")
|
@@ -15,6 +15,7 @@ module AIXM
|
|
15
15
|
# xy: AIXM.xy
|
16
16
|
# type: TYPES
|
17
17
|
# )
|
18
|
+
# designated_point.airport = AIXM.airport or nil
|
18
19
|
# designated_point.remarks = String or nil
|
19
20
|
#
|
20
21
|
# @see https://github.com/openflightmaps/ofmx/wiki/Navigational-aid#dpn-designated-point
|
@@ -24,15 +25,23 @@ module AIXM
|
|
24
25
|
private :organisation
|
25
26
|
|
26
27
|
TYPES = {
|
27
|
-
ICAO: :icao,
|
28
|
-
ADHP: :adhp,
|
29
|
-
COORD: :coordinates,
|
30
|
-
|
28
|
+
ICAO: :icao, # five-letter ICAO id
|
29
|
+
ADHP: :adhp, # airport related id
|
30
|
+
COORD: :coordinates, # derived from geographical coordinates
|
31
|
+
'VFR-RP': :vfr_reporting_point, # usually one or two letter id
|
32
|
+
'VFR-MRP': :vfr_mandatory_reporting_point, # usually one or two letter id
|
33
|
+
'VFR-ENR': :vfr_en_route_point,
|
34
|
+
'VFR-GLD': :vfr_glider_point,
|
35
|
+
OTHER: :other # specify in remarks
|
31
36
|
}.freeze
|
32
37
|
|
33
38
|
# @return [Symbol] type of designated point
|
34
39
|
attr_reader :type
|
35
40
|
|
41
|
+
# @return [AIXM::Feature::Airport] airport this designated point is
|
42
|
+
# associated with
|
43
|
+
attr_reader :airport
|
44
|
+
|
36
45
|
def initialize(type:, **arguments)
|
37
46
|
super(organisation: false, z: nil, **arguments)
|
38
47
|
self.type = type
|
@@ -42,6 +51,11 @@ module AIXM
|
|
42
51
|
@type = TYPES.lookup(value&.to_s&.to_sym, nil) || fail(ArgumentError, "invalid type")
|
43
52
|
end
|
44
53
|
|
54
|
+
def airport=(value)
|
55
|
+
fail(ArgumentError, "invalid airport") unless value.nil? || value.is_a?(AIXM::Feature::Airport)
|
56
|
+
@airport = value
|
57
|
+
end
|
58
|
+
|
45
59
|
# @return [String] UID markup
|
46
60
|
def to_uid
|
47
61
|
builder = Builder::XmlMarkup.new(indent: 2)
|
@@ -57,8 +71,9 @@ module AIXM
|
|
57
71
|
builder = to_builder
|
58
72
|
builder.Dpn({ source: (source if AIXM.ofmx?) }.compact) do |dpn|
|
59
73
|
dpn << to_uid.indent(2)
|
74
|
+
dpn << airport.to_uid(as: :AhpUidAssoc).indent(2) if airport
|
60
75
|
dpn.codeDatum('WGE')
|
61
|
-
dpn.codeType(type_key.to_s)
|
76
|
+
dpn.codeType(AIXM.aixm? && type_key =~ /^VFR/ ? 'OTHER' : type_key.to_s)
|
62
77
|
dpn.txtName(name) if name
|
63
78
|
dpn.txtRmk(remarks) if remarks
|
64
79
|
dpn.target!
|