package org.ianturton.cookbook.distances; import javax.measure.Measure; import javax.measure.quantity.Length; import javax.measure.unit.SI; import org.geotools.geometry.jts.JTS; import org.geotools.geometry.jts.JTSFactoryFinder; import org.geotools.geometry.jts.WKTReader2; import org.geotools.referencing.CRS; import org.geotools.referencing.GeodeticCalculator; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.opengis.geometry.MismatchedDimensionException; import org.opengis.referencing.FactoryException; import org.opengis.referencing.NoSuchAuthorityCodeException; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.operation.TransformException; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.io.ParseException; public class AutoProjection { static GeometryFactory geometryFactory = JTSFactoryFinder .getGeometryFactory(null); static WKTReader2 reader = new WKTReader2(geometryFactory); public static void main(String[] args) throws ParseException, MismatchedDimensionException, NoSuchAuthorityCodeException, FactoryException, TransformException { Point p1 = getRandomPoint(); for (int i = 1; i < 50; i++) { double dx = i * Math.cos(Math.PI / 4); double dy = i * Math.sin(Math.PI / 4); Coordinate coordinate = new Coordinate(p1.getCoordinate().x + dx, p1.getCoordinate().y + dy); Point p2 = geometryFactory.createPoint(coordinate); // System.out.println(p2); System.out.print(Math.round(p1.distance(p2)) + " degrees \t"); AutoProjection me = new AutoProjection(); double distance = me.calculateDistance(p1, p2); double oDistance = me.calculateOrthoDistance(p1, p2); Measure<Double, Length> dist = Measure.valueOf(distance, SI.METER); Measure<Double, Length> oDist = Measure.valueOf(oDistance, SI.METER); double diff = Math.abs(distance - oDistance); Measure<Double, Length> oDiff = Measure.valueOf(diff, SI.METER); System.out.println("Proj: " + dist.doubleValue(SI.KILOMETER) + " Km" + "\tOrtho: " + oDist.doubleValue(SI.KILOMETER) + " Km" + "\tDiff: " + oDiff.doubleValue(SI.KILOMETER) + " Km"); } } private double calculateDistance(Geometry g1, Geometry g2) throws NoSuchAuthorityCodeException, FactoryException, MismatchedDimensionException, TransformException { Point c1 = g1.getCentroid(); Point c2 = g2.getCentroid(); Coordinate[] coordinates = new Coordinate[2]; coordinates[0] = c1.getCoordinate(); coordinates[1] = c2.getCoordinate(); LineString line = geometryFactory.createLineString(coordinates); Point c = line.getCentroid(); double x = c.getCoordinate().x; double y = c.getCoordinate().y; /* * double x = (c1.getCoordinate().x - c2.getCoordinate().x) + * c1.getCoordinate().x; while (x > 180.0) { x -= 360.0; } while (x < * -180.0) { x += 360.0; } * * double y = (c1.getCoordinate().y - c2.getCoordinate().y) + * c1.getCoordinate().y; while (y > 90.0) { y -= 180.0; } while (x < -90.0) * { y += 180.0; } */ 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); Geometry g3 = JTS.transform(g1, transform); Geometry g4 = JTS.transform(g2, transform); return g3.distance(g4); } private double calculateOrthoDistance(Geometry g1, Geometry g2) { double distance = 0.0; Point c1 = g1.getCentroid(); Point c2 = g2.getCentroid(); GeodeticCalculator calc = new GeodeticCalculator(DefaultGeographicCRS.WGS84); calc.setStartingGeographicPoint(c1.getX(), c1.getY()); calc.setDestinationGeographicPoint(c2.getX(), c2.getY()); distance = calc.getOrthodromicDistance(); return distance; } private static Point getRandomPoint() { double lat = -90.0 + Math.random() * 180.0; double lon = -180.0 + Math.random() * 360.0; Point p = geometryFactory.createPoint(new Coordinate(lon, lat)); // System.out.println(p); return p; } }