aixm 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +96 -72
  4. data/README.md +0 -1
  5. data/lib/aixm/component/geometry.rb +8 -2
  6. data/lib/aixm/component/layer.rb +83 -2
  7. data/lib/aixm/document.rb +11 -2
  8. data/lib/aixm/errors.rb +14 -2
  9. data/lib/aixm/feature.rb +2 -14
  10. data/lib/aixm/feature/airport.rb +19 -18
  11. data/lib/aixm/feature/airspace.rb +19 -21
  12. data/lib/aixm/feature/navigational_aid.rb +2 -2
  13. data/lib/aixm/feature/navigational_aid/designated_point.rb +1 -2
  14. data/lib/aixm/feature/navigational_aid/dme.rb +25 -4
  15. data/lib/aixm/feature/navigational_aid/marker.rb +1 -2
  16. data/lib/aixm/feature/navigational_aid/ndb.rb +1 -2
  17. data/lib/aixm/feature/navigational_aid/tacan.rb +5 -2
  18. data/lib/aixm/feature/navigational_aid/vor.rb +3 -4
  19. data/lib/aixm/feature/organisation.rb +3 -4
  20. data/lib/aixm/feature/unit.rb +3 -4
  21. data/lib/aixm/version.rb +1 -1
  22. data/schemas/ofmx/0/OFMX-CSV-Obstacle.json +209 -0
  23. data/schemas/ofmx/0/OFMX-CSV.json +12 -0
  24. data/schemas/ofmx/0/OFMX-DataTypes.xsd +64 -5
  25. data/schemas/ofmx/0/OFMX-Features.xsd +73 -23
  26. data/schemas/ofmx/0/OFMX-Snapshot.xsd +7 -2
  27. data/spec/factory.rb +8 -18
  28. data/spec/lib/aixm/component/geometry_spec.rb +27 -4
  29. data/spec/lib/aixm/component/helipad_spec.rb +2 -2
  30. data/spec/lib/aixm/component/layer_spec.rb +27 -0
  31. data/spec/lib/aixm/component/runway_spec.rb +13 -13
  32. data/spec/lib/aixm/document_spec.rb +56 -42
  33. data/spec/lib/aixm/feature/airport_spec.rb +15 -15
  34. data/spec/lib/aixm/feature/airspace_spec.rb +38 -30
  35. data/spec/lib/aixm/feature/navigational_aid/designated_point_spec.rb +2 -2
  36. data/spec/lib/aixm/feature/navigational_aid/dme_spec.rb +24 -7
  37. data/spec/lib/aixm/feature/navigational_aid/marker_spec.rb +4 -4
  38. data/spec/lib/aixm/feature/navigational_aid/ndb_spec.rb +4 -4
  39. data/spec/lib/aixm/feature/navigational_aid/tacan_spec.rb +24 -7
  40. data/spec/lib/aixm/feature/navigational_aid/vor_spec.rb +14 -14
  41. data/spec/lib/aixm/feature/organisation_spec.rb +2 -2
  42. data/spec/lib/aixm/feature/unit_spec.rb +11 -11
  43. data/spec/lib/aixm/feature_spec.rb +0 -20
  44. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c0f5f953610761dad1816bb0a390155538205afc41fc53d677f9d433a53de5f6
4
- data.tar.gz: ba6b9edea4dc9ffe27239021f28fb3b2cb816bba568286f0108bf070a7108a73
3
+ metadata.gz: da3e3c10902d2c8b47bea41e1056a5447890e1ebeb9d7fb651115cc894f10067
4
+ data.tar.gz: dc2edb38a94804aa7c2c89d2cfcad6872a909598e77ac266fafebf2c39f7deb0
5
5
  SHA512:
