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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 package org.apache.lucene.spatial.geometry;
22 * Abstract base lat-lng class which can manipulate fixed point or floating
23 * point based coordinates. Instances are immutable.
27 * <p><font color="red"><b>NOTE:</b> This API is still in
28 * flux and might change in incompatible ways in the next
31 public abstract class LatLng {
33 public abstract boolean isNormalized();
35 public abstract boolean isFixedPoint();
37 public abstract LatLng normalize();
39 public abstract int getFixedLat();
41 public abstract int getFixedLng();
43 public abstract double getLat();
45 public abstract double getLng();
47 public abstract LatLng copy();
49 public abstract FixedLatLng toFixed();
51 public abstract FloatLatLng toFloat();
54 * Convert the lat/lng into the cartesian coordinate plane such that all
55 * world coordinates are represented in the first quadrant.
56 * The x dimension corresponds to latitude and y corresponds to longitude.
57 * The translation starts with the normalized latlng and adds 180 to the latitude and
58 * 90 to the longitude (subject to fixed point scaling).
60 public CartesianPoint toCartesian() {
61 LatLng ll=normalize();
63 int lat=ll.getFixedLat();
64 int lng=ll.getFixedLng();
66 return new CartesianPoint(
67 lng+180*FixedLatLng.SCALE_FACTOR_INT,
68 lat+90*FixedLatLng.SCALE_FACTOR_INT
73 * The inverse of toCartesian(). Always returns a FixedLatLng.
76 public static LatLng fromCartesian(CartesianPoint pt) {
77 int lat=pt.getY() - 90 * FixedLatLng.SCALE_FACTOR_INT;
78 int lng=pt.getX() - 180 * FixedLatLng.SCALE_FACTOR_INT;
80 return new FixedLatLng(lat, lng);
84 * Calculates the distance between two lat/lng's in miles.
85 * Imported from mq java client.
88 * Second lat,lng position to calculate distance to.
90 * @return Returns the distance in miles.
92 public double arcDistance(LatLng ll2) {
93 return arcDistance(ll2, DistanceUnits.MILES);
97 * Calculates the distance between two lat/lng's in miles or meters.
98 * Imported from mq java client. Variable references changed to match.
101 * Second lat,lng position to calculate distance to.
103 * Units to calculate distance, defaults to miles
105 * @return Returns the distance in meters or miles.
107 public double arcDistance(LatLng ll2, DistanceUnits lUnits) {
108 LatLng ll1 = normalize();
109 ll2 = ll2.normalize();
111 double lat1 = ll1.getLat(), lng1 = ll1.getLng();
112 double lat2 = ll2.getLat(), lng2 = ll2.getLng();
114 // Check for same position
115 if (lat1 == lat2 && lng1 == lng2)
118 // Get the m_dLongitude difference. Don't need to worry about
119 // crossing 180 since cos(x) = cos(-x)
120 double dLon = lng2 - lng1;
122 double a = radians(90.0 - lat1);
123 double c = radians(90.0 - lat2);
124 double cosB = (Math.cos(a) * Math.cos(c))
125 + (Math.sin(a) * Math.sin(c) * Math.cos(radians(dLon)));
127 double radius = (lUnits == DistanceUnits.MILES) ? 3963.205/* MILERADIUSOFEARTH */
128 : 6378.160187/* KMRADIUSOFEARTH */;
130 // Find angle subtended (with some bounds checking) in radians and
131 // multiply by earth radius to find the arc distance
133 return 3.14159265358979323846/* PI */* radius;
134 else if (cosB >= 1.0)
137 return Math.acos(cosB) * radius;
140 private double radians(double a) {
141 return a * 0.01745329251994;
145 public String toString() {
146 return "[" + getLat() + "," + getLng() + "]";
150 * Calculate the midpoint between this point an another. Respects fixed vs floating point
153 public abstract LatLng calculateMidpoint(LatLng other);
156 public abstract int hashCode();
159 public abstract boolean equals(Object obj);