1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 import javax.microedition.location.*; |
|
18 |
|
19 /* |
|
20 * This suite of testcases tests that: |
|
21 * - Coordinates object can be created and changed |
|
22 * - legal parameters are accepted |
|
23 * - illegal parameters are not accepted |
|
24 */ |
|
25 public class CoordinatesTest extends ViperUnitTest |
|
26 { |
|
27 protected double iLat; |
|
28 |
|
29 protected double iLon; |
|
30 |
|
31 protected float iAlt; |
|
32 |
|
33 protected final static float[] LEGAL_ALT_VALUES = { Float.NaN, |
|
34 Float.MAX_VALUE, -Float.MAX_VALUE, Float.MIN_VALUE, |
|
35 Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY |
|
36 }; |
|
37 |
|
38 public CoordinatesTest() |
|
39 { |
|
40 super("CoordinatesTest"); |
|
41 } |
|
42 |
|
43 protected CoordinatesTest(String s) |
|
44 { |
|
45 super(s); |
|
46 } |
|
47 |
|
48 protected void runTest() throws Throwable |
|
49 { |
|
50 testGoodArguments(); |
|
51 testBadArguments(); |
|
52 testArgumentsRange(); |
|
53 |
|
54 testLocationMathNormal(); |
|
55 testLocationMathReverse(); |
|
56 testLocationMathShortDistance(); |
|
57 testLocationMathPolar(); |
|
58 testLocationMathSameCoords(); |
|
59 testLocationMathNullCoord(); |
|
60 |
|
61 testConvertFromStringBadArguments(); |
|
62 testConvertFromString_DD_MM(); |
|
63 testConvertFromString_DD_MM_SS(); |
|
64 |
|
65 testConvertToStringBadArguments(); |
|
66 testConvertToString_DD_MM(); |
|
67 testConvertToString_DD_MM_SS(); |
|
68 |
|
69 testLocationMathThreadSafe(); |
|
70 } |
|
71 |
|
72 void testGoodArguments() |
|
73 { |
|
74 setCurrentTest("testGoodArguments()"); |
|
75 |
|
76 // Test some values in allowed range |
|
77 double lat = 57.111111d; |
|
78 double lon = 17.111111d; |
|
79 float alt = 31.111111f; |
|
80 |
|
81 // tests -lat, -lon and -alt too |
|
82 assertReallyGood(lat, lon, alt); |
|
83 |
|
84 // Test some legal values for alt |
|
85 for (int i = 0; i < LEGAL_ALT_VALUES.length; ++i) |
|
86 { |
|
87 assertGood(lat, lon, LEGAL_ALT_VALUES[i]); |
|
88 } |
|
89 } |
|
90 |
|
91 void testBadArguments() |
|
92 { |
|
93 setCurrentTest("testBadArguments()"); |
|
94 |
|
95 double lat = 57.111111d; |
|
96 double lon = 17.111111d; |
|
97 float alt = 31.111111f; |
|
98 |
|
99 // Test that NaN is illegal for lat, lon |
|
100 assertBad(Double.NaN, lon, alt); |
|
101 assertBad(lat, Double.NaN, alt); |
|
102 assertBad(Double.NaN, Double.NaN, alt); |
|
103 |
|
104 // Test some more bad values for lat |
|
105 assertBad(Double.MAX_VALUE, lon, alt); |
|
106 assertBad(Double.POSITIVE_INFINITY, lon, alt); |
|
107 assertBad(Double.NEGATIVE_INFINITY, lon, alt); |
|
108 |
|
109 // Test some more bad values for lon |
|
110 assertBad(lat, Double.MAX_VALUE, alt); |
|
111 assertBad(lat, Double.POSITIVE_INFINITY, alt); |
|
112 assertBad(lat, Double.NEGATIVE_INFINITY, alt); |
|
113 } |
|
114 |
|
115 // Tests range of allowed values. |
|
116 void testArgumentsRange() |
|
117 { |
|
118 setCurrentTest("testArgumentsRange()"); |
|
119 |
|
120 // Test maximum allowed values |
|
121 double lat = 90.0d; |
|
122 double lon = 179.99999999999d; |
|
123 float alt = Float.POSITIVE_INFINITY; |
|
124 assertGood(lat, lon, alt); |
|
125 |
|
126 // Test minimum allowed values |
|
127 lat = -90.0d; |
|
128 lon = -180.0d; |
|
129 alt = Float.NEGATIVE_INFINITY; |
|
130 assertGood(lat, lon, alt); |
|
131 |
|
132 // Test out of range positive values |
|
133 lat = 0; |
|
134 lon = 0; |
|
135 double badLat = 90.0000000000001d; |
|
136 double badLon = 180.0d; |
|
137 |
|
138 assertBad(badLat, lon, alt); |
|
139 assertBad(lat, badLon, alt); |
|
140 assertBad(badLat, badLon, alt); |
|
141 |
|
142 // Test out of range negative values |
|
143 badLat = -90.000000000001d; |
|
144 badLon = -180.00000000001d; |
|
145 |
|
146 assertBad(badLat, lon, alt); |
|
147 assertBad(lat, badLon, alt); |
|
148 assertBad(badLat, badLon, alt); |
|
149 } |
|
150 |
|
151 // Tests that a 'normal' calculation computes correct results. |
|
152 void testLocationMathNormal() throws Exception |
|
153 { |
|
154 setCurrentTest("testLocationMathNormal()"); |
|
155 |
|
156 // Define the expected results |
|
157 float expectedDistance = 407342.9950f; // from www.fai.org |
|
158 float expectedBearing = 33.2208175f; // from www.fai.org |
|
159 |
|
160 checkDistanceAndAzimuth(new Coordinates(57.0, 17.0, -1000.0f), |
|
161 new Coordinates(60.0, 21.0, 2000.0f), expectedDistance, |
|
162 expectedBearing); |
|
163 |
|
164 // Define the expected results |
|
165 expectedDistance = 6500256.303349322f; // from www.fai.org |
|
166 expectedBearing = 200.08970684975316f; // from www.fai.org |
|
167 |
|
168 checkDistanceAndAzimuth(new Coordinates(57.0, 17.0, -1000.0f), |
|
169 new Coordinates(0.0, 0.0, 2000.0f), expectedDistance, |
|
170 expectedBearing); |
|
171 |
|
172 } |
|
173 |
|
174 // Tests that the reverse of the 'normal' calculation computes correct |
|
175 void testLocationMathReverse() throws Exception |
|
176 { |
|
177 setCurrentTest("testLocationMathReverse()"); |
|
178 |
|
179 // Create two Coordinates object with 'normal' parameters and |
|
180 // check that the computed distance and bearing are correct |
|
181 Coordinates fromCoords = new Coordinates(60.0, 21.0, 2000.0f); |
|
182 Coordinates toCoords = new Coordinates(57.0, 17.0, -1000.0f); |
|
183 |
|
184 // Define the expected results |
|
185 float expectedDistance = (float) 407342.9950; // from www.fai.org |
|
186 float expectedBearing = (float) 216.63292698852845; // from www.fai.org |
|
187 |
|
188 checkDistanceAndAzimuth(fromCoords, toCoords, expectedDistance, |
|
189 expectedBearing); |
|
190 } |
|
191 |
|
192 // Tests that a 'normal' calculation computes correct results. |
|
193 void testLocationMathShortDistance() throws Exception |
|
194 { |
|
195 setCurrentTest("testLocationMathNormal2()"); |
|
196 |
|
197 // Define the expected results |
|
198 float expectedDistance = 789.11491522f; // from www.fai.org |
|
199 float expectedBearing = 44.96957375f; // from www.fai.org |
|
200 |
|
201 checkDistanceAndAzimuth(new Coordinates(57.0, 17.0, -1000.0f), |
|
202 new Coordinates(57.005013, 17.009178, 2000.0f), |
|
203 expectedDistance, expectedBearing); |
|
204 |
|
205 checkDistanceAndAzimuth(new Coordinates(0, 0, 0.0f), new Coordinates(0, |
|
206 0.00001, 0.0f), 1.11319f, 90.0f); |
|
207 } |
|
208 |
|
209 // Tests that polar values give correct results. |
|
210 void testLocationMathPolar() throws Exception |
|
211 { |
|
212 setCurrentTest("testLocationMathPolar()"); |
|
213 |
|
214 Coordinates northPole = new Coordinates(90.0, 0.0, 0.0f); |
|
215 Coordinates southPole = new Coordinates(-90.0, 0.0, 0.0f); |
|
216 |
|
217 // Define the expected results |
|
218 float expectedDistance = 20003931.458622963f; // from www.fai.org |
|
219 |
|
220 checkDistanceAndAzimuth(northPole, southPole, expectedDistance, 180.0f); |
|
221 checkDistanceAndAzimuth(southPole, northPole, expectedDistance, 0.0f); |
|
222 } |
|
223 |
|
224 // Tests that same coordinates doesn't cause exception. |
|
225 void testLocationMathSameCoords() throws Exception |
|
226 { |
|
227 setCurrentTest("testLocationMathSameCoords()"); |
|
228 |
|
229 // Expected results |
|
230 float expectedDistance = 0.0f; |
|
231 float expectedBearing = 0.0f; |
|
232 |
|
233 checkDistanceAndAzimuth(new Coordinates(57.0, 17.0, 0.0f), |
|
234 new Coordinates(57.0, 17.0, 0.0f), expectedDistance, |
|
235 expectedBearing); |
|
236 |
|
237 // Altitude should not be used in distance and azimuth calculation |
|
238 checkDistanceAndAzimuth(new Coordinates(57.0, 17.0, 4000.0f), |
|
239 new Coordinates(57.0, 17.0, -1000.0f), expectedDistance, |
|
240 expectedBearing); |
|
241 |
|
242 // North pole |
|
243 checkDistanceAndAzimuth(new Coordinates(90.0, 10.0, 0.0f), |
|
244 new Coordinates(90.0, 10.0, 0.0f), expectedDistance, |
|
245 expectedBearing); |
|
246 |
|
247 // South pole |
|
248 checkDistanceAndAzimuth(new Coordinates(-90.0, 10.0, 0.0f), |
|
249 new Coordinates(-90.0, 10.0, 0.0f), expectedDistance, |
|
250 expectedBearing); |
|
251 } |
|
252 |
|
253 // Tests that a null coordinate causes exception. |
|
254 void testLocationMathNullCoord() |
|
255 { |
|
256 setCurrentTest("testLocationMathNullCoord()"); |
|
257 |
|
258 Coordinates fromCoords = new Coordinates(57.0, 17.0, -1000.0f); |
|
259 try |
|
260 { |
|
261 float distance = fromCoords.distance(null); |
|
262 assertTrue(false, "NullPointerException was never thrown"); |
|
263 } |
|
264 catch (NullPointerException npe) |
|
265 { |
|
266 // Exception thrown correctly |
|
267 assertTrue(npe.getMessage() == null, "Message not allowed for " |
|
268 + npe); |
|
269 } |
|
270 |
|
271 try |
|
272 { |
|
273 float azimuth = fromCoords.azimuthTo(null); |
|
274 assertTrue(false, "NullPointerException was never thrown"); |
|
275 } |
|
276 catch (NullPointerException npe) |
|
277 { |
|
278 // Exception thrown correctly |
|
279 assertTrue(npe.getMessage() == null, "Message not allowed for " |
|
280 + npe); |
|
281 } |
|
282 } |
|
283 |
|
284 // Tests that the convert() function works. |
|
285 void testConvertFromStringBadArguments() |
|
286 { |
|
287 setCurrentTest("testConvertFromStringBadArguments()"); |
|
288 try |
|
289 { |
|
290 double result = Coordinates.convert(null); |
|
291 assertTrue(false, "NullPointerException was never thrown"); |
|
292 } |
|
293 catch (NullPointerException npe) |
|
294 { |
|
295 // Exception thrown correctly |
|
296 assertTrue(npe.getMessage() == null, "Message not allowed for " |
|
297 + npe); |
|
298 } |
|
299 |
|
300 // Illegal values |
|
301 assertConvertBad(""); |
|
302 assertConvertBad("44.44"); |
|
303 assertConvertBad("1234"); |
|
304 assertConvertBad("123A"); |
|
305 assertConvertBad("convertThis!"); |
|
306 |
|
307 // DD:MM |
|
308 assertConvertBad(":"); // empty |
|
309 assertConvertBad("a:11"); // Degrees illegal value |
|
310 assertConvertBad("1#:11"); // Degrees illegal value |
|
311 assertConvertBad("a1:11"); // Degrees illegal value |
|
312 assertConvertBad("+90:22"); // Degrees illegal value |
|
313 assertConvertBad("90@:22"); // Degrees illegal value |
|
314 assertConvertBad("1?2:33"); // Degrees illegal value |
|
315 assertConvertBad("-x12:44"); // Degrees illegal value |
|
316 assertConvertBad("01:10"); // starts with 0 |
|
317 assertConvertBad("011:11"); // starts with 0 |
|
318 assertConvertBad("-09:12"); // starts with -0 |
|
319 assertConvertBad("-099:19"); // starts with -0 |
|
320 assertConvertBad("180:00"); // >= 180 |
|
321 assertConvertBad("-181:01"); // < -180 |
|
322 assertConvertBad("-180:59.99999"); // < -180 |
|
323 assertConvertBad("60:0"); // Minutes < 10 does not start with 0 |
|
324 assertConvertBad("-160:1"); // Minutes < 10 does not start with 0 |
|
325 assertConvertBad("70:9.9"); // Minutes < 10 does not start with 0 |
|
326 assertConvertBad("20:300"); // Minutes > 59 |
|
327 assertConvertBad("-10:60"); // Minutes > 59 |
|
328 assertConvertBad("80:-1"); // Minutes < 0 |
|
329 assertConvertBad("90:+2"); // Minutes illegal value |
|
330 assertConvertBad("90:?2"); // Minutes illegal value |
|
331 assertConvertBad("80:33+1"); // Minutes illegal value |
|
332 assertConvertBad("90:44;5"); // Minutes illegal value |
|
333 assertConvertBad("-70:12.123456"); // Minutes too many decimals |
|
334 |
|
335 // DD:MM:SS |
|
336 assertConvertBad("::"); // empty |
|
337 assertConvertBad("b:11:11"); // Degrees illegal value |
|
338 assertConvertBad("1$:11:22"); // Degrees illegal value |
|
339 assertConvertBad("c1:11:33"); // Degrees illegal value |
|
340 assertConvertBad("*90:22:44"); // Degrees illegal value |
|
341 assertConvertBad("90!:22:55"); // Degrees illegal value |
|
342 assertConvertBad("1-2:33:01"); // Degrees illegal value |
|
343 assertConvertBad("-z12:44:02"); // Degrees illegal value |
|
344 assertConvertBad(":10:20"); // starts with : |
|
345 assertConvertBad("01:10:20"); // starts with 0 |
|
346 assertConvertBad("010:10:21"); // starts with 0 |
|
347 assertConvertBad("-09:10:22"); // starts with -0 |
|
348 assertConvertBad("-090:10:29"); // starts with -0 |
|
349 assertConvertBad("180:00:00"); // >= 180 |
|
350 assertConvertBad("280:59:59"); // >= 180 |
|
351 assertConvertBad("-181:00:00"); // < -180 |
|
352 assertConvertBad("-180:01:00"); // < -180 |
|
353 assertConvertBad("-180:00:00.001"); // < -180 |
|
354 assertConvertBad("12:3:40"); // Minutes < 10 does not start with 0 |
|
355 assertConvertBad("56:07.8:09"); // Minutes has decimals |
|
356 assertConvertBad("31:17.33:12"); // Minutes has decimals |
|
357 assertConvertBad("100:60:10"); // Minutes > 59 |
|
358 assertConvertBad("20:300:21"); // Minutes > 59 |
|
359 assertConvertBad("-10:60:01"); // Minutes > 59 |
|
360 assertConvertBad("80:-1:11"); // Minutes illegal value |
|
361 assertConvertBad("90:?2:22"); // Minutes illegal value |
|
362 assertConvertBad("80:3+:33"); // Minutes illegal value |
|
363 assertConvertBad("90:4;:44"); // Minutes illegal value |
|
364 assertConvertBad("60:10:0"); // Seconds < 10 does not start with 0 |
|
365 assertConvertBad("59:59:1"); // Seconds < 10 does not start with 0 |
|
366 assertConvertBad("69:49:9.999"); // Seconds < 10 does not start with 0 |
|
367 assertConvertBad("89:29:60"); // Seconds > 59.999 |
|
368 assertConvertBad("-90:39:60.000"); // Seconds > 59.999 |
|
369 assertConvertBad("99:19:100"); // Seconds > 59.999 |
|
370 assertConvertBad("10:10:-1"); // Seconds illegal value |
|
371 assertConvertBad("20:20:?2"); // Seconds illegal value |
|
372 assertConvertBad("-123:45.x2"); // Seconds illegal value |
|
373 assertConvertBad("30:30:3+.3"); // Seconds illegal value |
|
374 assertConvertBad("40:40:4;.4"); // Seconds illegal value |
|
375 assertConvertBad("-80:01:31..97"); // Seconds illegal value |
|
376 assertConvertBad("9:09:12.1234"); // Seconds too many decimals |
|
377 assertConvertBad("-70:30:12.3456"); // Seconds too many decimals |
|
378 } |
|
379 |
|
380 // Tests that the convert() function works. |
|
381 void testConvertFromString_DD_MM() throws Exception |
|
382 { |
|
383 setCurrentTest("testConvertFromString_DD_MM()"); |
|
384 |
|
385 // All legal values that should be equal to zero |
|
386 String[] zeroValues = { "0:00", "0:00.0", "0:00.00", "0:00.000", |
|
387 "0:00.0000", "0:00.00000", "-0:00", "-0:00.0", "-0:00.00", |
|
388 "-0:00.000", "-0:00.0000", "-0:00.00000" |
|
389 }; |
|
390 |
|
391 for (int i = 0; i < zeroValues.length; ++i) |
|
392 { |
|
393 double zero = Coordinates.convert(zeroValues[i]); |
|
394 assertTrue(zero == 0d, "Conversion failed for " + zeroValues[i] |
|
395 + ": " + zero + " != 0"); |
|
396 } |
|
397 |
|
398 // Define the input values |
|
399 String[] strings = { "-0:00.06", "-0:30.0", "-0:00.5", "-59:40.4", |
|
400 "-0:06.666", "0:39.996", "179:59.9994", "61:30.6" |
|
401 }; |
|
402 |
|
403 // Define the expected results |
|
404 double[] expecteds = { -0.0010d, -0.5d, -0.00833d, -59.6733d, -0.1111d, |
|
405 0.6666d, 179.99999d, 61.51d |
|
406 }; |
|
407 |
|
408 // Define the tolerance |
|
409 double tol = 0.001d; |
|
410 |
|
411 for (int i = 0; i < strings.length; ++i) |
|
412 { |
|
413 double result = Coordinates.convert(strings[i]); |
|
414 assertTrue(Math.abs(expecteds[i] - result) < tol, |
|
415 "Conversion failed for " + strings[i] + ": " + result |
|
416 + " != " + expecteds[i]); |
|
417 } |
|
418 } |
|
419 |
|
420 // Tests that the convert() function works. |
|
421 void testConvertFromString_DD_MM_SS() throws Exception |
|
422 { |
|
423 setCurrentTest("testConvertFromString_DD_MM_SS()"); |
|
424 |
|
425 // All legal values that should be equal to zero |
|
426 String[] zeroValues = { "0:00:00", "0:00:00.0", "0:00:00.00", |
|
427 "0:00:00.000", "-0:00:00", "-0:00:00.0", "-0:00:00.00", |
|
428 "-0:00:00.000" |
|
429 }; |
|
430 |
|
431 for (int i = 0; i < zeroValues.length; ++i) |
|
432 { |
|
433 double zero = Coordinates.convert(zeroValues[i]); |
|
434 assertTrue(zero == 0d, "Conversion failed for " + zeroValues[i] |
|
435 + ": " + zero + " != 0"); |
|
436 } |
|
437 |
|
438 // Define the input values |
|
439 String[] strings = { "-0:30:00.0", "-59:40", "-0:06:39.96", |
|
440 "0:39:59.76", "179:59:59.964", "61:30:36" |
|
441 }; |
|
442 |
|
443 // Define the expected results |
|
444 double[] expecteds = { -0.5d, -59.6667d, -0.1111d, 0.6666d, 179.99999d, |
|
445 61.51d |
|
446 }; |
|
447 |
|
448 // Define the tolerance |
|
449 double tol = 0.0001d; |
|
450 |
|
451 for (int i = 0; i < strings.length; i++) |
|
452 { |
|
453 double result = Coordinates.convert(strings[i]); |
|
454 assertTrue(Math.abs(expecteds[i] - result) < tol, |
|
455 "Conversion failed for " + strings[i] + ": " + result |
|
456 + " != " + expecteds[i]); |
|
457 } |
|
458 } |
|
459 |
|
460 // Tests that the convert() function works. |
|
461 void testConvertToStringBadArguments() |
|
462 { |
|
463 setCurrentTest("testConvertToStringBadArguments()"); |
|
464 |
|
465 double[] badCoords = { Double.NaN, Double.MAX_VALUE, -Double.MAX_VALUE, |
|
466 Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, 180.0d, |
|
467 -180.0001d, 300.99999d |
|
468 }; |
|
469 |
|
470 for (int i = 0; i < badCoords.length; ++i) |
|
471 { |
|
472 assertConvertBad(badCoords[i], Coordinates.DD_MM); |
|
473 assertConvertBad(badCoords[i], Coordinates.DD_MM_SS); |
|
474 } |
|
475 } |
|
476 |
|
477 // Tests that the convert() function works. |
|
478 void testConvertToString_DD_MM() |
|
479 { |
|
480 setCurrentTest("testConvertToString_DD_MM()"); |
|
481 |
|
482 double[] coords = { 61.51d, 57.0d, 0.6666d, -0.1111d, 179.99999d, |
|
483 30.1234567d, 1.333333d, -5.1d, -97.99d, -180.0d, 0.01d, 0.0d, |
|
484 1.000013d, 80.133602d, 1.666666666666666e-7d, 10.9833333d, |
|
485 0.999999916666667d |
|
486 }; |
|
487 |
|
488 String[] expected = { "61:30.6", "57:00.0", "0:39.996", "-0:06.666", |
|
489 "179:59.9994", "30:07.4074", "1:19.99998", "-5:06.0", |
|
490 "-97:59.4", "-180:00.0", "0:00.6", "0:00.0", "1:00.00078", |
|
491 "80:08.01612", "0:00.00001", "10:59.0", "1:00.0" |
|
492 }; |
|
493 |
|
494 for (int i = 0; i < coords.length; i++) |
|
495 { |
|
496 String result = Coordinates.convert(coords[i], Coordinates.DD_MM); |
|
497 assertTrue(expected[i].equals(result), "Conversion failed for " |
|
498 + coords[i] + " (" + result + " != " + expected[i] + ")"); |
|
499 } |
|
500 } |
|
501 |
|
502 // Tests that the convert() function works. |
|
503 void testConvertToString_DD_MM_SS() |
|
504 { |
|
505 setCurrentTest("testConvertToString_DD_MM_SS()"); |
|
506 |
|
507 double[] coords = { 61.51d, 57.0d, 0.6666d, -0.1111d, 179.99999d, |
|
508 30.1234567d, 1.333333d, -5.1d, -97.99d, -180.0d, |
|
509 7.000277777777778d, 0.01d, 0.0d, -179.000002d, -16.4d, |
|
510 2.777777777777778e-7d, 7.001111d, -8.002222d, |
|
511 0.999999916666667d |
|
512 }; |
|
513 |
|
514 String[] expected = { "61:30:36.0", "57:00:00.0", "0:39:59.76", |
|
515 "-0:06:39.96", "179:59:59.964", "30:07:24.444", "1:19:59.999", |
|
516 "-5:06:00.0", "-97:59:24.0", "-180:00:00.0", "7:00:01.0", |
|
517 "0:00:36.0", "0:00:00.0", "-179:00:00.007", "-16:24:00.0", |
|
518 "0:00:00.001", "7:00:04.0", "-8:00:07.999", "1:00:00.0" |
|
519 }; |
|
520 |
|
521 for (int i = 0; i < coords.length; i++) |
|
522 { |
|
523 String result = Coordinates |
|
524 .convert(coords[i], Coordinates.DD_MM_SS); |
|
525 assertTrue(expected[i].equals(result), "Conversion failed for " |
|
526 + coords[i] + " (" + result + " != " + expected[i] + ")"); |
|
527 } |
|
528 } |
|
529 |
|
530 void testLocationMathThreadSafe() throws InterruptedException |
|
531 { |
|
532 setCurrentTest("testLocationMathThreadSafe()"); |
|
533 ThreadSafeTester t2 = new ThreadSafeTester(); |
|
534 |
|
535 Coordinates from = new Coordinates(57.0f, 17.0f, 0f); |
|
536 Coordinates to = new Coordinates(60.0f, 21.0f, 0f); |
|
537 |
|
538 t2.start(); |
|
539 |
|
540 for (int i = 0; i < 100; i++) |
|
541 { |
|
542 float d = from.distance(to); |
|
543 float a = from.azimuthTo(to); |
|
544 checkDistanceAndAzimuth(from, to, d, a); |
|
545 } |
|
546 |
|
547 t2.join(); |
|
548 assertTrue(t2.iSuccess, "Thread t2 produced the wrong result"); |
|
549 } |
|
550 |
|
551 private class ThreadSafeTester extends Thread |
|
552 { |
|
553 boolean iSuccess = false; |
|
554 |
|
555 public void run() |
|
556 { |
|
557 Coordinates from = new Coordinates(57.0f, 17.0f, 0f); |
|
558 Coordinates to = new Coordinates(56.0f, 17.0f, 0f); |
|
559 for (int i = 0; i < 100; i++) |
|
560 { |
|
561 float d = from.distance(to); |
|
562 float a = from.azimuthTo(to); |
|
563 checkDistanceAndAzimuth(from, to, d, a); |
|
564 } |
|
565 iSuccess = true; |
|
566 } |
|
567 } |
|
568 |
|
569 // Also used in QualifiedCoordinatesTest |
|
570 protected Coordinates newCoordinates() |
|
571 { |
|
572 return new Coordinates(iLat, iLon, iAlt); |
|
573 } |
|
574 |
|
575 // Also used in QualifiedCoordinatesTest |
|
576 protected Coordinates newZeroCoordinates() |
|
577 { |
|
578 return new Coordinates(0, 0, 0); |
|
579 } |
|
580 |
|
581 //------------------------ Helper methods ----------------------- |
|
582 |
|
583 private void assertReallyGood(double lat, double lon, float alt) |
|
584 { |
|
585 assertGood(lat, lon, alt); |
|
586 assertGood(-lat, lon, alt); |
|
587 assertGood(lat, -lon, alt); |
|
588 assertGood(lat, lon, -alt); |
|
589 assertGood(-lat, lon, -alt); |
|
590 assertGood(lat, -lon, -alt); |
|
591 assertGood(-lat, -lon, -alt); |
|
592 } |
|
593 |
|
594 protected void assertGood(double aLat, double aLon, float aAlt) |
|
595 { |
|
596 // Test constructor |
|
597 iLat = aLat; |
|
598 iLon = aLon; |
|
599 iAlt = aAlt; |
|
600 Coordinates coords = newCoordinates(); |
|
601 |
|
602 assertTrue(coords.getLatitude() == aLat |
|
603 && coords.getLongitude() == aLon |
|
604 && (Float.isNaN(aAlt) ^ coords.getAltitude() == aAlt), |
|
605 "Coordinates values not equal to constructor input (" + aLat |
|
606 + "," + aLon + "," + aAlt + ")"); |
|
607 |
|
608 // Test setters |
|
609 coords = newZeroCoordinates(); |
|
610 |
|
611 try |
|
612 { |
|
613 coords.setLatitude(aLat); |
|
614 } |
|
615 catch (IllegalArgumentException iae) |
|
616 { |
|
617 assertTrue(false, "setLatitude(" + aLat + ") failed"); |
|
618 } |
|
619 |
|
620 try |
|
621 { |
|
622 coords.setLongitude(aLon); |
|
623 } |
|
624 catch (IllegalArgumentException iae) |
|
625 { |
|
626 assertTrue(false, "setLongitude(" + aLon + ") failed"); |
|
627 } |
|
628 |
|
629 try |
|
630 { |
|
631 coords.setAltitude(aAlt); |
|
632 } |
|
633 catch (IllegalArgumentException iae) |
|
634 { |
|
635 assertTrue(false, "setAtitude(" + aAlt + ") failed"); |
|
636 } |
|
637 |
|
638 assertTrue(coords.getLatitude() == aLat |
|
639 && coords.getLongitude() == aLon |
|
640 && (Float.isNaN(aAlt) ^ coords.getAltitude() == aAlt), |
|
641 "Coordinates values not equal to set values (" + aLat + "," |
|
642 + aLon + "," + aAlt + ")"); |
|
643 } |
|
644 |
|
645 protected void assertBad(double aLat, double aLon, float aAlt) |
|
646 { |
|
647 // Test constructor |
|
648 try |
|
649 { |
|
650 iLat = aLat; |
|
651 iLon = aLon; |
|
652 iAlt = aAlt; |
|
653 Coordinates coords = newCoordinates(); |
|
654 |
|
655 assertTrue(false, "No exception thrown for constructor (" + aLat |
|
656 + ", " + aLon + ", " + aAlt + ")"); |
|
657 } |
|
658 catch (IllegalArgumentException iae) |
|
659 { |
|
660 // Exception was thrown correctly |
|
661 assertTrue(iae.getMessage() == null, "Message not allowed for " |
|
662 + iae); |
|
663 } |
|
664 |
|
665 // Test setters |
|
666 Coordinates coords = newZeroCoordinates(); |
|
667 |
|
668 try |
|
669 { |
|
670 coords.setLatitude(aLat); |
|
671 coords.setLongitude(aLon); |
|
672 assertTrue(false, "IllegalArgumentException not thrown for setter"); |
|
673 } |
|
674 catch (IllegalArgumentException iae) |
|
675 { |
|
676 // Exception was thrown correctly |
|
677 assertTrue(iae.getMessage() == null, "Message not allowed for " |
|
678 + iae); |
|
679 } |
|
680 |
|
681 // setAltitude should never throw exception |
|
682 coords.setAltitude(aAlt); |
|
683 } |
|
684 |
|
685 private void checkDistanceAndAzimuth(Coordinates aFrom, Coordinates aTo, |
|
686 float aExpectedDistance, float aExpectedAzimuth) |
|
687 { |
|
688 // Define the tolerance |
|
689 float distTol = 0.0035f; // Relative error |
|
690 float azTol = 1f; // Absolute error |
|
691 |
|
692 float distance = aFrom.distance(aTo); |
|
693 if (aExpectedDistance != 0.0f) |
|
694 { |
|
695 float distErr = Math.abs((distance - aExpectedDistance) |
|
696 / aExpectedDistance); |
|
697 |
|
698 assertTrue(distErr <= distTol, "Computed distance " + distance |
|
699 + " != " + aExpectedDistance); |
|
700 } |
|
701 else |
|
702 { |
|
703 assertTrue(distance == 0.0f, "Computed distance " + distance |
|
704 + " != 0.0"); |
|
705 } |
|
706 |
|
707 float azimuth = aFrom.azimuthTo(aTo); |
|
708 if (aExpectedAzimuth != 0.0f) |
|
709 { |
|
710 assertTrue(Math.abs(azimuth - aExpectedAzimuth) <= azTol, |
|
711 "Computed bearing " + azimuth + " != " + aExpectedAzimuth); |
|
712 } |
|
713 else |
|
714 { |
|
715 assertTrue(azimuth == 0.0f, "Computed bearing " + azimuth |
|
716 + " != 0.0"); |
|
717 } |
|
718 } |
|
719 |
|
720 private void assertConvertBad(String aString) |
|
721 { |
|
722 try |
|
723 { |
|
724 double result = Coordinates.convert(aString); |
|
725 assertTrue(false, "No exception thrown for convert(" + aString |
|
726 + ")"); |
|
727 } |
|
728 catch (IllegalArgumentException iae) |
|
729 { |
|
730 // Exception was thrown correctly |
|
731 assertTrue(iae.getMessage() == null, "Message not allowed for " |
|
732 + iae); |
|
733 } |
|
734 } |
|
735 |
|
736 private void assertConvertBad(double aCoord, int aFormat) |
|
737 { |
|
738 try |
|
739 { |
|
740 String result = Coordinates.convert(aCoord, aFormat); |
|
741 assertTrue(false, "IllegalArgumentException was never thrown"); |
|
742 } |
|
743 catch (IllegalArgumentException iae) |
|
744 { |
|
745 // Exception thrown correctly |
|
746 assertTrue(iae.getMessage() == null, "Message not allowed for " |
|
747 + iae); |
|
748 } |
|
749 } |
|
750 } |
|