6
- metadata.gz: b0947e0e79962e86e21f96833d47944c012fd1be4fa28a2fbf1aa3d82e2549195bafdcb32d9b3e6fd65f8f63ede53000d7218c6afaa5393549768d1ad0d6b569
7
- data.tar.gz: 4358cb754979f06efd3c62d0288a41db984573d6de47f021c585ab056f801c71de480c1258969eeed33db287cc13137355c016f7e911c91e555a499067d9f15c
6
+ metadata.gz: 70a1af692e7141c60c49b3c2426be8037f030acc7808a3ec12029bc8df5bc62681396eb3b8e42add5aff92c10d010156a4cc920f8febf0b70a576a1fb5bd7ac2
7
+ data.tar.gz: c5dc5a92ebef4b7dea61928c794dd2d38c64c9d6a83fc305cb6b6105dff3adb7cb34b4c5eccb95501a14dbb89317c311924c5928a84fa333c165112cda63f820
@@ -1 +1 @@
1
- ruby-2.5.1
1
+ ruby-2.5.3
@@ -1,101 +1,125 @@
1
+ ## 0.3.1
2
+
3
+ #### Additions
4
+ * `AIXM::Error` base error which reveals the `subject`
5
+ * Consider single point geometries to be closed
6
+ * Calculate `DME#ghost_f` from `DME#channel`
7
+ * `Layer#location_indicator` and `Layer#activity`
8
+
9
+ #### Breaking Changes
10
+ * Renamed `Airport#code` to `Airport#id`
11
+ * Renamed `Airspace#short_name` to `Airspace#local_type`
12
+ * Moved `region` attribute from features to Document
13
+
14
+ #### Changes
15
+ * Be more permissive on `Airport#id` in order to accomodate generated codes
16
+ built by concatting the `region` and `Airport#gps`.
17
+
1
18
  ## 0.3.0
2
19
 
3
- * Breaking additions:
4
- * Global configuration with `AIXM.config`
5
- * Breaking changes:
6
- * Switch from "AIXM with OFM extensions" to OFMX
7
- * `to_aixm` renamed to `to_xml` again
8
- * Removed signature `to_xml(extension)` in favor of `AIXM.schema`
9
- * Removed `Array#to_digest`
10
- * Removed `Document#complete?`
11
- * Renamed Schedule to Timetable
12
- * Timetable and remarks moved from Airspace to to Layer (formerly known as
13
- class layer)
14
- * Additions
15
- * Organization and Unit features
16
- * Airport feature
17
- * Refinement `Float#to_rad`
18
- * Distance calculation with `AIXM::XY#distance`
19
- * `Schedule#remarks`
20
+ #### Breaking Additions
21
+ * Global configuration with `AIXM.config`
22
+
23
+ #### Breaking Changes
24
+ * Switch from "AIXM with OFM extensions" to OFMX
25
+ * `to_aixm` renamed to `to_xml` again
26
+ * Removed signature `to_xml(extension)` in favor of `AIXM.schema`
27
+ * Removed `Array#to_digest`
28
+ * Removed `Document#complete?`
29
+ * Renamed Schedule to Timetable
30
+ * Timetable and remarks moved from Airspace to to Layer (formerly known as class layer)
31
+
32
+ #### Additions
33
+ * Organization and Unit features
34
+ * Airport feature
35
+ * Refinement `Float#to_rad`
36
+ * Distance calculation with `AIXM::XY#distance`
37
+ * `Schedule#remarks`
20
38
 
21
39
  ## 0.2.3
22
40
 
23
- * Breaking changes:
24
- * VOR types renamed from :vor to :conventional and :doppler_vor to :doppler
25
- * NBR types added
26
- * Marker types added
27
- * Changes:
28
- * "mid" attributes on all navigational aid features
41
+ #### Breaking Changes
42
+ * VOR types renamed from `:vor` to `:conventional` and `:doppler_vor` to `:doppler`
43
+ * NBR types added
44
+ * Marker types added
45
+
46
+ #### Changes
47
+ * `mid` attributes on all navigational aid features
29
48
 
30
49
  ## 0.2.2
31
50
 
