package fi.nls.oskari.map.geometry;

import fi.nls.oskari.domain.geo.Point;
import fi.nls.oskari.log.LogFactory;
import fi.nls.oskari.log.Logger;
import org.geotools.geometry.DirectPosition2D;
import org.geotools.referencing.CRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.cs.AxisDirection;
import org.opengis.referencing.operation.MathTransform;

/**
 * Helper for transformations
 */
public class ProjectionHelper {

    private static Logger log = LogFactory.getLogger(ProjectionHelper.class);

    public static Point transformPoint(final double x, final double y, final String sourceSRS, final String targetSRS) {
        return transformPoint(new Point(x, y), sourceSRS, targetSRS);
    }

    public static Point transformPoint(final Point point, final String sourceSRS, final String targetSRS) {
        try {
            CoordinateReferenceSystem sourceCrs = CRS.decode(sourceSRS);
            CoordinateReferenceSystem targetCrs = CRS.decode(targetSRS);

            boolean lenient = false;
            MathTransform mathTransform = CRS.findMathTransform(sourceCrs, targetCrs, lenient);

            //DirectPosition2D srcDirectPosition2D = new DirectPosition2D(sourceCrs, point.getY(), point.getX());
            DirectPosition2D srcDirectPosition2D = new DirectPosition2D(sourceCrs, point.getLon(), point.getLat());
            DirectPosition2D destDirectPosition2D = new DirectPosition2D();
            mathTransform.transform(srcDirectPosition2D, destDirectPosition2D);
            // Switch direction, if 1st coord is to the north on the other but not on the other
            if (isFirstAxisNorth(sourceCrs) != isFirstAxisNorth(targetCrs)) {
                return new Point(destDirectPosition2D.x, destDirectPosition2D.y);
            }
            return new Point(destDirectPosition2D.y, destDirectPosition2D.x);
        } catch (Exception e) {
            log.error(e, "Transform failed! Params: sourceSRS", sourceSRS, "targetSRS", targetSRS, "Point", point );
        }
        return null;
    }

    public static boolean isFirstAxisNorth(CoordinateReferenceSystem crs) {
        return crs.getCoordinateSystem().getAxis(0).getDirection().absolute() == AxisDirection.NORTH ||
                crs.getCoordinateSystem().getAxis(0).getDirection().absolute() == AxisDirection.UP ||
                crs.getCoordinateSystem().getAxis(0).getDirection().absolute() == AxisDirection.DISPLAY_UP;
    }
}

@@ -730,33 +730,32 @@
 rgetSRS);%0A    %7D%0A
-%0A
     public stati
@@ -1005,16 +1005,921 @@
 getSRS);
+%0A            return transformPoint(point, sourceCrs, targetCrs);%0A%0A        %7D catch (Exception e) %7B%0A            log.error(e, %22Transform CRS decoding failed! Params: sourceSRS%22, sourceSRS, %22targetSRS%22, targetSRS, %22Point%22, point );%0A        %7D%0A        return null;%0A    %7D%0A    public static Point transformPoint(final double x, final double y, final CoordinateReferenceSystem sourceCrs, final String targetSRS) %7B%0A        try %7B%0A            CoordinateReferenceSystem targetCrs = CRS.decode(targetSRS);%0A            return transformPoint(new Point(x, y), sourceCrs, targetCrs);%0A%0A        %7D catch (Exception e) %7B%0A            log.error(e, %22Transform CRS decoding failed! Params: targetSRS%22, targetSRS, %22Point: %22,x,%22  %22,y );%0A        %7D%0A        return null;%0A    %7D%0A    public static Point transformPoint(final Point point, final CoordinateReferenceSystem sourceCrs, final CoordinateReferenceSystem targetCrs) %7B%0A        try %7B
 %0A%0A      
@@ -2874,35 +2874,35 @@
 urceSRS%22, source
-SRS
+Crs
 , %22targetSRS%22, t
@@ -2898,35 +2898,35 @@
 rgetSRS%22, target
-SRS
+Crs
 , %22Point%22, point

transform helper methods