Skip to content

Commit

Permalink
Added DistanceUtils.DEG_TO_KM and KM_TO_DEG convenience constants.
Browse files Browse the repository at this point in the history
  • Loading branch information
dsmiley committed Sep 5, 2012
1 parent 054ee2f commit 3b17c0d
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 50 deletions.
21 changes: 0 additions & 21 deletions pom.xml
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -123,20 +123,6 @@
<forkMode>never</forkMode> <forkMode>never</forkMode>
</configuration> </configuration>
</plugin> </plugin>

<!-- so that the source jar gets deployed -->
<!--<plugin>-->
<!--<groupId>org.apache.maven.plugins</groupId>-->
<!--<artifactId>maven-source-plugin</artifactId>-->
<!--<version>2.2</version>-->
<!--<executions>-->
<!--<execution>-->
<!--<goals>-->
<!--<goal>jar</goal>-->
<!--</goals>-->
<!--</execution>-->
<!--</executions>-->
<!--</plugin>-->


</plugins> </plugins>


Expand Down Expand Up @@ -193,11 +179,4 @@
</plugins> </plugins>
</reporting> </reporting>


<distributionManagement>
<site>
<id>github-project-site</id>
<url>gitsite:git@github.com/spatial4j/spatial4j.git</url>
</site>
</distributionManagement>