32
- * Changes:
33
- * Bad error classes fixed
34
- * Allow navigational aids without name
51
+ #### Changes
52
+ * Bad error classes fixed
53
+ * Allow navigational aids without name
35
54
 
36
55
  ## 0.2.1
37
56
 
38
- * Breaking changes:
39
- * DVOR and VORDME confusion fixed
40
- * VOR can be associated with DME (-> VOR/DME) or TACAN (-> VORTAC) now
41
- * `to_xml` renamed to `to_aixm` everywhere
42
- * Removed :other from all value lists
43
- * Changes:
44
- * Schedule added to navigational aids
57
+ #### Breaking Changes
58
+ * DVOR and VORDME confusion fixed
59
+ * VOR can be associated with DME (-> VOR/DME) or TACAN (-> VORTAC) now
60
+ * `to_xml` renamed to `to_aixm` everywhere
61
+ * Removed `:other` from all value lists
62
+
63
+ #### Changes
64
+ * Schedule added to navigational aids
45
65
 
46
66
  ## 0.2.0
47
67
 
48
- * Breaking changes:
49
- * Symbols such as :qnh, :ofm or :mhz are downcased now
50
- * Additions:
51
- * Frequency
52
- * Navigational aids features
53
- * `AIXM::Z#qfe?` and friends
68
+ #### Breaking Changes
69
+ * Symbols such as `:qnh`, `:ofm` or `:mhz` are downcased now
70
+
71
+ #### Additions
72
+ * Frequency
73
+ * Navigational aids features
74
+ * `AIXM::Z#qfe?` and friends
54
75
 
55
76
  ## 0.1.4
56
77
 
57
- * Breaking changes:
58
- * `AIXM.z(alt: 123, code: :QNE)` is now `AIXM.z(123, :QNE)`
78
+ #### Breaking Changes
79
+ * `AIXM.z(alt: 123, code: :QNE)` is now `AIXM.z(123, :QNE)`
59
80
 
60
81
  ## 0.1.3
61
82
 
62
- * Breaking changes:
63
- * Re-organization of classes in features and components
64
- * Additions:
65
- * Shortcut initializers e.g. `AIXM.airspace(...)`
83
+ #### Breaking Changes
84
+ * Re-organization of classes in features and components
85
+
86
+ #### Additions
87
+ * Shortcut initializers e.g. `AIXM.airspace(...)`
66
88
 
67
89
  ## 0.1.2
68
90
 
69
- * Breaking additions:
70
- * Class layers
71
- * Breaking changes:
72
- * Use `document.features << (feature)` instead of `document << (feature)`
91
+ #### Breaking Additions
92
+ * Class layers
93
+
94
+ #### Breaking Changes
95
+ * Use `document.features << (feature)` instead of `document << (feature)`
73
96
 
74
97
  ## 0.1.1
75
98
 
76
- * Additions:
77
- * Schedule (all but `TIMSH`)
78
- * Refinement `Float#to_km` and `String#uptrans`
79
- * Shortcut constants `AIXM::UNLIMITED` and `AIXM::H24`
80
- * `Airspace#short_name`
81
- * Changes:
82
- * `Document#created_at` and `#effective_at` accept Time, Date, String or *nil*
83
- * Separate `AIXM::Document#valid?` from `#complete?`
84
- * Write coordinates in DD if extension `:OFM` is set
85
- * `Array#to_digest` returns Integer which fits in signed 32bit
99
+ #### Additions
100
+ * Schedule (all but `TIMSH`)
101
+ * Refinement `Float#to_km` and `String#uptrans`
102
+ * Shortcut constants `AIXM::UNLIMITED` and `AIXM::H24`
103
+ * `Airspace#short_name`
104
+
105
+ #### Changes
106
+ * `Document#created_at` and `#effective_at` accept Time, Date, String or *nil*
107
+ * Separate `AIXM::Document#valid?` from `#complete?`
108
+ * Write coordinates in DD if extension `:OFM` is set
109
+ * `Array#to_digest` returns Integer which fits in signed 32bit
86
110
 
