add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / spatial / src / java / org / apache / lucene / spatial / geometry / shape / DistanceApproximation.java
1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 package org.apache.lucene.spatial.geometry.shape;
19
20 /**
21  * Imported from mq java client.  No changes made.
22  *
23  * <p><font color="red"><b>NOTE:</b> This API is still in
24  * flux and might change in incompatible ways in the next
25  * release.</font>
26  *
27  * @deprecated This has been replaced with more accurate
28  * math in {@link LLRect}. This class will be removed in a future release.
29  */
30 @Deprecated
31 public class DistanceApproximation
32 {
33   private double m_testLat;
34   private double m_testLng;
35   private double m_mpd;
36   private static final double m_milesPerLngDeg[]={
37      69.170976f, 69.160441f, 69.128838f, 69.076177f, 69.002475f,
38      68.907753f, 68.792041f, 68.655373f, 68.497792f, 68.319345f,
39      68.120088f, 67.900079f, 67.659387f, 67.398085f, 67.116253f,
40      66.813976f, 66.491346f, 66.148462f, 65.785428f, 65.402355f,
41      64.999359f, 64.576564f, 64.134098f, 63.672096f, 63.190698f,
42      62.690052f, 62.170310f, 61.631630f, 61.074176f, 60.498118f,
43      59.903632f, 59.290899f, 58.660106f, 58.011443f, 57.345111f,
44      56.661310f, 55.960250f, 55.242144f, 54.507211f, 53.755675f,
45      52.987764f, 52.203713f, 51.403761f, 50.588151f, 49.757131f,
46      48.910956f, 48.049882f, 47.174172f, 46.284093f, 45.379915f,
47      44.461915f, 43.530372f, 42.585570f, 41.627796f, 40.657342f,
48      39.674504f, 38.679582f, 37.672877f, 36.654698f, 35.625354f,
49      34.585159f, 33.534429f, 32.473485f, 31.402650f, 30.322249f,
50      29.232613f, 28.134073f, 27.026963f, 25.911621f, 24.788387f,
51      23.657602f, 22.519612f, 21.374762f, 20.223401f, 19.065881f,
52      17.902554f, 16.733774f, 15.559897f, 14.381280f, 13.198283f,
53      12.011266f, 10.820591f,  9.626619f,  8.429716f,  7.230245f,
54       6.028572f,  4.825062f,  3.620083f,  2.414002f,  1.207185f,
55       1.000000f};
56
57   public static final double MILES_PER_LATITUDE   = 69.170976f;
58   public static final double KILOMETERS_PER_MILE  = 1.609347f;
59
60
61   public DistanceApproximation()
62   {
63   }
64
65   public void setTestPoint(double lat, double lng)
66   {
67     m_testLat = lat;
68     m_testLng = lng;
69     m_mpd     = m_milesPerLngDeg[(int)(Math.abs(lat) + 0.5f)];
70   }
71
72   // Approximate arc distance between 2 lat,lng positions using miles per
73   //    latitude and longitude degree
74   public double getDistanceSq(double lat, double lng)
75   {
76     double latMiles = (lat - m_testLat) * MILES_PER_LATITUDE;
77
78     // Approximate longitude miles using the miles per degree assuming the
79     //    middle latitude/longitude.  This is less accurate at high (near
80     //    polar) latitudes but no road network is present at the poles!
81     //    If we ever have any roads crossing the international date we will
82     //    have to worry about that case.
83     double lngMiles = (lng - m_testLng) * m_mpd;
84
85      // Find the squared distance by the Pythagorean theorem (without sqrt)
86     return (latMiles * latMiles + lngMiles * lngMiles);
87   }
88
89   // Approximate arc distance between a segment (with lat,lng endpoints) and
90   //    the test position
91   public double getDistanceSq(double lat1, double lng1, double lat2, double lng2)
92   {
93      // Check if lat1,lng1 is closest point.  Construct a vector from point1
94      //    to point2 (v1) and another from point 1 to the test point (v2).
95      //    If dot product is negative then point 1 is the closest point
96      double v1y = lat2 - lat1;
97      double v1x = lng2 - lng1;
98      double v2y = m_testLat - lat1;
99      double v2x = m_testLng - lng1;
100      double dot = v1x * v2x + v1y * v2y;
101      if (dot <= 0.0f)
102         return getDistanceSq(lat1, lng1);
103
104      // Get the component of vector v2 along v1.  If component is greater
105      //    than 1 then the endpoint is the closest point.
106      double c = dot / (v1x * v1x + v1y * v1y);
107      if (c >= 1.0f)
108         return getDistanceSq(lat2, lng2);
109
110      // Since we are working io lat,lng space we need to find the point
111      //    along p1->p2 such that q->pt is perpendicular to p1->p2.  We
112      //    then find the distance squared between Q and pt.
113      return getDistanceSq((lat1 + v1y * c), (lng1 + v1x * c));
114   }
115
116   // Return the number of miles per degree of longitude
117   public static double getMilesPerLngDeg(double lat)
118   {
119      return (Math.abs(lat) <= 90.0) ? m_milesPerLngDeg[(int)(Math.abs(lat) + 0.5f)] : 69.170976f;
120   }
121   
122   public static double getMilesPerLatDeg() {
123     return MILES_PER_LATITUDE;
124   }
125 }
126