aixm 0.3.6 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d13df653e543e46983fa5d15d841afae85142eb249e0272ecfa9e440047f8998
4
- data.tar.gz: 988b5d2736771137ba4764b320c886d456576ecdea0c1115d3dde4d9ab33dbb4
3
+ metadata.gz: bad5f1c431575562810faf541c197660e815e3652213dc8d6fedc8cde897f9d4
4
+ data.tar.gz: f1a750f511dc13146af92a25aea066a89a67d358534f2f4a582e415919855ef4
5
5
  SHA512:
6
- metadata.gz: 86b872de155b94fd83a331b7935e4496a8558fdff94e60d64fcceb9973e1ce21acf7f08a52e5955f03352990f0a818b3844fda3ad598e394bcf83aabb7b5dd0e
7
- data.tar.gz: da0e8ab2566abb6530085c632a4e84bc7628ec2aa42cc93566c0b35c2768657f7c42764848b9a0b5149d15617aa25990bb0c5a7a368f39f67cc19f17d702ebc4
6
+ metadata.gz: f587e9d97f7a1fdb21e38f79c2be3567a9a8a8a4c0bc692b74c19305db8b0c2c8fb734d0b90b7ba488916ca9bc23a2a60ba4e836510be6984d1bd95055ffbe28
7
+ data.tar.gz: ac70ee0a8c63f20f0fb0277ba075c0880ed2ad39ae32e6c5e38d9fa76d80943a7c8efb394bb33af52f5c6ce00081d066e59d9df9a1105812bfaf8bafc2a23596
@@ -1 +1 @@
1
- ruby-2.6.3
1
+ ruby-2.6.4
@@ -1,3 +1,9 @@
1
+ ## 0.3.7
2
+
3
+ #### Additions
4
+ * `AIXM::Document#select_features`
5
+ * `AIXM::Document#group_obstacles!`
6
+
1
7
  ## 0.3.6
2
8
 
3
9
  #### Additions
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency 'minitest-reporters'
26
26
  spec.add_development_dependency 'minitest-sound'
27
27
  spec.add_development_dependency 'minitest-matchers'
28
+ spec.add_development_dependency 'minitest-focus'
28
29
  spec.add_development_dependency 'guard'
29
30
  spec.add_development_dependency 'guard-minitest'
30
31
  spec.add_development_dependency 'yard'
@@ -62,6 +62,53 @@ module AIXM
62
62
  @effective_at = value&.to_time || created_at || Time.now
63
63
  end
64
64
 
65
+ # Search features and return those matching the given class and attribute
66
+ # values
67
+ #
68
+ # @example
69
+ # select_features(:airport, id: "LFNT")
70
+ #
71
+ # @param klass [Class, Symbol] feature class like AIXM::Feature::Airport or
72
+ # AIXM::Feature::NavigationalAid::VOR, shorthand notations as symbols
73
+ # e.g. :airport or :vor as listed in AIXM::CLASSES are recognized as well
74
+ # @param attributes [Hash] search attributes by their values
75
+ # @return [Array<AIXM::Feature>]
76
+ def select_features(klass, attributes={})
77
+ if klass.is_a? Symbol
78
+ klass = AIXM::CLASSES.fetch(klass, nil)
79
+ fail(ArgumentError, "unknown feature shortcut") unless klass
80
+ end
81
+ features.select do |feature|
82
+ if feature.is_a? klass
83
+ attributes.reduce(true) do |memo, (attribute, value)|
84
+ memo && feature.send(attribute) == value
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ # Compare all ungrouped obstacles and create new obstacle groups whose
91
+ # members are located within +max_distance+ pairwise.
92
+ #
93
+ # @param max_distance [AIXM::D] max distance between obstacle group member
94
+ # pairs (default: 1 NM)
95
+ # @return [Integer] number of obstacle groups added
96
+ def group_obstacles!(max_distance: AIXM.d(1, :nm))
97
+ obstacles, list = select_features(:obstacle), {}
98
+ while subject = obstacles.shift
99
+ obstacles.each do |obstacle|
100
+ if subject.xy.distance(obstacle.xy) <= max_distance
101
+ [subject, obstacle].each { |o| list[o] = list[subject] || SecureRandom.uuid }
102
+ end
103
+ end
104
+ end
105
+ list.group_by(&:last).each do |_, grouped_list|
106
+ obstacle_group = AIXM.obstacle_group(source: grouped_list.first.first.source)
107
+ grouped_list.each { |o, _| obstacle_group.obstacles << features.delete(o) }
108
+ features << obstacle_group
109
+ end.count
110
+ end
111
+
65
112
  # Validate the generated AIXM or OFMX atainst it's XSD.
66
113
  #
67
114
  # @return [Boolean] whether valid or not
@@ -107,7 +107,8 @@ module AIXM
107
107
 
108
108
  def initialize(source: nil, organisation:, id: nil, name:, xy:)
109
109
  super(source: source)
110
- self.organisation, self.id, self.name, self.xy = organisation, id, name, xy
110
+ self.organisation, self.name, self.xy = organisation, name, xy
111
+ self.id = id # name must already be set
111
112
  @runways, @fatos, @helipads, @usage_limitations, @addresses = [], [], [], [], []
112
113
  end
113
114
 
@@ -1,3 +1,3 @@
1
1
  module AIXM
2
- VERSION = "0.3.6".freeze
2
+ VERSION = "0.3.7".freeze
3
3
  end
