Friday 29 January 2016

spherical geometry - Finding Perpendicular Distance and Minimum Perpendicular Vector between Point and Line using GeoTools and JTS?


I have a line formed by 2 lat/lon pairs, and the lat/lon of a point. I would like to find out the perpendicular distance between the line and the point on the Earth surface (can assume Earth as great sphere), and the minimum perpendicular vector (i.e. the projected "cross point" on the line).



I am trying to use Geotools 8.0 and JTS for this. Below captured my testing code:


    //Coordinates in lon, lat
Coordinate linePt1 = new Coordinate(-5.71472, 50.06639);
Coordinate linePt2 = new Coordinate(-3.07000, 58.64389);

//Multiply all longitudes by the cosine of latitude.
//http://gis.stackexchange.com/a/29713/10772
linePt1.x = linePt1.x * Math.cos(linePt1.y);
linePt2.x = linePt2.x * Math.cos(linePt2.y);


LineString line = createLine(new Coordinate[]{linePt1, linePt2});

Coordinate pt1 = new Coordinate(-6, 54);
pt1.x = pt1.x * Math.cos(pt1.y);
Point point = createPoint(pt1.x, pt1.y);

double distanceOp = DistanceOp.distance(line, point);
System.out.println("Distance = " + distanceOp);

//Find the minimum perpendicular vector using "closestPoints()"

for (Coordinate c : DistanceOp.closestPoints(line, point)) {
System.out.println("=== " + c);
//verify if the point is on the line
System.out.println(CGAlgorithms.isOnLine(c, new Coordinate[]{linePt1, linePt2}));
}

the createPoint() and createLine() methods:


public static LineString createLine(Coordinate[] coordinates){
GeometryFactory factory = new GeometryFactory(new PrecisionModel(
PrecisionModel.FLOATING), WGS84_SRID);

LineString line = (LineString) factory.createLineString(coordinates);
return line;
}

public static Point createPoint(double longitude, double latitude) {
if (longitude < -180 || longitude > 180) {
throw new IllegalArgumentException(
"Longitude should be between -180 and 180");
}
if (latitude < -90 || latitude > 90) {

throw new IllegalArgumentException(
"latitude should be between -90 and 90");
}
GeometryFactory factory = new GeometryFactory(new PrecisionModel(
PrecisionModel.FLOATING), WGS84_SRID);
Point point = (Point) factory.createPoint(new Coordinate(longitude,
latitude));
return point;
}


However, the result of "isOnLine()" return false. I was wondering if there is anything wrong.


Is there something wrong with my verification method, or actually the way I used to find out the perpendicular distance and the "cross point" on the Earth surface is not correct?




No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...