Reputation: 523
I have a Line that has a Start and End coordinate on the earth.
I'm trying to place perpendicular points on each side of the Start point length distance away.
Originally I thought I could
Coordinate p1 = Ppoint(start, end, length);
Coordinate p2 = Ppoint(start, end, -(length));
public static Coordinate Ppoint(Coordinate start, Coordinate end, double length){
double slope = getSlope(start, end);
double pSlope;
if(slope != 0)
{
pSlope = -(1/slope);
}
else
{
pSlope = 0;
}
double b = start.y + (-(pSlope * start.x));
double x = (start.x + length);
double y = (pSlope * x) + b;
Return new Coordinate(x,y);
}
I think there's a problem with doing math on lat/lon and accounting for their ranges
and this doesn't account for the earth not being flat.
Is there better way to approach this ?
Upvotes: 0
Views: 277
Reputation: 10976
You should probably not attempt to do this sort of maths on a sphere (while it can be made to work, it is hard and slow).
Assuming that length
is of the order of 10s-100s of kilometres you should reproject your problem to a "flat" surface centred on the start point and use Euclidean maths on a plane.
Fortunately, GeoTools provides handy automatic projections for just this problem. Here x
& y
are the coordinate of the start point (lon==x, lat==y):
String code = "AUTO:42001," + y + "," + x;
// System.out.println(code);
CoordinateReferenceSystem auto = CRS.decode(code);
// System.out.println(auto);
MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84,
auto);
MathTransform rTransform = CRS.findMathTransform(auto, DefaultGeographicCRS.WGS84);
You can then use the transform
object to convert your points to the new projection:
Geometry g3 = JTS.transform(g1, transform);
do whatever maths you need and then transform back to lat, lon using rTransform
So to adapt this to your problem.
Coordinate start = new Coordinate(1.0, 51.0);
Coordinate end = new Coordinate(2.0, 52.0);
double length = 10000;
GeometryFactory gf = new GeometryFactory();
double x = start.getX();
double y = start.getY();
String code;
if(CRS.getAxisOrder(DefaultGeographicCRS.WGS84).equals(AxisOrder.EAST_NORTH)) {
code = "AUTO:42001," + x + "," + y;
} else {
code = "AUTO:42001," + y + "," + x;
}
CoordinateReferenceSystem auto = CRS.decode(code);
MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
MathTransform rTransform = CRS.findMathTransform(auto, DefaultGeographicCRS.WGS84);
Point pStart = gf.createPoint(start);
Point pEnd = gf.createPoint(end);
Point ptStart = (Point) JTS.transform(pStart, transform);
Point ptEnd = (Point) JTS.transform(pEnd, transform);
Coordinate p1 = pPoint(ptStart.getCoordinate(), ptEnd.getCoordinate(), length);
Point tPoint = gf.createPoint(p1);
Point p = (Point) JTS.transform(tPoint, rTransform);
System.out.println(p);
which gives me POINT (1.2643 47.6531)
which looks wrong to me! You may need to check the maths in the pPoint
method.
Upvotes: 1
Reputation: 1537
Earth is not flat ?
Ok, there is this website that will explain better than me how to do with sphere. What you are looking for is this : Destination point given start point, distance & bearing
You could also change your coordinate system to a flat coordinate system, it's not a shame. https://epsg.io/
Upvotes: 1