</project> </project>
11 changes: 6 additions & 5 deletions src/main/java/com/spatial4j/core/distance/DistanceUtils.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
public class DistanceUtils { public class DistanceUtils {


//pre-compute some angles that are commonly used //pre-compute some angles that are commonly used
public static final double DEG_45_AS_RADS = Math.PI / 4.0; public static final double DEG_45_AS_RADS = Math.PI / 4;
public static final double SIN_45_AS_RADS = Math.sin(DEG_45_AS_RADS); public static final double SIN_45_AS_RADS = Math.sin(DEG_45_AS_RADS);
public static final double DEG_90_AS_RADS = Math.PI / 2; public static final double DEG_90_AS_RADS = Math.PI / 2;
public static final double DEG_180_AS_RADS = Math.PI; public static final double DEG_180_AS_RADS = Math.PI;
public static final double DEG_225_AS_RADS = 5 * DEG_45_AS_RADS; public static final double DEG_225_AS_RADS = 5 * DEG_45_AS_RADS;
public static final double DEG_270_AS_RADS = 3 * DEG_90_AS_RADS; public static final double DEG_270_AS_RADS = 3 * DEG_90_AS_RADS;


public static final double DEGREES_TO_RADIANS = Math.PI / 180.0; public static final double DEGREES_TO_RADIANS = Math.PI / 180;
public static final double RADIANS_TO_DEGREES = 1 / DEGREES_TO_RADIANS; public static final double RADIANS_TO_DEGREES = 1 / DEGREES_TO_RADIANS;


public static final double KM_TO_MILES = 0.621371192; public static final double KM_TO_MILES = 0.621371192;
Expand All @@ -50,6 +50,9 @@ public class DistanceUtils {
public static final double EARTH_MEAN_RADIUS_KM = 6371.0087714; public static final double EARTH_MEAN_RADIUS_KM = 6371.0087714;
public static final double EARTH_EQUATORIAL_RADIUS_KM = 6378.1370; public static final double EARTH_EQUATORIAL_RADIUS_KM = 6378.1370;


public static final double DEG_TO_KM = degrees2Dist(1, EARTH_MEAN_RADIUS_KM);
public static final double KM_TO_DEG = 1 / DEG_TO_KM;

public static final double EARTH_MEAN_RADIUS_MI = EARTH_MEAN_RADIUS_KM * KM_TO_MILES; public static final double EARTH_MEAN_RADIUS_MI = EARTH_MEAN_RADIUS_KM * KM_TO_MILES;
public static final double EARTH_EQUATORIAL_RADIUS_MI = EARTH_EQUATORIAL_RADIUS_KM * KM_TO_MILES; public static final double EARTH_EQUATORIAL_RADIUS_MI = EARTH_EQUATORIAL_RADIUS_KM * KM_TO_MILES;


Expand Down Expand Up @@ -136,8 +139,6 @@ public static double[] vectorBoxCorner(double[] center, double[] result, double
/** /**
* Given a start point (startLat, startLon) and a bearing on a sphere, return the destination point. * Given a start point (startLat, startLon) and a bearing on a sphere, return the destination point.
* *
*
*
* @param startLat The starting point latitude, in radians * @param startLat The starting point latitude, in radians
* @param startLon The starting point longitude, in radians * @param startLon The starting point longitude, in radians
* @param distanceRAD The distance to travel along the bearing in radians. * @param distanceRAD The distance to travel along the bearing in radians.
Expand Down Expand Up @@ -341,7 +342,7 @@ public static double distHaversineRAD(double lat1, double lon1, double lat2, dou
} }


/** /**
* Calculates the distance between two lat/lng's using the Law of Cosines. Due to numeric conditioning * Calculates the distance between two lat-lon's using the Law of Cosines. Due to numeric conditioning
* errors, it is not as accurate as the Haversine formula for small distances. But with * errors, it is not as accurate as the Haversine formula for small distances. But with
* double precision, it isn't that bad -- <a href="http://www.movable-type.co.uk/scripts/latlong.html"> * double precision, it isn't that bad -- <a href="http://www.movable-type.co.uk/scripts/latlong.html">
* allegedly 1 meter</a>. * allegedly 1 meter</a>.
Expand Down
45 changes: 21 additions & 24 deletions src/test/java/com/spatial4j/core/distance/TestDistances.java
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;


import static com.spatial4j.core.distance.DistanceUtils.DEG_TO_KM;
import static com.spatial4j.core.distance.DistanceUtils.KM_TO_DEG;

public class TestDistances extends RandomizedTest { public class TestDistances extends RandomizedTest {


//NOTE! These are sometimes modified by tests. //NOTE! These are sometimes modified by tests.
Expand All @@ -43,29 +46,22 @@ private DistanceCalculator dc() {
return ctx.getDistCalc(); return ctx.getDistCalc();
} }


private static double degToKm(double deg) {
return DistanceUtils.degrees2Dist(deg, DistanceUtils.EARTH_MEAN_RADIUS_KM);
}

private static double kmToDeg(double km) {
return DistanceUtils.dist2Degrees(km, DistanceUtils.EARTH_MEAN_RADIUS_KM);
}

@Test @Test
public void testSomeDistances() { public void testSomeDistances() {
//See to verify: from http://www.movable-type.co.uk/scripts/latlong.html //See to verify: from http://www.movable-type.co.uk/scripts/latlong.html
Point ctr = pLL(0,100); Point ctr = pLL(0,100);
assertEquals(11100, degToKm(dc().distance(ctr, pLL(10, 0))), 3); assertEquals(11100, dc().distance(ctr, pLL(10, 0)) * DEG_TO_KM, 3);
assertEquals(11100, degToKm(dc().distance(ctr, pLL(10, -160))), 3); double deg = dc().distance(ctr, pLL(10, -160));
assertEquals(11100, deg * DEG_TO_KM, 3);


assertEquals(314.40338, degToKm(dc().distance(pLL(1, 2), pLL(3, 4))), EPS); assertEquals(314.40338, dc().distance(pLL(1, 2), pLL(3, 4)) * DEG_TO_KM, EPS);
} }


@Test @Test
public void testCalcBoxByDistFromPt() { public void testCalcBoxByDistFromPt() {
//first test regression //first test regression
{ {
double d = kmToDeg(6894.1); double d = 6894.1 * KM_TO_DEG;
Point pCtr = pLL(-20, 84); Point pCtr = pLL(-20, 84);
Point pTgt = pLL(-42, 15); Point pTgt = pLL(-42, 15);
assertTrue(dc().distance(pCtr, pTgt) < d); assertTrue(dc().distance(pCtr, pTgt) < d);
Expand All @@ -78,17 +74,17 @@ public void testCalcBoxByDistFromPt() {
assertEquals("0 dist, horiz line", assertEquals("0 dist, horiz line",
-45,dc().calcBoxByDistFromPt_yHorizAxisDEG(ctx.makePoint(-180, -45), 0, ctx),0); -45,dc().calcBoxByDistFromPt_yHorizAxisDEG(ctx.makePoint(-180, -45), 0, ctx),0);


double MAXDIST = degToKm(180); double MAXDIST = (double) 180 * DEG_TO_KM;
checkBBox(ctx.makePoint(0,0), MAXDIST); checkBBox(ctx.makePoint(0,0), MAXDIST);
checkBBox(ctx.makePoint(0,0), MAXDIST *0.999999); checkBBox(ctx.makePoint(0,0), MAXDIST *0.999999);
checkBBox(ctx.makePoint(0,0),0); checkBBox(ctx.makePoint(0,0),0);
checkBBox(ctx.makePoint(0,0),0.000001); checkBBox(ctx.makePoint(0,0),0.000001);
checkBBox(ctx.makePoint(0,90),0.000001); checkBBox(ctx.makePoint(0,90),0.000001);
checkBBox(ctx.makePoint(-32.7,-5.42),9829); checkBBox(ctx.makePoint(-32.7,-5.42),9829);
checkBBox(ctx.makePoint(0,90-20),degToKm(20)); checkBBox(ctx.makePoint(0,90-20), (double) 20 * DEG_TO_KM);
{ {
double d = 0.010;//10m double d = 0.010;//10m
checkBBox(ctx.makePoint(0,90-kmToDeg(d + 0.001)),d); checkBBox(ctx.makePoint(0,90- (d + 0.001) * KM_TO_DEG),d);
} }


for (int T = 0; T < 100; T++) { for (int T = 0; T < 100; T++) {
Expand All @@ -103,7 +99,7 @@ public void testCalcBoxByDistFromPt() {


private void checkBBox(Point ctr, double distKm) { private void checkBBox(Point ctr, double distKm) {
String msg = "ctr: "+ctr+" distKm: "+distKm; String msg = "ctr: "+ctr+" distKm: "+distKm;
double dist = kmToDeg(distKm); double dist = distKm * KM_TO_DEG;


Rectangle r = dc().calcBoxByDistFromPt(ctr, dist, ctx, null); Rectangle r = dc().calcBoxByDistFromPt(ctr, dist, ctx, null);
double horizAxisLat = dc().calcBoxByDistFromPt_yHorizAxisDEG(ctr, dist, ctx); double horizAxisLat = dc().calcBoxByDistFromPt_yHorizAxisDEG(ctr, dist, ctx);
Expand All @@ -112,23 +108,24 @@ private void checkBBox(Point ctr, double distKm) {


//horizontal //horizontal
if (r.getWidth() >= 180) { if (r.getWidth() >= 180) {
double calcDistKm = degToKm(dc().distance(ctr, r.getMinX(), r.getMaxY() == 90 ? 90 : -90)); double deg = dc().distance(ctr, r.getMinX(), r.getMaxY() == 90 ? 90 : -90);
double calcDistKm = deg * DEG_TO_KM;
assertTrue(msg, calcDistKm <= distKm + EPS); assertTrue(msg, calcDistKm <= distKm + EPS);
//horizAxisLat is meaningless in this context //horizAxisLat is meaningless in this context
} else { } else {
Point tPt = findClosestPointOnVertToPoint(r.getMinX(), r.getMinY(), r.getMaxY(), ctr); Point tPt = findClosestPointOnVertToPoint(r.getMinX(), r.getMinY(), r.getMaxY(), ctr);
double calcDistKm = degToKm(dc().distance(ctr, tPt)); double calcDistKm = dc().distance(ctr, tPt) * DEG_TO_KM;
assertEquals(msg, distKm, calcDistKm, EPS); assertEquals(msg, distKm, calcDistKm, EPS);
assertEquals(msg, tPt.getY(), horizAxisLat, EPS); assertEquals(msg, tPt.getY(), horizAxisLat, EPS);
} }


//vertical //vertical
double topDistKm = degToKm(dc().distance(ctr, ctr.getX(), r.getMaxY())); double topDistKm = dc().distance(ctr, ctr.getX(), r.getMaxY()) * DEG_TO_KM;
if (r.getMaxY() == 90) if (r.getMaxY() == 90)
assertTrue(msg, topDistKm <= distKm + EPS); assertTrue(msg, topDistKm <= distKm + EPS);
else else
assertEquals(msg, distKm, topDistKm, EPS); assertEquals(msg, distKm, topDistKm, EPS);
double botDistKm = degToKm(dc().distance(ctr, ctr.getX(), r.getMinY())); double botDistKm = dc().distance(ctr, ctr.getX(), r.getMinY()) * DEG_TO_KM;
if (r.getMinY() == -90) if (r.getMinY() == -90)
assertTrue(msg, botDistKm <= distKm + EPS); assertTrue(msg, botDistKm <= distKm + EPS);
else else
Expand Down Expand Up @@ -187,7 +184,7 @@ public void testDistCalcPointOnBearing_geo() {
// double calcDist = dc().distance(c, p2); // double calcDist = dc().distance(c, p2);
// assertEqualsRatio(dist, calcDist); // assertEqualsRatio(dist, calcDist);
// } // }
double maxDistKm = degToKm(180); double maxDistKm = (double) 180 * DEG_TO_KM;
for(int i = 0; i < 1000; i++) { for(int i = 0; i < 1000; i++) {
int distKm = randomInt((int) maxDistKm); int distKm = randomInt((int) maxDistKm);
EPS = (distKm < maxDistKm*0.75 ? 10e-6 : 10e-3); EPS = (distKm < maxDistKm*0.75 ? 10e-6 : 10e-3);
Expand All @@ -205,8 +202,8 @@ private void testDistCalcPointOnBearing(double distKm) {
Point p2 = dc().pointOnBearing(c, 0, angDEG, ctx, null); Point p2 = dc().pointOnBearing(c, 0, angDEG, ctx, null);
assertEquals(c,p2); assertEquals(c,p2);


p2 = dc().pointOnBearing(c, kmToDeg(distKm), angDEG, ctx, null); p2 = dc().pointOnBearing(c, distKm * KM_TO_DEG, angDEG, ctx, null);
double calcDistKm = degToKm(dc().distance(c, p2)); double calcDistKm = dc().distance(c, p2) * DEG_TO_KM;
assertEqualsRatio(distKm, calcDistKm); assertEqualsRatio(distKm, calcDistKm);
} }
} }
Expand Down Expand Up @@ -280,7 +277,7 @@ private Point pLL(double lat, double lon) {


@Test @Test
public void testArea() { public void testArea() {
double radius = kmToDeg(DistanceUtils.EARTH_MEAN_RADIUS_KM); double radius = DistanceUtils.EARTH_MEAN_RADIUS_KM * KM_TO_DEG;
//surface of a sphere is 4 * pi * r^2 //surface of a sphere is 4 * pi * r^2
final double earthArea = 4 * Math.PI * radius * radius; final double earthArea = 4 * Math.PI * radius * radius;


Expand Down

0 comments on commit 3b17c0d

Please sign in to comment.