parent
9160516b28
commit
e1634f66bb
|
@ -81,10 +81,12 @@ public enum GeoDistance {
|
|||
public double calculate(double sourceLatitude, double sourceLongitude, double targetLatitude, double targetLongitude, DistanceUnit unit) {
|
||||
double x1 = sourceLatitude * Math.PI / 180D;
|
||||
double x2 = targetLatitude * Math.PI / 180D;
|
||||
double h1 = (1D - Math.cos(x1 - x2)) / 2D;
|
||||
double h2 = (1D - Math.cos((sourceLongitude - targetLongitude) * Math.PI / 180D)) / 2D;
|
||||
double h = h1 + Math.cos(x1) * Math.cos(x2) * h2;
|
||||
return unit.fromMeters(GeoUtils.EARTH_MEAN_RADIUS * 2D * Math.asin(Math.min(1, Math.sqrt(h))));
|
||||
double h1 = 1D - Math.cos(x1 - x2);
|
||||
double h2 = 1D - Math.cos((sourceLongitude - targetLongitude) * Math.PI / 180D);
|
||||
double h = (h1 + Math.cos(x1) * Math.cos(x2) * h2) / 2;
|
||||
double averageLatitude = (x1 + x2) / 2;
|
||||
double diameter = GeoUtils.earthDiameter(averageLatitude);
|
||||
return unit.fromMeters(diameter * Math.asin(Math.min(1, Math.sqrt(h))));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.elasticsearch.common.geo;
|
|||
|
||||
import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
|
||||
import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
|
||||
import org.apache.lucene.util.SloppyMath;
|
||||
import org.elasticsearch.common.unit.DistanceUnit;
|
||||
|
||||
/**
|
||||
|
@ -45,6 +46,14 @@ public class GeoUtils {
|
|||
/** Earth ellipsoid polar distance in meters */
|
||||
public static final double EARTH_POLAR_DISTANCE = Math.PI * EARTH_SEMI_MINOR_AXIS;
|
||||
|
||||
/**
|
||||
* Return an approximate value of the diameter of the earth (in meters) at the given latitude (in radians).
|
||||
*/
|
||||
public static double earthDiameter(double latitude) {
|
||||
// SloppyMath impl returns a result in kilometers
|
||||
return SloppyMath.earthDiameter(latitude) * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the width (in meters) of geohash cells at a specific level
|
||||
* @param level geohash level must be greater or equal to zero
|
||||
|
|
|
@ -44,12 +44,6 @@ public class SloppyMathTests extends ElasticsearchTestCase {
|
|||
|
||||
@Test
|
||||
public void testSloppyMath() {
|
||||
assertThat(GeoDistance.SLOPPY_ARC.calculate(-46.645, -171.057, -46.644, -171.058, DistanceUnit.METERS), closeTo(134.87709, maxError(134.87709)));
|
||||
assertThat(GeoDistance.SLOPPY_ARC.calculate(-77.912, -81.173, -77.912, -81.171, DistanceUnit.METERS), closeTo(46.57161, maxError(46.57161)));
|
||||
assertThat(GeoDistance.SLOPPY_ARC.calculate(65.75, -20.708, 65.75, -20.709, DistanceUnit.METERS), closeTo(45.66996, maxError(45.66996)));
|
||||
assertThat(GeoDistance.SLOPPY_ARC.calculate(-86.9, 53.738, -86.9, 53.741, DistanceUnit.METERS), closeTo(18.03998, maxError(18.03998)));
|
||||
assertThat(GeoDistance.SLOPPY_ARC.calculate(89.041, 115.93, 89.04, 115.946, DistanceUnit.METERS), closeTo(115.11711, maxError(115.11711)));
|
||||
|
||||
testSloppyMath(DistanceUnit.METERS, 0.01, 5, 45, 90);
|
||||
testSloppyMath(DistanceUnit.KILOMETERS, 0.01, 5, 45, 90);
|
||||
testSloppyMath(DistanceUnit.INCH, 0.01, 5, 45, 90);
|
||||
|
|
Loading…
Reference in New Issue