aixm 0.3.1 → 0.3.2

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.
@@ -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