@@ -79,6 +79,83 @@ describe AIXM::Document do
79
79
  end
80
80
  end
81
81
 
82
+ describe :select_features do
83
+ subject do
84
+ AIXM::Factory.document
85
+ end
86
+
87
+ it "returns array of features by class" do
88
+ subject.select_features(:airport).map(&:id).must_equal %w(LFNT)
89
+ subject.select_features(AIXM::Feature::Airport).map(&:id).must_equal %w(LFNT)
90
+ end
91
+
92
+ it "returns array of features by class and attributes" do
93
+ subject.select_features(:airport, id: "LFNT").map(&:id).must_equal %w(LFNT)
94
+ subject.select_features(AIXM::Feature::Airport, id: "LFNT").map(&:id).must_equal %w(LFNT)
95
+ end
96
+
97
+ it "returns empty array if nothing matches" do
98
+ subject.select_features(:airport, id: "FAKE").must_equal []
99
+ end
100
+
101
+ it "fails on invalid shortcut" do
102
+ -> { subject.select_features(:fake) }.must_raise ArgumentError
103
+ end
104
+ end
105
+
106
+ describe :group_obstacles! do
107
+ subject do
108
+ AIXM.document.tap do |document|
109
+ {
110
+ 1 => AIXM.xy(lat: 32.665623, long: -111.488584), # 4 north ends:
111
+ 2 => AIXM.xy(lat: 32.665613, long: -111.487701), # 84m distance between each
112
+ 3 => AIXM.xy(lat: 32.665603, long: -111.486796), # 505m distance to south ends
113
+ 4 => AIXM.xy(lat: 32.665611, long: -111.485902),
114
+ 5 => AIXM.xy(lat: 32.661062, long: -111.488624), # 4 south ends:
115
+ 6 => AIXM.xy(lat: 32.661061, long: -111.487731), # 84m distance between each
116
+ 7 => AIXM.xy(lat: 32.661042, long: -111.486814), # 505m distance to north ends
117
+ 8 => AIXM.xy(lat: 32.661054, long: -111.485931),
118
+ 9 => AIXM.xy(lat: 0, long: 0) # far away from the others
119
+ }.to_a.shuffle.each do |index, xy|
120
+ document.features << AIXM.obstacle(
121
+ source: index.to_s,
122
+ name: index.to_s,
123
+ type: :other,
124
+ xy: xy,
125
+ radius: AIXM.d(10, :m),
126
+ z: AIXM.z(1680 , :qnh)
127
+ )
128
+ end
129
+ end
130
+ end
131
+
132
+ it "adds 1 group of obstacles with default max distance" do
133
+ subject.group_obstacles!.must_equal 1
134
+ obstacle_group = subject.select_features(:obstacle_group).first
135
+ obstacle_group.obstacles.count.must_equal 8
136
+ end
137
+
138
+ it "adds 2 groups of obstacles with max distance 400m" do
139
+ subject.group_obstacles!(max_distance: AIXM.d(400, :m)).must_equal 2
140
+ obstacle_groups = subject.features.select { |f| f.is_a? AIXM::Feature::ObstacleGroup }
141
+ obstacle_groups.each do |obstacle_group|
142
+ names = obstacle_group.obstacles.map(&:name).sort
143
+ names.must_equal names.include?('1') ? %w(1 2 3 4) : %w(5 6 7 8)
144
+ end
145
+ end
146
+
147
+ it "leaves ungrouped obstacles untouched" do
148
+ subject.group_obstacles!
149
+ subject.select_features(:obstacle).count.must_equal 1
150
+ end
151
+
152
+ it "copies source of first obstacle to obstacle group" do
153
+ subject.group_obstacles!
154
+ obstacle_group = subject.select_features(:obstacle_group).first
155
+ obstacle_group.source.must_equal obstacle_group.obstacles.first.source
156
+ end
157
+ end
158
+
82
159
  context "AIXM" do
83
160
  subject do
84
161
  AIXM.aixm!
@@ -33,6 +33,7 @@ describe AIXM::Feature::Airport do
33
33
 
34
34
  it "combines 2 character region with an 8 characters digest from name" do
35
35
  subject.tap { |s| s.id = 'lf' }.id.must_equal 'LFD18754F5'
36
+ subject.tap { |s| s.name = 'OTHER'; s.id = 'lf' }.id.must_equal 'LFD646E0F9'
36
37
  end
37
38
 
38
39
  it "upcases valid values" do
@@ -14,6 +14,7 @@ Minitest::Sound.failure = Pathname(__dir__).join('sounds/failure.mp3').to_s
14
14
  require 'minitest/reporters'
15
15
  Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new, Minitest::Sound::Reporter.new]
16
16
 
17
+ require 'minitest/focus'
17
18
  require 'minitest/matchers'
18
19
  require Pathname(__dir__).join('factory')
19
20
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aixm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.3.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Schwyn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-22 00:00:00.000000000 Z
11
+ date: 2019-09-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest-focus
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: guard
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -293,7 +307,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
293
307
  - !ruby/object:Gem::Version
294
308
  version: '0'
295
309
  requirements: []
296
- rubygems_version: 3.0.3
310
+ rubygems_version: 3.0.6
297
311
  signing_key:
298
312
  specification_version: 4
299
313
  summary: Aeronautical Information Exchange Model (AIXM 4.5).