87
111
  ## 0.1.0
88
112
 
89
- * Initial implementation to import D/R/P zones to OFM:
90
- * XY Coordinate
91
- * Z Altitude
92
- * AIXM-Snapshot 4.5 Document
93
- * Airspace feature
94
- * Vertical Limits
95
- * Geometry
96
- * Point
97
- * Arc
98
- * Border
99
- * Circle
100
- * Shortcut constant `AIXM::GROUND`
101
- * Refinements
113
+ #### Initial Implementation
114
+ * XY Coordinate
115
+ * Z Altitude
116
+ * AIXM-Snapshot 4.5 Document
117
+ * Airspace feature
118
+ * Vertical Limits
119
+ * Geometry
120
+ * Point
121
+ * Arc
122
+ * Border
123
+ * Circle
124
+ * Shortcut constant `AIXM::GROUND`
125
+ * Refinements
data/README.md CHANGED
@@ -50,7 +50,6 @@ The following configuration options are available for setting and getting:
50
50
 
51
51
  ```ruby
52
52
  AIXM.config.schema # either :aixm (default) or :ofmx
53
- AIXM.config.region # fallback region
54
53
  AIXM.config.ignored_errors # ignore XML schema errors which match this regex
55
54
  ```
56
55
 
@@ -8,6 +8,7 @@ module AIXM
8
8
  # has to be a point with the same coordinates as the first).
9
9
  #
10
10
  # For a geometry to be valid, it must be comprised of either:
11
+ # * exactly one point
11
12
  # * exactly one circle
12
13
  # * at least three points, arcs or borders (the last of which a point with
13
14
  # identical coordinates as the first)
@@ -53,17 +54,22 @@ module AIXM
53
54
 
54
55
  # @return [Boolean] whether the geometry is closed
55
56
  def closed?
56
- circle? || polygon?
57
+ point? || circle? || polygon?
57
58
  end
58
59
 
59
60
  # @return [String] AIXM or OFMX markup
60
61
  def to_xml
61
- fail(GeometryError, "geometry is not closed") unless closed?
62
+ fail(GeometryError.new("geometry is not closed", self)) unless closed?
62
63
  @result_array.map { |h| h.to_xml }.join
63
64
  end
64
65
 
65
66
  private
66
67
 
68
+ def point?
69
+ @result_array.size == 1 &&
70
+ @result_array.first.is_a?(AIXM::Component::Geometry::Point)
71
+ end
72
+
67
73
  def circle?
68
74
  @result_array.size == 1 &&
69
75
  @result_array.first.is_a?(AIXM::Component::Geometry::Circle)
@@ -9,8 +9,10 @@ module AIXM
9
9
  # ===Cheat Sheet in Pseudo Code:
10
10
  # layer = AIXM.layer(
11
11
  # class: String or nil
12
+ # location_indicator: String or nil
12
13
  # vertical_limits: AIXM.vertical_limits
13
14
  # )
15
+ # layer.activity = String or nil
14
16
  # layer.timetable = AIXM.timetable or nil
15
17
  # layer.selective = true or false (default)
16
18
  # layer.remarks = String or nil
@@ -19,18 +21,86 @@ module AIXM
19
21
  class Layer
20
22
  CLASSES = (:A..:G).freeze
21
23
 
