pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / spatial / src / test / org / apache / lucene / spatial / DistanceUtilsTest.java
1 package org.apache.lucene.spatial;
2
3 import junit.framework.TestCase;
4 import org.apache.lucene.spatial.tier.InvalidGeoException;
5
6
7 /**
8  * Licensed to the Apache Software Foundation (ASF) under one or more
9  * contributor license agreements.  See the NOTICE file distributed with
10  * this work for additional information regarding copyright ownership.
11  * The ASF licenses this file to You under the Apache License, Version 2.0
12  * (the "License"); you may not use this file except in compliance with
13  * the License.  You may obtain a copy of the License at
14  *
15  *     http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23
24
25 /**
26  *
27  *
28  **/
29 public class DistanceUtilsTest extends TestCase {
30
31   public void testBoxCorner() throws Exception {
32     double[] zero = new double[]{0, 0};
33     double[] zeroOne = new double[]{0, 1};
34     double[] oneOne = new double[]{1, 1};
35     double[] pt1 = new double[]{1.5, 110.3};
36     double[] result = DistanceUtils.vectorBoxCorner(zero, null, Math.sqrt(2), true);
37     assertEquals(1.0, result[0], 0);
38     assertEquals(1.0, result[1], 0);
39
40     result = DistanceUtils.vectorBoxCorner(zero, null, Math.sqrt(2), false);
41     assertEquals(-1.0, result[0], 0);
42     assertEquals(-1.0, result[1], 0);
43
44     result = DistanceUtils.vectorBoxCorner(oneOne, null, Math.sqrt(2), true);
45     assertEquals(2.0, result[0], 0);
46     assertEquals(2.0, result[1], 0);
47
48     result = DistanceUtils.vectorBoxCorner(zeroOne, null, Math.sqrt(2), true);
49     assertEquals(1.0, result[0], 0);
50     assertEquals(2.0, result[1], 0);
51
52     result = DistanceUtils.vectorBoxCorner(pt1, null, Math.sqrt(2), true);
53     assertEquals(2.5, result[0], 0.1);
54     assertEquals(111.3, result[1], 0.1);
55
56     result = DistanceUtils.vectorBoxCorner(pt1, null, Math.sqrt(2), false);
57     assertEquals(0.5, result[0], 0.1);
58     assertEquals(109.3, result[1], 0.1);
59
60   }
61
62   public void testNormLatLon() throws Exception {
63
64   }
65
66   public void testLatLonCorner() throws Exception {
67     double[] zero = new double[]{0, 0};
68     double[] zero45 = new double[]{0, DistanceUtils.DEG_45_AS_RADS};
69     double[] result;
70     //  00°38′09″N, 000°38′09″E
71     //Verify at http://www.movable-type.co.uk/scripts/latlong.html
72     result = DistanceUtils.latLonCorner(zero[0], zero[1], 100, null, true, DistanceUtils.EARTH_MEAN_RADIUS_KM);
73     assertEquals(0.63583 * DistanceUtils.DEGREES_TO_RADIANS, result[0], 0.001);
74     assertEquals(0.63583 * DistanceUtils.DEGREES_TO_RADIANS, result[1], 0.001);
75
76     result = DistanceUtils.latLonCornerDegs(zero[0], zero[1], 100, null, true, DistanceUtils.EARTH_MEAN_RADIUS_KM);
77     //  00°38′09″N, 000°38′09″E
78     assertEquals(0.63583, result[0], 0.001);
79     assertEquals(0.63583, result[1], 0.001);
80
81     result = DistanceUtils.latLonCornerDegs(zero[0], zero[1], 100, null, false, DistanceUtils.EARTH_MEAN_RADIUS_KM);
82     //  00°38′09″N, 000°38′09″E
83     assertEquals(-0.63583, result[0], 0.001);
84     assertEquals(-0.63583, result[1], 0.001);
85
86     //test some edge cases
87     //89°16′02″N, 060°12′35″E
88     result = DistanceUtils.latLonCornerDegs(89.0, 0, 100, null, true, DistanceUtils.EARTH_MEAN_RADIUS_KM);
89     assertEquals(89.26722, result[0], 0.001);
90     assertEquals(60.20972, result[1], 0.001);
91
92     result = DistanceUtils.latLonCornerDegs(0, -179.0, 100, null, true, DistanceUtils.EARTH_MEAN_RADIUS_KM);
93     assertEquals(0.63583, result[0], 0.001);
94     assertEquals(-178.36417, result[1], 0.001);
95
96   }
97
98   public void testPointBearing() throws Exception {
99     double[] zero = new double[]{0, 0};
100     double[] zero45 = new double[]{40 * DistanceUtils.DEGREES_TO_RADIANS, DistanceUtils.DEG_45_AS_RADS};
101     double[] result;
102     //  00°38′09″N, 000°38′09″E
103     //Verify at http://www.movable-type.co.uk/scripts/latlong.html
104     result = DistanceUtils.pointOnBearing(zero[0], zero[1], 100, DistanceUtils.DEG_45_AS_RADS, null, DistanceUtils.EARTH_MEAN_RADIUS_KM);
105     assertEquals(0.63583 * DistanceUtils.DEGREES_TO_RADIANS, result[0], 0.001);
106     assertEquals(0.63583 * DistanceUtils.DEGREES_TO_RADIANS, result[1], 0.001);
107
108     //should be above the current point at 0.8994°,0.0000°
109     result = DistanceUtils.pointOnBearing(zero[0], zero[1], 100, 0, null, DistanceUtils.EARTH_MEAN_RADIUS_KM);
110     assertEquals(0.8994 * DistanceUtils.DEGREES_TO_RADIANS, result[0], 0.001);
111     assertEquals(0, result[1], 0.001);
112     //directly below
113     result = DistanceUtils.pointOnBearing(zero[0], zero[1], 100, DistanceUtils.DEG_180_AS_RADS, null, DistanceUtils.EARTH_MEAN_RADIUS_KM);
114     assertEquals(-0.8994 * DistanceUtils.DEGREES_TO_RADIANS, result[0], 0.001);
115     assertEquals(0, result[1], 0.001);
116     //0.7183°,0.5414° -- 37 deg bearing
117     result = DistanceUtils.pointOnBearing(zero[0], zero[1], 100, 37 * DistanceUtils.DEGREES_TO_RADIANS, null, DistanceUtils.EARTH_MEAN_RADIUS_KM);
118     assertEquals(0.7183 * DistanceUtils.DEGREES_TO_RADIANS, result[0], 0.001);
119     assertEquals(0.5414 * DistanceUtils.DEGREES_TO_RADIANS, result[1], 0.001);
120
121     result = DistanceUtils.pointOnBearing(zero45[0], zero45[1], 100, DistanceUtils.DEG_45_AS_RADS, null, DistanceUtils.EARTH_MEAN_RADIUS_KM);
122     //40.6328°,45.8381°
123     assertEquals(40.6328 * DistanceUtils.DEGREES_TO_RADIANS, result[0], 0.001);
124     assertEquals(45.8381 * DistanceUtils.DEGREES_TO_RADIANS, result[1], 0.001);
125
126     result = DistanceUtils.pointOnBearing(1 * DistanceUtils.DEGREES_TO_RADIANS, 1 * DistanceUtils.DEGREES_TO_RADIANS, 100, DistanceUtils.DEG_90_AS_RADS, null, DistanceUtils.EARTH_MEAN_RADIUS_KM);
127     //0.9997°,1.8994°
128     assertEquals(0.9997 * DistanceUtils.DEGREES_TO_RADIANS, result[0], 0.001);
129     assertEquals(1.8994 * DistanceUtils.DEGREES_TO_RADIANS, result[1], 0.001);
130
131     result = DistanceUtils.pointOnBearing(-10 * DistanceUtils.DEGREES_TO_RADIANS, -150 * DistanceUtils.DEGREES_TO_RADIANS, 15, 205*DistanceUtils.DEGREES_TO_RADIANS, null, DistanceUtils.EARTH_MEAN_RADIUS_KM);
132     //-10.1222°,-150.0578°
133     assertEquals(-10.1222 * DistanceUtils.DEGREES_TO_RADIANS, result[0], 0.001);
134     assertEquals(-150.0578 * DistanceUtils.DEGREES_TO_RADIANS, result[1], 0.001);
135
136     result = DistanceUtils.pointOnBearing(-10 * DistanceUtils.DEGREES_TO_RADIANS, -150 * DistanceUtils.DEGREES_TO_RADIANS, 200, 63*DistanceUtils.DEGREES_TO_RADIANS, null, DistanceUtils.EARTH_MEAN_RADIUS_KM);
137     //-9.1797°,-148.3767°
138     assertEquals(-9.1797 * DistanceUtils.DEGREES_TO_RADIANS, result[0], 0.001);
139     assertEquals(-148.3767 * DistanceUtils.DEGREES_TO_RADIANS, result[1], 0.001);
140
141     result = DistanceUtils.pointOnBearing(-10 * DistanceUtils.DEGREES_TO_RADIANS, -150 * DistanceUtils.DEGREES_TO_RADIANS, 3000, 63*DistanceUtils.DEGREES_TO_RADIANS, null, DistanceUtils.EARTH_MEAN_RADIUS_KM);
142     //2.7561°,-126.1281°
143     assertEquals(2.7561 * DistanceUtils.DEGREES_TO_RADIANS, result[0], 0.001);
144     assertEquals(-126.1281 * DistanceUtils.DEGREES_TO_RADIANS, result[1], 0.001);
145
146   }
147
148   public void testVectorDistance() throws Exception {
149     double[] zero = new double[]{0, 0};
150
151     double[] zeroOne = new double[]{0, 1};
152     double[] oneZero = new double[]{1, 0};
153     double[] oneOne = new double[]{1, 1};
154     double distance;
155     distance = DistanceUtils.vectorDistance(zero, zeroOne, 2);
156     assertEquals(1.0, distance, 0);
157     distance = DistanceUtils.vectorDistance(zero, oneZero, 2);
158     assertEquals(1.0, distance, 0);
159     distance = DistanceUtils.vectorDistance(zero, oneOne, 2);
160     assertEquals(Math.sqrt(2), distance, 0.001);
161
162     distance = DistanceUtils.squaredEuclideanDistance(zero, oneOne);
163     assertEquals(2, distance, 0.001);
164   }
165
166   public void testHaversine() throws Exception {
167     double distance;
168     //compare to http://www.movable-type.co.uk/scripts/latlong.html
169     distance = DistanceUtils.haversine(0, 0, Math.PI / 4.0, Math.PI / 4.0, DistanceUtils.EARTH_MEAN_RADIUS_KM);
170     assertEquals(6672.0, distance, 0.5);
171
172     distance = DistanceUtils.haversine(0, 0, Math.toRadians(20), Math.toRadians(20), DistanceUtils.EARTH_MEAN_RADIUS_KM);
173     assertEquals(3112, distance, 0.5);
174
175     distance = DistanceUtils.haversine(0, 0, Math.toRadians(1), Math.toRadians(1), DistanceUtils.EARTH_MEAN_RADIUS_KM);
176     assertEquals(157.2, distance, 0.5);
177
178     //Try some around stuff
179     distance = DistanceUtils.haversine(Math.toRadians(1), Math.toRadians(-1),
180             Math.toRadians(1), Math.toRadians(1), DistanceUtils.EARTH_MEAN_RADIUS_KM);
181     assertEquals(222.4, distance, 0.5);
182
183     distance = DistanceUtils.haversine(Math.toRadians(89), Math.toRadians(-1),
184             Math.toRadians(89), Math.toRadians(179), DistanceUtils.EARTH_MEAN_RADIUS_KM);
185     assertEquals(222.4, distance, 0.5);
186
187     distance = DistanceUtils.haversine(Math.toRadians(89), Math.toRadians(-1),
188             Math.toRadians(49), Math.toRadians(179), DistanceUtils.EARTH_MEAN_RADIUS_KM);
189     assertEquals(4670, distance, 0.5);
190
191     distance = DistanceUtils.haversine(Math.toRadians(0), Math.toRadians(-179),
192             Math.toRadians(0), Math.toRadians(179), DistanceUtils.EARTH_MEAN_RADIUS_KM);
193     assertEquals(222.4, distance, 0.5);
194
195   }
196
197   public void testParse() throws Exception {
198     String[] parse;
199     parse = DistanceUtils.parsePoint(null, "89.0,73.2", 2);
200     assertEquals(2, parse.length);
201     assertEquals("89.0", parse[0]);
202     assertEquals("73.2", parse[1]);
203
204     parse = DistanceUtils.parsePoint(null, "89.0,73.2,-92.3", 3);
205     assertEquals(3, parse.length);
206     assertEquals("89.0", parse[0]);
207     assertEquals("73.2", parse[1]);
208     assertEquals("-92.3", parse[2]);
209
210     parse = DistanceUtils.parsePoint(null, "    89.0         ,   73.2  ,              -92.3   ", 3);
211     assertEquals(3, parse.length);
212     assertEquals("89.0", parse[0]);
213     assertEquals("73.2", parse[1]);
214     assertEquals("-92.3", parse[2]);
215
216
217     String[] foo = DistanceUtils.parsePoint(parse, "89.0         ,   73.2 ,              -92.3", 3);
218     //should be same piece of memory
219     assertTrue(foo == parse);
220     assertEquals(3, parse.length);
221     assertEquals("89.0", parse[0]);
222     assertEquals("73.2", parse[1]);
223     assertEquals("-92.3", parse[2]);
224     //array should get automatically resized
225     parse = DistanceUtils.parsePoint(new String[1], "89.0         ,   73.2 ,              -92.3", 3);
226     assertEquals(3, parse.length);
227     assertEquals("89.0", parse[0]);
228     assertEquals("73.2", parse[1]);
229     assertEquals("-92.3", parse[2]);
230
231
232     try {
233       parse = DistanceUtils.parsePoint(null, "89.0         ,   ", 3);
234       assertTrue(false);
235     } catch (InvalidGeoException e) {
236     }
237     try {
238       parse = DistanceUtils.parsePoint(null, " , 89.0          ", 3);
239       assertTrue(false);
240     } catch (InvalidGeoException e) {
241     }
242
243     try {
244       parse = DistanceUtils.parsePoint(null, "", 3);
245       assertTrue(false);
246     } catch (InvalidGeoException e) {
247     }
248
249
250     double[] dbls = DistanceUtils.parsePointDouble(null, "89.0         ,   73.2 ,              -92.3", 3);
251     assertEquals(3, dbls.length);
252     assertEquals(89.0, dbls[0], 0);
253     assertEquals(73.2, dbls[1], 0.1);
254     assertEquals(-92.3, dbls[2], 0.1);
255
256     try {
257       dbls = DistanceUtils.parsePointDouble(null, "89.0         ,   foo ,              -92.3", 3);
258       assertTrue(false);
259     } catch (NumberFormatException e) {
260     }
261
262     dbls = DistanceUtils.parseLatitudeLongitude(null, "89.0         ,   73.2    ");
263     assertEquals(2, dbls.length);
264     assertEquals(89.0, dbls[0], 0.1);
265     assertEquals(73.2, dbls[1], 0.1);
266
267     //test some bad lat/long pairs
268     try {
269       dbls = DistanceUtils.parseLatitudeLongitude(null, "189.0         ,   73.2    ");
270       assertTrue(false);
271     } catch (InvalidGeoException e) {
272
273     }
274
275     try {
276       dbls = DistanceUtils.parseLatitudeLongitude(null, "89.0         ,   273.2    ");
277       assertTrue(false);
278     } catch (InvalidGeoException e) {
279
280     }
281
282   }
283
284 }