aixm 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,284 @@
1
+ require_relative '../../../spec_helper'
2
+
3
+ describe AIXM::Feature::ObstacleGroup do
4
+ describe "unlinked group" do
5
+ subject do
6
+ AIXM.obstacle_group(name: "Mirmande éoliennes")
7
+ end
8
+
9
+ describe :initialize do
10
+ it "sets defaults" do
11
+ subject = AIXM.obstacle_group(
12
+ name: "Mirmande éoliennes"
13
+ )
14
+ subject.obstacles.must_equal []
15
+ end
16
+ end
17
+
18
+ describe :name= do
19
+ it "fails on invalid values" do
20
+ [:foobar, 123].wont_be_written_to subject, :name
21
+ end
22
+
23
+ it "upcases and transcodes valid values" do
24
+ subject.name.must_equal 'MIRMANDE EOLIENNES'
25
+ end
26
+ end
27
+
28
+ describe :add_obstacle do
29
+ it "adds an obstacle to the group" do
30
+ subject.add_obstacle(AIXM::Factory.obstacle)
31
+ subject.obstacles.count.must_equal 1
32
+ subject.obstacles.first.must_be :grouped?
33
+ subject.obstacles.first.group.must_equal subject
34
+ end
35
+ end
36
+
37
+ describe :id do
38
+ subject do
39
+ AIXM::Factory.unlinked_obstacle_group
40
+ end
41
+
42
+ it "is derived from the group name" do
43
+ subject.id.must_equal '462c8d00-981a-0995-09aa-4ba39161bb41'
44
+ subject.name = 'Oggy'
45
+ subject.id.must_equal '939de24d-941b-d5a6-3437-df135ddb9906'
46
+ end
47
+
48
+ it "is derived from the xy of the group obstacles" do
49
+ subject.id.must_equal '462c8d00-981a-0995-09aa-4ba39161bb41'
50
+ subject.obstacles.first.xy.long = 1
51
+ subject.id.must_equal '819d6977-5301-14d3-6d2e-1de007d922e1'
52
+ end
53
+ end
54
+
55
+ describe :to_xml do
56
+ subject do
57
+ AIXM::Factory.unlinked_obstacle_group
58
+ end
59
+
60
+ it "builds correct AIXM" do
61
+ AIXM.aixm!
62
+ subject.to_xml.must_equal <<~END
63
+ <!-- Obstacle: [wind_turbine] 44.67501389N 004.87256667E LA TEISSONIERE 1 -->
64
+ <Obs>
65
+ <ObsUid>
66
+ <geoLat>444030.05N</geoLat>
67
+ <geoLong>0045221.24E</geoLong>
68
+ </ObsUid>
69
+ <txtName>LA TEISSONIERE 1</txtName>
70
+ <txtDescrType>WINDTURBINE</txtDescrType>
71
+ <codeGroup>Y</codeGroup>
72
+ <codeLgt>N</codeLgt>
73
+ <codeDatum>WGE</codeDatum>
74
+ <valGeoAccuracy>50</valGeoAccuracy>
75
+ <uomGeoAccuracy>M</uomGeoAccuracy>
76
+ <valElev>1764</valElev>
77
+ <valElevAccuracy>33</valElevAccuracy>
78
+ <valHgt>262</valHgt>
79
+ <uomDistVer>FT</uomDistVer>
80
+ </Obs>
81
+ <!-- Obstacle: [wind_turbine] 44.67946667N 004.87381111E LA TEISSONIERE 2 -->
82
+ <Obs>
83
+ <ObsUid>
84
+ <geoLat>444046.08N</geoLat>
85
+ <geoLong>0045225.72E</geoLong>
86
+ </ObsUid>
87
+ <txtName>LA TEISSONIERE 2</txtName>
88
+ <txtDescrType>WINDTURBINE</txtDescrType>
89
+ <codeGroup>Y</codeGroup>
90
+ <codeLgt>N</codeLgt>
91
+ <codeDatum>WGE</codeDatum>
92
+ <valGeoAccuracy>50</valGeoAccuracy>
93
+ <uomGeoAccuracy>M</uomGeoAccuracy>
94
+ <valElev>1738</valElev>
95
+ <valElevAccuracy>33</valElevAccuracy>
96
+ <valHgt>262</valHgt>
97
+ <uomDistVer>FT</uomDistVer>
98
+ </Obs>
99
+ END
100
+ end
101
+
102
+ it "builds correct OFMX" do
103
+ AIXM.ofmx!
104
+ subject.to_xml.must_equal <<~END
105
+ <!-- Obstacle: [wind_turbine] 44.67501389N 004.87256667E LA TEISSONIERE 1 -->
106
+ <Obs>
107
+ <ObsUid>
108
+ <geoLat>44.67501389N</geoLat>
109
+ <geoLong>004.87256667E</geoLong>
110
+ </ObsUid>
111
+ <txtName>LA TEISSONIERE 1</txtName>
112
+ <codeType>WINDTURBINE</codeType>
113
+ <codeLgt>N</codeLgt>
114
+ <codeMarking>N</codeMarking>
115
+ <codeDatum>WGE</codeDatum>
116
+ <valGeoAccuracy>50</valGeoAccuracy>
117
+ <uomGeoAccuracy>M</uomGeoAccuracy>
118
+ <valElev>1764</valElev>
119
+ <valElevAccuracy>33</valElevAccuracy>
120
+ <valHgt>262</valHgt>
121
+ <codeHgtAccuracy>N</codeHgtAccuracy>
122
+ <uomDistVer>FT</uomDistVer>
123
+ <valRadius>80</valRadius>
124
+ <uomRadius>M</uomRadius>
125
+ <codeGroupId>462c8d00-981a-0995-09aa-4ba39161bb41</codeGroupId>
126
+ <txtGroupName>MIRMANDE EOLIENNES</txtGroupName>
127
+ </Obs>
128
+ <!-- Obstacle: [wind_turbine] 44.67946667N 004.87381111E LA TEISSONIERE 2 -->
129
+ <Obs>
130
+ <ObsUid>
131
+ <geoLat>44.67946667N</geoLat>
132
+ <geoLong>004.87381111E</geoLong>
133
+ </ObsUid>
134
+ <txtName>LA TEISSONIERE 2</txtName>
135
+ <codeType>WINDTURBINE</codeType>
136
+ <codeLgt>N</codeLgt>
137
+ <codeMarking>N</codeMarking>
138
+ <codeDatum>WGE</codeDatum>
139
+ <valGeoAccuracy>50</valGeoAccuracy>
140
+ <uomGeoAccuracy>M</uomGeoAccuracy>
141
+ <valElev>1738</valElev>
142
+ <valElevAccuracy>33</valElevAccuracy>
143
+ <valHgt>262</valHgt>
144
+ <codeHgtAccuracy>N</codeHgtAccuracy>
145
+ <uomDistVer>FT</uomDistVer>
146
+ <valRadius>80</valRadius>
147
+ <uomRadius>M</uomRadius>
148
+ <codeGroupId>462c8d00-981a-0995-09aa-4ba39161bb41</codeGroupId>
149
+ <txtGroupName>MIRMANDE EOLIENNES</txtGroupName>
150
+ </Obs>
151
+ END
152
+ end
153
+ end
154
+ end
155
+
156
+ describe "linked group" do
157
+ subject do
158
+ AIXM.obstacle_group(name: "Mirmande éoliennes")
159
+ end
160
+
161
+ describe :add_obstacle do
162
+ it "adds an obstacle to the group and links it to previous" do
163
+ subject.add_obstacle(AIXM::Factory.obstacle)
164
+ subject.add_obstacle(AIXM::Factory.obstacle, linked_to: :previous, link_type: :cable)
165
+ subject.obstacles.count.must_equal 2
166
+ subject.obstacles.last.linked_to.must_equal subject.obstacles.first
167
+ subject.obstacles.last.link_type.must_equal :cable
168
+ end
169
+
170
+ it "adds an obstacle to the group and links it to another obstacle" do
171
+ subject.add_obstacle(AIXM::Factory.obstacle)
172
+ subject.add_obstacle(AIXM::Factory.obstacle, linked_to: subject.obstacles.first, link_type: :solid)
173
+ subject.obstacles.count.must_equal 2
174
+ subject.obstacles.last.linked_to.must_equal subject.obstacles.first
175
+ subject.obstacles.last.link_type.must_equal :solid
176
+ end
177
+ end
178
+
179
+ describe :to_xml do
180
+ subject do
181
+ AIXM::Factory.linked_obstacle_group
182
+ end
183
+
184
+ it "builds correct AIXM" do
185
+ AIXM.aixm!
186
+ subject.to_xml.must_equal <<~END
187
+ <!-- Obstacle: [mast] 52.29639722N 002.10675278W DROITWICH LW NORTH -->
188
+ <Obs>
189
+ <ObsUid>
190
+ <geoLat>521747.03N</geoLat>
191
+ <geoLong>0020624.31W</geoLong>
192
+ </ObsUid>
193
+ <txtName>DROITWICH LW NORTH</txtName>
194
+ <txtDescrType>MAST</txtDescrType>
195
+ <codeGroup>Y</codeGroup>
196
+ <codeLgt>N</codeLgt>
197
+ <codeDatum>WGE</codeDatum>
198
+ <valGeoAccuracy>0</valGeoAccuracy>
199
+ <uomGeoAccuracy>M</uomGeoAccuracy>
200
+ <valElev>848</valElev>
201
+ <valElevAccuracy>0</valElevAccuracy>
202
+ <valHgt>700</valHgt>
203
+ <uomDistVer>FT</uomDistVer>
204
+ </Obs>
205
+ <!-- Obstacle: [mast] 52.29457778N 002.10568611W DROITWICH LW NORTH -->
206
+ <Obs>
207
+ <ObsUid>
208
+ <geoLat>521740.48N</geoLat>
209
+ <geoLong>0020620.47W</geoLong>
210
+ </ObsUid>
211
+ <txtName>DROITWICH LW NORTH</txtName>
212
+ <txtDescrType>MAST</txtDescrType>
213
+ <codeGroup>Y</codeGroup>
214
+ <codeLgt>N</codeLgt>
215
+ <codeDatum>WGE</codeDatum>
216
+ <valGeoAccuracy>0</valGeoAccuracy>
217
+ <uomGeoAccuracy>M</uomGeoAccuracy>
218
+ <valElev>848</valElev>
219
+ <valElevAccuracy>0</valElevAccuracy>
220
+ <valHgt>700</valHgt>
221
+ <uomDistVer>FT</uomDistVer>
222
+ </Obs>
223
+ END
224
+ end
225
+
226
+ it "builds correct OFMX" do
227
+ AIXM.ofmx!
228
+ subject.to_xml.must_equal <<~END
229
+ <!-- Obstacle: [mast] 52.29639722N 002.10675278W DROITWICH LW NORTH -->
230
+ <Obs>
231
+ <ObsUid>
232
+ <geoLat>52.29639722N</geoLat>
233
+ <geoLong>002.10675278W</geoLong>
234
+ </ObsUid>
235
+ <txtName>DROITWICH LW NORTH</txtName>
236
+ <codeType>MAST</codeType>
237
+ <codeLgt>N</codeLgt>
238
+ <codeMarking>N</codeMarking>
239
+ <codeDatum>WGE</codeDatum>
240
+ <valGeoAccuracy>0</valGeoAccuracy>
241
+ <uomGeoAccuracy>M</uomGeoAccuracy>
242
+ <valElev>848</valElev>
243
+ <valElevAccuracy>0</valElevAccuracy>
244
+ <valHgt>700</valHgt>
245
+ <codeHgtAccuracy>Y</codeHgtAccuracy>
246
+ <uomDistVer>FT</uomDistVer>
247
+ <valRadius>200</valRadius>
248
+ <uomRadius>M</uomRadius>
249
+ <codeGroupId>18e65683-798d-0941-8de4-cb65a6427035</codeGroupId>
250
+ <txtGroupName>DROITWICH LONGWAVE ANTENNA</txtGroupName>
251
+ </Obs>
252
+ <!-- Obstacle: [mast] 52.29457778N 002.10568611W DROITWICH LW NORTH -->
253
+ <Obs>
254
+ <ObsUid>
255
+ <geoLat>52.29457778N</geoLat>
256
+ <geoLong>002.10568611W</geoLong>
257
+ </ObsUid>
258
+ <txtName>DROITWICH LW NORTH</txtName>
259
+ <codeType>MAST</codeType>
260
+ <codeLgt>N</codeLgt>
261
+ <codeMarking>N</codeMarking>
262
+ <codeDatum>WGE</codeDatum>
263
+ <valGeoAccuracy>0</valGeoAccuracy>
264
+ <uomGeoAccuracy>M</uomGeoAccuracy>
265
+ <valElev>848</valElev>
266
+ <valElevAccuracy>0</valElevAccuracy>
267
+ <valHgt>700</valHgt>
268
+ <codeHgtAccuracy>Y</codeHgtAccuracy>
269
+ <uomDistVer>FT</uomDistVer>
270
+ <valRadius>200</valRadius>
271
+ <uomRadius>M</uomRadius>
272
+ <codeGroupId>18e65683-798d-0941-8de4-cb65a6427035</codeGroupId>
273
+ <txtGroupName>DROITWICH LONGWAVE ANTENNA</txtGroupName>
274
+ <ObsUidLink>
275
+ <geoLat>52.29639722N</geoLat>
276
+ <geoLong>002.10675278W</geoLong>
277
+ </ObsUidLink>
278
+ <codeLinkType>CABLE</codeLinkType>
279
+ </Obs>
280
+ END
281
+ end
282
+ end
283
+ end
284
+ end
@@ -0,0 +1,285 @@
1
+ require_relative '../../../spec_helper'
2
+
3
+ describe AIXM::Feature::Obstacle do
4
+ subject do
5
+ AIXM::Factory.obstacle
6
+ end
7
+
8
+ describe :initialize do
9
+ it "sets defaults" do
10
+ subject = AIXM.obstacle(
11
+ type: :tower,
12
+ xy: AIXM.xy(lat: %q(48°51'29.7"N), long: %q(002°17'40.52"E)),
13
+ radius: AIXM.d(88, :m),
14
+ z: AIXM.z(1187 , :qnh)
15
+ )
16
+ subject.wont_be :lighting
17
+ subject.wont_be :marking
18
+ subject.wont_be :height_accurate
19
+ end
20
+ end
21
+
22
+ describe :name= do
23
+ it "fails on invalid values" do
24
+ [:foobar, 123].wont_be_written_to subject, :name
25
+ end
26
+
27
+ it "upcases and transcodes valid values" do
28
+ subject.tap { |s| s.name = 'Teufelsbrücke' }.name.must_equal 'TEUFELSBRUECKE'
29
+ end
30
+ end
31
+
32
+ describe :type= do
33
+ it "fails on invalid values" do
34
+ [nil, :foobar].wont_be_written_to subject, :type
35
+ end
36
+
37
+ it "looks up valid values" do
38
+ subject.tap { |s| s.type = :WINDTURBINE }.type.must_equal :wind_turbine
39
+ subject.tap { |s| s.type = :TOWER }.type.must_equal :tower
40
+ end
41
+ end
42
+
43
+ describe :xy= do
44
+ macro :xy
45
+
46
+ it "fails on nil values" do
47
+ [nil].wont_be_written_to subject, :xy
48
+ end
49
+ end
50
+
51
+ describe :radius= do
52
+ it "fails on invalid values" do
53
+ [nil, :foobar, 123, AIXM.d(0, :m)].wont_be_written_to subject, :radius
54
+ end
55
+
56
+ it "accepts valid values" do
57
+ [AIXM::Factory.d].must_be_written_to subject, :radius
58
+ end
59
+ end
60
+
61
+ describe :z= do
62
+ macro :z_qnh
63
+
64
+ it "fails on nil values" do
65
+ [nil].wont_be_written_to subject, :z
66
+ end
67
+ end
68
+
69
+ describe :lighting= do
70
+ it "fails on invalid values" do
71
+ [:foobar, 123].wont_be_written_to subject, :lighting
72
+ end
73
+
74
+ it "accepts valid values" do
75
+ [true, false, nil].must_be_written_to subject, :lighting
76
+ end
77
+ end
78
+
79
+ describe :lighting_remarks= do
80
+ it "accepts nil value" do
81
+ [nil].must_be_written_to subject, :lighting_remarks
82
+ end
83
+
84
+ it "stringifies valid values" do
85
+ subject.tap { |s| s.lighting_remarks = 'foobar' }.lighting_remarks.must_equal 'foobar'
86
+ subject.tap { |s| s.lighting_remarks = 123 }.lighting_remarks.must_equal '123'
87
+ end
88
+ end
89
+
90
+ describe :marking= do
91
+ it "fails on invalid values" do
92
+ [:foobar, 123].wont_be_written_to subject, :marking
93
+ end
94
+
95
+ it "accepts valid values" do
96
+ [true, false, nil].must_be_written_to subject, :marking
97
+ end
98
+ end
99
+
100
+ describe :marking_remarks= do
101
+ it "accepts nil value" do
102
+ [nil].must_be_written_to subject, :marking_remarks
103
+ end
104
+
105
+ it "stringifies valid values" do
106
+ subject.tap { |s| s.marking_remarks = 'foobar' }.marking_remarks.must_equal 'foobar'
107
+ subject.tap { |s| s.marking_remarks = 123 }.marking_remarks.must_equal '123'
108
+ end
109
+ end
110
+
111
+ describe :height= do
112
+ it "fails on invalid values" do
113
+ [:foobar, 123, AIXM.d(0, :m)].wont_be_written_to subject, :height
114
+ end
115
+
116
+ it "accepts valid values" do
117
+ [nil, AIXM::Factory.d].must_be_written_to subject, :height
118
+ end
119
+ end
120
+
121
+ describe :xy_accuracy= do
122
+ it "fails on invalid values" do
123
+ [:foobar, 123].wont_be_written_to subject, :xy_accuracy
124
+ end
125
+
126
+ it "accepts valid values" do
127
+ [nil, AIXM::Factory.d, AIXM.d(0, :m)].must_be_written_to subject, :xy_accuracy
128
+ end
129
+ end
130
+
131
+ describe :z_accuracy= do
132
+ it "fails on invalid values" do
133
+ [:foobar, 123].wont_be_written_to subject, :z_accuracy
134
+ end
135
+
136
+ it "accepts valid values" do
137
+ [nil, AIXM::Factory.d, AIXM.d(0, :m)].must_be_written_to subject, :z_accuracy
138
+ end
139
+ end
140
+
141
+ describe :height_accurate= do
142
+ it "fails on invalid values" do
143
+ [:foobar, 123].wont_be_written_to subject, :height_accurate
144
+ end
145
+
146
+ it "accepts valid values" do
147
+ [true, false, nil].must_be_written_to subject, :height_accurate
148
+ end
149
+ end
150
+
151
+ describe :valid_from= do
152
+ it "fails on invalid values" do
153
+ ['foobar', '2018-01-77'].wont_be_written_to subject, :valid_from
154
+ end
155
+
156
+ it "accepts nil value" do
157
+ [nil].must_be_written_to subject, :valid_from
158
+ end
159
+
160
+ it "parses dates and times" do
161
+ string = '2018-01-01 12:00:00 +0100'
162
+ subject.tap { |s| s.valid_from = string }.valid_from.must_equal Time.parse(string)
163
+ end
164
+ end
165
+
166
+ describe :valid_until= do
167
+ it "fails on invalid values" do
168
+ ['foobar', '2018-01-77'].wont_be_written_to subject, :valid_until
169
+ end
170
+
171
+ it "accepts nil value" do
172
+ [nil].must_be_written_to subject, :valid_until
173
+ end
174
+
175
+ it "parses dates and times" do
176
+ string = '2018-01-01 12:00:00 +0100'
177
+ subject.tap { |s| s.valid_until = string }.valid_until.must_equal Time.parse(string)
178
+ end
179
+ end
180
+
181
+ describe :remarks= do
182
+ macro :remarks
183
+ end
184
+
185
+ describe :clustered? do
186
+ it "returns false if no height is set" do
187
+ subject.tap { |s| s.height = nil }.wont_be :clustered?
188
+ end
189
+
190
+ it "returns true if radius is bigger than height" do
191
+ subject.tap { |s| s.radius, s.height = AIXM.d(2, :m), AIXM.d(1, :m) }.must_be :clustered?
192
+ end
193
+
194
+ it "returns false if radius is smaller than height" do
195
+ subject.tap { |s| s.radius, s.height = AIXM.d(1, :m), AIXM.d(2, :m) }.wont_be :clustered?
196
+ end
197
+ end
198
+
199
+ describe :grouped? do
200
+ it "returns false since obstacles are not grouped" do
201
+ subject.wont_be :grouped?
202
+ end
203
+ end
204
+
205
+ describe :to_xml do
206
+ it "builds correct AIXM" do
207
+ AIXM.aixm!
208
+ subject.to_xml.must_equal <<~END
209
+ <!-- Obstacle: [tower] 48.85825000N 002.29458889E EIFFEL TOWER -->
210
+ <Obs>
211
+ <ObsUid>
212
+ <geoLat>485129.70N</geoLat>
213
+ <geoLong>0021740.52E</geoLong>
214
+ </ObsUid>
215
+ <txtName>EIFFEL TOWER</txtName>
216
+ <txtDescrType>TOWER</txtDescrType>
217
+ <codeGroup>N</codeGroup>
218
+ <codeLgt>Y</codeLgt>
219
+ <txtDescrLgt>red strobes</txtDescrLgt>
220
+ <codeDatum>WGE</codeDatum>
221
+ <valGeoAccuracy>2</valGeoAccuracy>
222
+ <uomGeoAccuracy>M</uomGeoAccuracy>
223
+ <valElev>1187</valElev>
224
+ <valElevAccuracy>3</valElevAccuracy>
225
+ <valHgt>1063</valHgt>
226
+ <uomDistVer>FT</uomDistVer>
227
+ <txtRmk>Temporary light installations (white strobes, gyro light etc)</txtRmk>
228
+ </Obs>
229
+ END
230
+ end
231
+
232
+ it "builds correct OFMX" do
233
+ AIXM.ofmx!
234
+ subject.to_xml.must_equal <<~END
235
+ <!-- Obstacle: [tower] 48.85825000N 002.29458889E EIFFEL TOWER -->
236
+ <Obs>
237
+ <ObsUid>
238
+ <geoLat>48.85825000N</geoLat>
239
+ <geoLong>002.29458889E</geoLong>
240
+ </ObsUid>
241
+ <txtName>EIFFEL TOWER</txtName>
242
+ <codeType>TOWER</codeType>
243
+ <codeLgt>Y</codeLgt>
244
+ <txtDescrLgt>red strobes</txtDescrLgt>
245
+ <codeDatum>WGE</codeDatum>
246
+ <valGeoAccuracy>2</valGeoAccuracy>
247
+ <uomGeoAccuracy>M</uomGeoAccuracy>
248
+ <valElev>1187</valElev>
249
+ <valElevAccuracy>3</valElevAccuracy>
250
+ <valHgt>1063</valHgt>
251
+ <codeHgtAccuracy>Y</codeHgtAccuracy>
252
+ <uomDistVer>FT</uomDistVer>
253
+ <valRadius>88</valRadius>
254
+ <uomRadius>M</uomRadius>
255
+ <datetimeValidWef>2018-01-01T12:00:00+01:00</datetimeValidWef>
256
+ <datetimeValidTil>2019-01-01T12:00:00+01:00</datetimeValidTil>
257
+ <txtRmk>Temporary light installations (white strobes, gyro light etc)</txtRmk>
258
+ </Obs>
259
+ END
260
+ end
261
+ end
262
+ end
263
+
264
+ describe AIXM::Feature::Obstacle::Grouped do
265
+ subject do
266
+ AIXM::Factory.unlinked_obstacle_group.obstacles.first
267
+ end
268
+
269
+ describe :grouped? do
270
+ it "returns true since obstacles are grouped" do
271
+ subject.must_be :grouped?
272
+ end
273
+ end
274
+
275
+ describe :linked? do
276
+ it "returns false for unlinked obstacles" do
277
+ subject.wont_be :linked?
278
+ end
279
+
280
+ it "returns true for linked obstacles" do
281
+ subject = AIXM::Factory.linked_obstacle_group.obstacles.last
282
+ subject.must_be :linked?
283
+ end
284
+ end
285
+ end