24
+ ACTIVITIES = {
25
+ ACCIDENT: :accident_investigation,
26
+ ACROBAT: :acrobatics,
27
+ AIRGUN: :aerial_gunnery,
28
+ AIRSHOW: :air_show,
29
+ ANTIHAIL: :anti_hail_rocket,
30
+ ARTILERY: :artillary_firing,
31
+ ASCENT: :probe,
32
+ ATS: :air_traffic_services,
33
+ BALLOON: :balloon,
34
+ BIRD: :bird_hazard,
35
+ 'BIRD-MGR': :bird_migration,
36
+ BLAST: :blasting_operation,
37
+ DROP: :dropping,
38
+ DUSTING: :crop_dusting,
39
+ EQUIPMENT: :special_equipment_required,
40
+ 'EQUIPMENT-833': :radio_8_33_required,
41
+ 'EQUIPMENT-RNAV': :rnav_equipment_required,
42
+ 'EQUIPMENT-RSVM': :rsvm_equipment_required,
43
+ EXERCISE: :combat_exercise,
44
+ FAUNA: :sensitive_fauna,
45
+ FIRE: :fire_suppression,
46
+ FIREWORK: :fireworks,
47
+ GAZ: :gaz_field,
48
+ GLIDER: :gliding,
49
+ HANGGLIDER: :hanggliding,
50
+ 'HI-LIGHT': :high_intensity_light,
51
+ 'HI-RADIO': :high_intensity_radio,
52
+ 'IND-CHEM': :chemical_plant,
53
+ 'IND-NUCLEAR': :nuclear_activity,
54
+ 'IND-OIL': :oil_refinery,
55
+ JETCLIMB: :jet_climb,
56
+ LASER: :laser_light,
57
+ MILOPS: :military_operation,
58
+ MISSILES: :guided_missiles,
59
+ NATURE: :natural_reserve,
60
+ NAVAL: :ship_exercise,
61
+ 'NO-NOISE': :noise_abatement,
62
+ OIL: :oil_field,
63
+ PARACHUTE: :parachuting,
64
+ PARAGLIDER: :paragliding,
65
+ POPULATION: :highly_populated,
66
+ PROCEDURE: :special_procedure,
67
+ REFUEL: :refuelling,
68
+ SHOOT: :shooting_from_ground,
69
+ SPACEFLT: :space_flight,
70
+ SPORT: :sport,
71
+ TECHNICAL: :technical_activity,
72
+ 'TFC-AD': :aerodrome_traffic,
73
+ 'TFC-HELI': :helicopter_traffic,
74
+ TOWING: :winch_activity,
75
+ TRG: :training,
76
+ UAV: :drone,
77
+ ULM: :ultra_light_flight,
78
+ VIP: :vip,
79
+ 'VIP-PRES': :president,
80
+ 'VIP-VICE': :vice_president,
81
+ WATERBLAST: :underwater_explosion,
82
+ WORK: :aerial_work,
83
+ OTHER: :other
84
+ }.freeze
85
+
86
+ # @return [String, nil] four letter location identifier as published in the ICAO DOC 7910
87
+ attr_reader :location_indicator
88
+
22
89
  # @return [AIXM::Component::VerticalLimits] vertical limits of this layer
23
90
  attr_reader :vertical_limits
24
91
 
92
+ # @return [String, nil] primary activity (e.g. "GLIDER")
93
+ attr_reader :activity
94
+
25
95
  # @return [AIXM::Component::Timetable, nil] activation hours
26
96
  attr_reader :timetable
27
97
 
28
98
  # @return [String, nil] free text remarks
29
99
  attr_reader :remarks
30
100
 
31
- def initialize(class: nil, vertical_limits:)
101
+ def initialize(class: nil, location_indicator: nil, vertical_limits:)
32
102
  self.class = binding.local_variable_get(:class)
33
- self.vertical_limits = vertical_limits
103
+ self.location_indicator, self.vertical_limits = location_indicator, vertical_limits
34
104
  self.selective = false
35
105
  end
36
106
 
@@ -50,11 +120,20 @@ module AIXM
50
120
  fail(ArgumentError, "invalid class") unless @klass.nil? || CLASSES.include?(@klass)
51
121
  end
52
122
 
123
+ def location_indicator=(value)
124
+ fail(ArgumentError, "invalid location indicator") unless value.nil? || (value.is_a?(String) && value.length == 4)
125
+ @location_indicator = value&.uptrans
126
+ end
127
+
53
128
  def vertical_limits=(value)
54
129
  fail(ArgumentError, "invalid vertical limits") unless value.is_a? AIXM::Component::VerticalLimits
