As it happens I have some code lying around that does most of this, so this should do what you need.
import java.util.ArrayList;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.referencing.GeodeticCalculator;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.util.factory.GeoTools;
import org.locationtech.jts.geom.Point;
import org.opengis.referencing.operation.TransformException;
import com.ianturton.cookbook.utilities.GenerateRandomData;
/**
* given a direction in degrees (from North) return the Compass Point on an 8
* element compass rose.
*
* @author ian
*/
public class CompassRose8 {
private static final int SIZE = 8;
static final float STEP = 360f / SIZE;
static final float HALF_STEP = STEP / 2.0f;
static final GeodeticCalculator gc = new GeodeticCalculator();
static final String points[] = { "N", "NE", "E", "SE", "S", "SW", "W", "NW", "N" };
static ArrayList<Direction> directions = new ArrayList<>();
static {
int k = 0;
for (float i = 0; i <= 360; i += (360.0 / SIZE), k++) {
Direction d = new Direction(points[k], i);
directions.add(d);
}
}
public static String getDirection(Point p1, Point p2) throws TransformException {
gc.setStartingPosition(new DirectPosition2D(DefaultGeographicCRS.WGS84, p1.getX(), p1.getY()));
gc.setDestinationPosition(new DirectPosition2D(DefaultGeographicCRS.WGS84, p2.getX(), p2.getY()));
float heading = (float) (gc.getAzimuth() + 180.0f);
return getDirection(heading);
}
public static String getDirection(float heading) {
while (heading < 0) {
heading += 360;
}
while (heading > 360) {
heading -= 360;
}
for (Direction d : directions) {
if (d.contains(heading)) {
return d.name;
}
}
return "bad heading " + heading;
}
public static void main(String[] args) throws TransformException {
// Make sure we know our axis order (doesn't matter which we pick)
System.setProperty(GeoTools.FORCE_LONGITUDE_FIRST_AXIS_ORDER, "true");
Point p1 = GenerateRandomData.createRandomPoint();
Point p2 = GenerateRandomData.createRandomPoint();
System.out.println(p1 + " is " + CompassRose8.getDirection(p1, p2) + " of " + p2);
}
static public class Direction {
private float start;
private float end;
private float centre;
final String name;
Direction(String name, float centre) {
this.name = name;
this.centre = centre;
start = this.centre - HALF_STEP;
end = this.centre + HALF_STEP;
}
public boolean contains(float degree) {
return (start < degree && end > degree);
}
}
}