Add bearingTo method for PointType (#2757)

Signed-off-by: James Melville <jamesmelville@gmail.com>
This commit is contained in:
James Melville 2022-02-13 09:01:21 +00:00 committed by GitHub
parent 9a9217eab8
commit 92679aa6fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 2 deletions

View File

@ -128,6 +128,24 @@ public class PointType implements ComplexType, Command, State {
return new DecimalType(result);
}
/**
* Return the bearing in degrees from otherPoint following a great circle path.
*
* @param otherPoint
* @return bearing in degrees
* @see <a href="http://www.movable-type.co.uk/scripts/latlong.html">Calculate distance, bearing and more between
* Latitude/Longitude points</a>
*/
public DecimalType bearingTo(PointType otherPoint) {
double y = Math.sin(otherPoint.longitude.doubleValue() - this.longitude.doubleValue())
* Math.cos(otherPoint.latitude.doubleValue());
double x = Math.cos(this.latitude.doubleValue()) * Math.sin(otherPoint.latitude.doubleValue())
- Math.sin(this.latitude.doubleValue()) * Math.cos(otherPoint.latitude.doubleValue())
* Math.cos(otherPoint.longitude.doubleValue() - this.longitude.doubleValue());
double deg = (Math.atan2(y, x) * 180 / Math.PI + 360) % 360;
return new DecimalType(deg);
}
/**
* Return the distance in meters from otherPoint, ignoring altitude. This algorithm also
* ignores the oblate spheroid shape of Earth and assumes a perfect sphere, so results

View File

@ -96,13 +96,16 @@ public class PointTypeTest {
}
@Test
public void testDistance() {
public void testDefaultConstructor() {
// Ensure presence of default constructor
PointType middleOfTheOcean = new PointType();
assertEquals(0, middleOfTheOcean.getLongitude().doubleValue(), 0.0000001);
assertEquals(0, middleOfTheOcean.getLatitude().doubleValue(), 0.0000001);
assertEquals(0, middleOfTheOcean.getAltitude().doubleValue(), 0.0000001);
}
@Test
public void testGravity() {
PointType pointParis = PointType.valueOf("48.8566140,2.3522219");
assertEquals(2.3522219, pointParis.getLongitude().doubleValue(), 0.0000001);
@ -110,8 +113,10 @@ public class PointTypeTest {
double gravParis = pointParis.getGravity().doubleValue();
assertEquals(gravParis, 9.809, 0.001);
}
// Check canonization of position
@Test
public void testCanonicalization() {
PointType point3 = PointType.valueOf("-100,200");
double lat3 = point3.getLatitude().doubleValue();
double lon3 = point3.getLongitude().doubleValue();
@ -119,7 +124,10 @@ public class PointTypeTest {
assertTrue(lat3 < 90);
assertTrue(lon3 < 180);
assertTrue(lon3 > -180);
}
@Test
public void testConstructorToString() {
PointType pointTest1 = new PointType("48.8566140,2.3522219,118");
PointType pointTest2 = new PointType(pointTest1.toString());
assertEquals(pointTest1.getAltitude().longValue(), pointTest2.getAltitude().longValue());
@ -128,6 +136,27 @@ public class PointTypeTest {
// Ensure that constructor and toString are consistent
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=467612#c17
PointType point3 = PointType.valueOf("-100,200");
assertTrue(point3.equals(PointType.valueOf(point3.toString())));
}
@Test
public void testDistance() {
PointType pointParis = PointType.valueOf("48.8566140,2.3522219");
PointType greenwich = PointType.valueOf("51.477338,0.0");
assertEquals(336474.0, pointParis.distanceFrom(greenwich).doubleValue(), 1);
}
@Test
public void testBearing() {
PointType middleOfTheOcean = PointType.valueOf("0.0,0.0");
PointType greenwich = PointType.valueOf("51.477338,0.0");
PointType mudchute = PointType.valueOf("51.492148,-0.012126");
assertEquals(0.0, middleOfTheOcean.bearingTo(greenwich).doubleValue());
assertEquals(180, greenwich.bearingTo(middleOfTheOcean).doubleValue());
assertEquals(344.0, greenwich.bearingTo(mudchute).doubleValue(), 1);
assertEquals(164.0, mudchute.bearingTo(greenwich).doubleValue(), 1);
}
}