55
130
  @vertical_limits = value
56
131
  end
57
132
 
133
+ def activity=(value)
134
+ @activity = value.nil? ? nil : ACTIVITIES.lookup(value.to_s.to_sym, nil) || fail(ArgumentError, "invalid activity")
135
+ end
136
+
58
137
  def timetable=(value)
59
138
  fail(ArgumentError, "invalid timetable") unless value.nil? || value.is_a?(AIXM::Component::Timetable)
60
139
  @timetable = value
@@ -79,6 +158,8 @@ module AIXM
79
158
  def to_xml
80
159
  builder = Builder::XmlMarkup.new(indent: 2)
81
160
  builder.codeClass(self.class.to_s) if self.class
161
+ builder.codeLocInd(location_indicator) if location_indicator
162
+ builder.codeActivity(ACTIVITIES.key(activity).to_s) if activity
82
163
  builder << vertical_limits.to_xml
83
164
  builder << timetable.to_xml(as: :Att) if timetable
84
165
  builder.codeSelAvbl(selective? ? 'Y' : 'N') if AIXM.ofmx?
@@ -17,6 +17,9 @@ module AIXM
17
17
  class Document
18
18
  NAMESPACE_PATTERN = /\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
+ # @return [String] OFMX region all features in this document belong to
21
+ attr_reader :region
22
+
20
23
  # @return [String] UUID to namespace the data contained in this document
21
24
  attr_reader :namespace
22
25
 
@@ -29,8 +32,8 @@ module AIXM
29
32
  # @return [Array<AIXM::Feature>] airspaces, airports and other features
30
33
  attr_accessor :features
31
34
 
32
- def initialize(namespace: nil, created_at: nil, effective_at: nil)
33
- self.namespace, self.created_at, self.effective_at = namespace, created_at, effective_at
35
+ def initialize(region: nil, namespace: nil, created_at: nil, effective_at: nil)
36
+ self.region, self.namespace, self.created_at, self.effective_at = region, namespace, created_at, effective_at
34
37
  @features = []
35
38
  end
36
39
 
@@ -39,6 +42,11 @@ module AIXM
39
42
  %Q(#<#{self.class} created_at=#{created_at.inspect}>)
40
43
  end
41
44
 
45
+ def region=(value)
46
+ fail(ArgumentError, "invalid region") unless value.nil? || value.is_a?(String)
47
+ @region = value&.upcase
48
+ end
49
+
42
50
  def namespace=(value)
43
51
  fail(ArgumentError, "invalid namespace") unless value.nil? || value.match?(NAMESPACE_PATTERN)
44
52
  @namespace = value || SecureRandom.uuid
@@ -76,6 +84,7 @@ module AIXM
76
84
  'xmlns:xsi': AIXM.schema(:namespace),
77
85
  version: AIXM.schema(:version),
78
86
  origin: "rubygem aixm-#{AIXM::VERSION}",
87
+ region: (region if AIXM.ofmx?),
79
88
  namespace: (namespace if AIXM.ofmx?),
80
89
  created: @created_at.xmlschema,
81
90
  effective: @effective_at.xmlschema
@@ -1,11 +1,23 @@
1
1
  module AIXM
2
2
 
3
+ # Extension of StandardError which contains the subject of the error.
4
+ #
5
+ # @abstract
6
+ class Error < StandardError
7
+ attr_reader :subject
8
+
9
+ def initialize(message, subject=nil)
10
+ @subject = subject
11
+ super message
12
+ end
13
+ end
14
+
3
15
  # @see AIXM::Component::Geometry
4
16
  # @see AIXM::Feature::Airspace#to_xml
5
- class GeometryError < StandardError; end
17
+ class GeometryError < Error; end
6
18
 
7
19
  # @see AIXM::Component::Layer
8
20
  # @see AIXM::Feature::Airspace#to_xml
9
- class LayerError < StandardError; end
21
+ class LayerError < Error; end
10
22
 
11
23
  end