package org.simantics.district.network; import org.geotools.referencing.GeodeticCalculator; import org.opengis.referencing.FactoryException; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.layer0.Layer0; public class ModelledCRS implements CRS { private GeodeticCalculator calculator; public ModelledCRS(ReadGraph graph, Resource type) throws DatabaseException, FactoryException { String code = graph.getRelatedValue2(type, Layer0.getInstance(graph).HasLabel, Bindings.STRING); CoordinateReferenceSystem crs = org.geotools.referencing.CRS.decode(code); this.calculator = new GeodeticCalculator(crs); } @Override public double calculateDistance(double[] start, double[] end) { calculator.setStartingGeographicPoint(start[0], start[1]); calculator.setDestinationGeographicPoint(end[0], end[1]); double dist = calculator.getOrthodromicDistance(); return dist; } // TODO: these only work with Spherical Mercator public static double xToLongitude(double x) { return x; } public static double yToLatitude(double y) { double rad = Math.toRadians(y); double sinh = Math.sinh(rad); double atan = Math.atan(sinh); double finald = Math.toDegrees(atan); return finald; } public static double longitudeToX(double lon) { return lon; } private static double asinh(double x) { return Math.log(x + Math.sqrt(x*x + 1.0)); } public static double latitudeToY(double lat) { double frad = Math.toRadians(lat); double ftan = Math.tan(frad); double fsin = asinh(ftan); double f = Math.toDegrees(fsin); return f; } }